main.cpp 179 KB
Newer Older
s_nakamoto's avatar
s_nakamoto committed
1
// Copyright (c) 2009-2010 Satoshi Nakamoto
2
// Copyright (c) 2009-2014 The Bitcoin developers
3
// Distributed under the MIT software license, see the accompanying
Fordy's avatar
Fordy committed
4
5
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

6
#include "main.h"
7

8
#include "addrman.h"
9
#include "alert.h"
10
#include "chainparams.h"
11
#include "checkpoints.h"
12
#include "checkqueue.h"
13
#include "init.h"
14
#include "merkleblock.h"
15
#include "net.h"
16
#include "pow.h"
17
18
#include "txdb.h"
#include "txmempool.h"
Pieter Wuille's avatar
Pieter Wuille committed
19
#include "ui_interface.h"
20
#include "util.h"
21
#include "utilmoneystr.h"
22

Gavin Andresen's avatar
Gavin Andresen committed
23
#include <sstream>
24
25
26
27

#include <boost/algorithm/string/replace.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
Wladimir J. van der Laan's avatar
Wladimir J. van der Laan committed
28
#include <boost/thread.hpp>
s_nakamoto's avatar
s_nakamoto committed
29

30
using namespace boost;
31
using namespace std;
s_nakamoto's avatar
s_nakamoto committed
32

33
34
35
36
#if defined(NDEBUG)
# error "Bitcoin cannot be compiled without assertions."
#endif

37
38
39
/**
 * Global state
 */
s_nakamoto's avatar
s_nakamoto committed
40
41
42

CCriticalSection cs_main;

43
BlockMap mapBlockIndex;
44
CChain chainActive;
45
CBlockIndex *pindexBestHeader = NULL;
46
int64_t nTimeBestReceived = 0;
47
48
CWaitableCriticalSection csBestBlock;
CConditionVariable cvBlockChange;
49
int nScriptCheckThreads = 0;
50
bool fImporting = false;
51
bool fReindex = false;
52
bool fTxIndex = false;
53
bool fIsBareMultisigStd = true;
Pieter Wuille's avatar
Pieter Wuille committed
54
unsigned int nCoinCacheSize = 5000;
s_nakamoto's avatar
s_nakamoto committed
55

56

57
/** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
Gavin Andresen's avatar
Gavin Andresen committed
58
59
60
CFeeRate minRelayTxFee = CFeeRate(1000);

CTxMemPool mempool(::minRelayTxFee);
Gavin Andresen's avatar
Gavin Andresen committed
61

62
63
64
65
66
struct COrphanTx {
    CTransaction tx;
    NodeId fromPeer;
};
map<uint256, COrphanTx> mapOrphanTransactions;
67
map<uint256, set<uint256> > mapOrphanTransactionsByPrev;
68
void EraseOrphansFor(NodeId peer);
s_nakamoto's avatar
s_nakamoto committed
69

70
/** Constant stuff for coinbase transactions we create: */
71
CScript COINBASE_FLAGS;
s_nakamoto's avatar
s_nakamoto committed
72

73
74
const string strMessageMagic = "Bitcoin Signed Message:\n";

75
76
// Internal stuff
namespace {
77

R E Broadley's avatar
R E Broadley committed
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
    struct CBlockIndexWorkComparator
    {
        bool operator()(CBlockIndex *pa, CBlockIndex *pb) {
            // First sort by most total work, ...
            if (pa->nChainWork > pb->nChainWork) return false;
            if (pa->nChainWork < pb->nChainWork) return true;

            // ... then by earliest time received, ...
            if (pa->nSequenceId < pb->nSequenceId) return false;
            if (pa->nSequenceId > pb->nSequenceId) return true;

            // Use pointer address as tie breaker (should only happen with blocks
            // loaded from disk, as those all have id 0).
            if (pa < pb) return false;
            if (pa > pb) return true;

            // Identical blocks.
            return false;
        }
    };

    CBlockIndex *pindexBestInvalid;
100

101
102
103
104
    /**
     * The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS or better that are at least
     * as good as our current tip. Entries may be failed, though.
     */
105
    set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
106
    /** Number of nodes with fSyncStarted. */
Pieter Wuille's avatar
Pieter Wuille committed
107
    int nSyncStarted = 0;
108
    /** All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions. */
Pieter Wuille's avatar
Pieter Wuille committed
109
    multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked;
R E Broadley's avatar
R E Broadley committed
110
111

    CCriticalSection cs_LastBlockFile;
112
    std::vector<CBlockFileInfo> vinfoBlockFile;
R E Broadley's avatar
R E Broadley committed
113
114
    int nLastBlockFile = 0;

115
116
117
118
    /**
     * Every received block is assigned a unique and increasing identifier, so we
     * know which one to give priority in case of a fork.
     */
R E Broadley's avatar
R E Broadley committed
119
    CCriticalSection cs_nBlockSequenceId;
120
    /** Blocks loaded from disk are assigned id 0, so start the counter at 1. */
R E Broadley's avatar
R E Broadley committed
121
122
    uint32_t nBlockSequenceId = 1;

123
124
125
126
    /**
     * Sources of received blocks, to be able to send them reject messages or ban
     * them, if processing happens afterwards. Protected by cs_main.
     */
R E Broadley's avatar
R E Broadley committed
127
128
    map<uint256, NodeId> mapBlockSource;

129
    /** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */
R E Broadley's avatar
R E Broadley committed
130
131
    struct QueuedBlock {
        uint256 hash;
132
133
        CBlockIndex *pindex;  //! Optional.
        int64_t nTime;  //! Time of "getdata" request in microseconds.
134
135
        int nValidatedQueuedBefore;  //! Number of blocks queued with validated headers (globally) at the time this one is requested.
        bool fValidatedHeaders;  //! Whether this block has validated headers at the time of request.
R E Broadley's avatar
R E Broadley committed
136
137
    };
    map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;
138

139
140
141
    /** Number of blocks in flight with validated headers. */
    int nQueuedValidatedHeaders = 0;

142
    /** Number of preferable block download peers. */
143
    int nPreferredDownload = 0;
144

145
    /** Dirty block index entries. */
146
147
    set<CBlockIndex*> setDirtyBlockIndex;

148
    /** Dirty block file entries. */
149
    set<int> setDirtyFileInfo;
150
} // anon namespace
s_nakamoto's avatar
s_nakamoto committed
151

Pieter Wuille's avatar
Pieter Wuille committed
152
153
154
155
156
//////////////////////////////////////////////////////////////////////////////
//
// dispatching functions
//

Pieter Wuille's avatar
Pieter Wuille committed
157
158
// These functions dispatch to one or all registered wallets

159
namespace {
160

161
struct CMainSignals {
162
    /** Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. */
163
    boost::signals2::signal<void (const CTransaction &, const CBlock *)> SyncTransaction;
164
    /** Notifies listeners of an erased transaction (currently disabled, requires transaction replacement). */
165
    boost::signals2::signal<void (const uint256 &)> EraseTransaction;
166
    /** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */
167
    boost::signals2::signal<void (const uint256 &)> UpdatedTransaction;
168
    /** Notifies listeners of a new active block chain. */
169
    boost::signals2::signal<void (const CBlockLocator &)> SetBestChain;
170
    /** Notifies listeners about an inventory item being seen on the network. */
171
    boost::signals2::signal<void (const uint256 &)> Inventory;
172
    /** Tells listeners to broadcast their data. */
173
    boost::signals2::signal<void ()> Broadcast;
174
    /** Notifies listeners of a block validation result */
175
    boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked;
176
} g_signals;
177
178

} // anon namespace
Pieter Wuille's avatar
Pieter Wuille committed
179

180
181
182
183
184
185
186
void RegisterValidationInterface(CValidationInterface* pwalletIn) {
    g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2));
    g_signals.EraseTransaction.connect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1));
    g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
    g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
    g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
    g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn));
187
    g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
Pieter Wuille's avatar
Pieter Wuille committed
188
189
}

190
void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
191
    g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
192
193
194
195
196
197
    g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn));
    g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
    g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
    g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
    g_signals.EraseTransaction.disconnect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1));
    g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2));
Pieter Wuille's avatar
Pieter Wuille committed
198
199
}

200
void UnregisterAllValidationInterfaces() {
201
    g_signals.BlockChecked.disconnect_all_slots();
202
203
204
205
206
207
    g_signals.Broadcast.disconnect_all_slots();
    g_signals.Inventory.disconnect_all_slots();
    g_signals.SetBestChain.disconnect_all_slots();
    g_signals.UpdatedTransaction.disconnect_all_slots();
    g_signals.EraseTransaction.disconnect_all_slots();
    g_signals.SyncTransaction.disconnect_all_slots();
Pieter Wuille's avatar
Pieter Wuille committed
208
209
}

210
211
void SyncWithWallets(const CTransaction &tx, const CBlock *pblock) {
    g_signals.SyncTransaction(tx, pblock);
Pieter Wuille's avatar
Pieter Wuille committed
212
213
}

214
215
216
217
218
//////////////////////////////////////////////////////////////////////////////
//
// Registration of network node signals.
//

Pieter Wuille's avatar
Pieter Wuille committed
219
namespace {
220
221
222
223
224
225
226

struct CBlockReject {
    unsigned char chRejectCode;
    string strRejectReason;
    uint256 hashBlock;
};

227
228
229
230
231
232
/**
 * Maintain validation-specific state about nodes, protected by cs_main, instead
 * by CNode's own locks. This simplifies asynchronous operation, where
 * processing of incoming data is done after the ProcessMessage call returns,
 * and we're no longer holding the node's locks.
 */
Pieter Wuille's avatar
Pieter Wuille committed
233
struct CNodeState {
234
235
236
237
    //! The peer's address
    CService address;
    //! Whether we have a fully established connection.
    bool fCurrentlyConnected;
238
    //! Accumulated misbehaviour score for this peer.
Pieter Wuille's avatar
Pieter Wuille committed
239
    int nMisbehavior;
240
    //! Whether this peer should be disconnected and banned (unless whitelisted).
Pieter Wuille's avatar
Pieter Wuille committed
241
    bool fShouldBan;
242
    //! String name of this peer (debugging/logging purposes).
Pieter Wuille's avatar
Pieter Wuille committed
243
    std::string name;
244
    //! List of asynchronously-determined block rejections to notify this peer about.
245
    std::vector<CBlockReject> rejects;
246
    //! The best known block we know this peer has announced.
Pieter Wuille's avatar
Pieter Wuille committed
247
    CBlockIndex *pindexBestKnownBlock;
248
    //! The hash of the last unknown block this peer has announced.
Pieter Wuille's avatar
Pieter Wuille committed
249
    uint256 hashLastUnknownBlock;
250
    //! The last full block we both have.
Pieter Wuille's avatar
Pieter Wuille committed
251
    CBlockIndex *pindexLastCommonBlock;
252
    //! Whether we've started headers synchronization with this peer.
Pieter Wuille's avatar
Pieter Wuille committed
253
    bool fSyncStarted;
254
    //! Since when we're stalling block download progress (in microseconds), or 0.
Pieter Wuille's avatar
Pieter Wuille committed
255
    int64_t nStallingSince;
256
257
    list<QueuedBlock> vBlocksInFlight;
    int nBlocksInFlight;
258
    //! Whether we consider this a preferred download peer.
259
    bool fPreferredDownload;
Pieter Wuille's avatar
Pieter Wuille committed
260
261

    CNodeState() {
262
        fCurrentlyConnected = false;
Pieter Wuille's avatar
Pieter Wuille committed
263
264
        nMisbehavior = 0;
        fShouldBan = false;
Pieter Wuille's avatar
Pieter Wuille committed
265
266
        pindexBestKnownBlock = NULL;
        hashLastUnknownBlock = uint256(0);
Pieter Wuille's avatar
Pieter Wuille committed
267
268
269
        pindexLastCommonBlock = NULL;
        fSyncStarted = false;
        nStallingSince = 0;
270
        nBlocksInFlight = 0;
271
        fPreferredDownload = false;
Pieter Wuille's avatar
Pieter Wuille committed
272
273
274
    }
};

275
/** Map maintaining per-node state. Requires cs_main. */
Pieter Wuille's avatar
Pieter Wuille committed
276
277
278
279
280
281
282
283
284
285
286
map<NodeId, CNodeState> mapNodeState;

// Requires cs_main.
CNodeState *State(NodeId pnode) {
    map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode);
    if (it == mapNodeState.end())
        return NULL;
    return &it->second;
}

int GetHeight()
287
288
289
290
291
{
    LOCK(cs_main);
    return chainActive.Height();
}

292
293
294
295
296
297
298
299
300
301
void UpdatePreferredDownload(CNode* node, CNodeState* state)
{
    nPreferredDownload -= state->fPreferredDownload;

    // Whether this node should be marked as a preferred download node.
    state->fPreferredDownload = (!node->fInbound || node->fWhitelisted) && !node->fOneShot && !node->fClient;

    nPreferredDownload += state->fPreferredDownload;
}

Pieter Wuille's avatar
Pieter Wuille committed
302
303
304
305
void InitializeNode(NodeId nodeid, const CNode *pnode) {
    LOCK(cs_main);
    CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second;
    state.name = pnode->addrName;
306
    state.address = pnode->addr;
Pieter Wuille's avatar
Pieter Wuille committed
307
308
309
310
}

void FinalizeNode(NodeId nodeid) {
    LOCK(cs_main);
311
312
    CNodeState *state = State(nodeid);

Pieter Wuille's avatar
Pieter Wuille committed
313
314
315
    if (state->fSyncStarted)
        nSyncStarted--;

316
317
318
319
    if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
        AddressCurrentlyConnected(state->address);
    }

320
321
    BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight)
        mapBlocksInFlight.erase(entry.hash);
322
    EraseOrphansFor(nodeid);
323
    nPreferredDownload -= state->fPreferredDownload;
324

Pieter Wuille's avatar
Pieter Wuille committed
325
326
    mapNodeState.erase(nodeid);
}
327
328

// Requires cs_main.
Pieter Wuille's avatar
Pieter Wuille committed
329
void MarkBlockAsReceived(const uint256& hash) {
330
331
332
    map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
    if (itInFlight != mapBlocksInFlight.end()) {
        CNodeState *state = State(itInFlight->second.first);
333
        nQueuedValidatedHeaders -= itInFlight->second.second->fValidatedHeaders;
334
335
        state->vBlocksInFlight.erase(itInFlight->second.second);
        state->nBlocksInFlight--;
Pieter Wuille's avatar
Pieter Wuille committed
336
        state->nStallingSince = 0;
337
338
339
340
341
        mapBlocksInFlight.erase(itInFlight);
    }
}

// Requires cs_main.
Pieter Wuille's avatar
Pieter Wuille committed
342
void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, CBlockIndex *pindex = NULL) {
343
344
345
346
347
348
    CNodeState *state = State(nodeid);
    assert(state != NULL);

    // Make sure it's not listed somewhere already.
    MarkBlockAsReceived(hash);

349
350
    QueuedBlock newentry = {hash, pindex, GetTimeMicros(), nQueuedValidatedHeaders, pindex != NULL};
    nQueuedValidatedHeaders += newentry.fValidatedHeaders;
351
352
353
354
355
    list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry);
    state->nBlocksInFlight++;
    mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
}

Pieter Wuille's avatar
Pieter Wuille committed
356
357
358
359
360
361
/** Check whether the last unknown block a peer advertized is not yet known. */
void ProcessBlockAvailability(NodeId nodeid) {
    CNodeState *state = State(nodeid);
    assert(state != NULL);

    if (state->hashLastUnknownBlock != 0) {
362
        BlockMap::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock);
Pieter Wuille's avatar
Pieter Wuille committed
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
        if (itOld != mapBlockIndex.end() && itOld->second->nChainWork > 0) {
            if (state->pindexBestKnownBlock == NULL || itOld->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
                state->pindexBestKnownBlock = itOld->second;
            state->hashLastUnknownBlock = uint256(0);
        }
    }
}

/** Update tracking information about which blocks a peer is assumed to have. */
void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) {
    CNodeState *state = State(nodeid);
    assert(state != NULL);

    ProcessBlockAvailability(nodeid);

378
    BlockMap::iterator it = mapBlockIndex.find(hash);
Pieter Wuille's avatar
Pieter Wuille committed
379
380
381
382
383
384
385
386
387
388
    if (it != mapBlockIndex.end() && it->second->nChainWork > 0) {
        // An actually better block was announced.
        if (state->pindexBestKnownBlock == NULL || it->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
            state->pindexBestKnownBlock = it->second;
    } else {
        // An unknown block was announced; just assume that the latest one is the best one.
        state->hashLastUnknownBlock = hash;
    }
}

Pieter Wuille's avatar
Pieter Wuille committed
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
/** Find the last common ancestor two blocks have.
 *  Both pa and pb must be non-NULL. */
CBlockIndex* LastCommonAncestor(CBlockIndex* pa, CBlockIndex* pb) {
    if (pa->nHeight > pb->nHeight) {
        pa = pa->GetAncestor(pb->nHeight);
    } else if (pb->nHeight > pa->nHeight) {
        pb = pb->GetAncestor(pa->nHeight);
    }

    while (pa != pb && pa && pb) {
        pa = pa->pprev;
        pb = pb->pprev;
    }

    // Eventually all chain branches meet at the genesis block.
    assert(pa == pb);
    return pa;
}

/** Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has
 *  at most count entries. */
void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBlockIndex*>& vBlocks, NodeId& nodeStaller) {
    if (count == 0)
        return;

    vBlocks.reserve(vBlocks.size() + count);
    CNodeState *state = State(nodeid);
    assert(state != NULL);

    // Make sure pindexBestKnownBlock is up to date, we'll need it.
    ProcessBlockAvailability(nodeid);

    if (state->pindexBestKnownBlock == NULL || state->pindexBestKnownBlock->nChainWork < chainActive.Tip()->nChainWork) {
        // This peer has nothing interesting.
        return;
    }

    if (state->pindexLastCommonBlock == NULL) {
        // Bootstrap quickly by guessing a parent of our best tip is the forking point.
        // Guessing wrong in either direction is not a problem.
        state->pindexLastCommonBlock = chainActive[std::min(state->pindexBestKnownBlock->nHeight, chainActive.Height())];
    }

    // If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor
    // of their current tip anymore. Go back enough to fix that.
    state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
    if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
        return;

    std::vector<CBlockIndex*> vToFetch;
    CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
Pieter Wuille's avatar
Pieter Wuille committed
440
441
442
443
444
    // Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last
    // linked block we have in common with this peer. The +1 is so we can detect stalling, namely if we would be able to
    // download that next block if the window were 1 larger.
    int nWindowEnd = state->pindexLastCommonBlock->nHeight + BLOCK_DOWNLOAD_WINDOW;
    int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1);
Pieter Wuille's avatar
Pieter Wuille committed
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
    NodeId waitingfor = -1;
    while (pindexWalk->nHeight < nMaxHeight) {
        // Read up to 128 (or more, if more blocks than that are needed) successors of pindexWalk (towards
        // pindexBestKnownBlock) into vToFetch. We fetch 128, because CBlockIndex::GetAncestor may be as expensive
        // as iterating over ~100 CBlockIndex* entries anyway.
        int nToFetch = std::min(nMaxHeight - pindexWalk->nHeight, std::max<int>(count - vBlocks.size(), 128));
        vToFetch.resize(nToFetch);
        pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->nHeight + nToFetch);
        vToFetch[nToFetch - 1] = pindexWalk;
        for (unsigned int i = nToFetch - 1; i > 0; i--) {
            vToFetch[i - 1] = vToFetch[i]->pprev;
        }

        // Iterate over those blocks in vToFetch (in forward direction), adding the ones that
        // are not yet downloaded and not in flight to vBlocks. In the mean time, update
        // pindexLastCommonBlock as long as all ancestors are already downloaded.
        BOOST_FOREACH(CBlockIndex* pindex, vToFetch) {
462
463
464
465
            if (!pindex->IsValid(BLOCK_VALID_TREE)) {
                // We consider the chain that this peer is on invalid.
                return;
            }
Pieter Wuille's avatar
Pieter Wuille committed
466
467
468
469
470
            if (pindex->nStatus & BLOCK_HAVE_DATA) {
                if (pindex->nChainTx)
                    state->pindexLastCommonBlock = pindex;
            } else if (mapBlocksInFlight.count(pindex->GetBlockHash()) == 0) {
                // The block is not already downloaded, and not yet in flight.
Pieter Wuille's avatar
Pieter Wuille committed
471
                if (pindex->nHeight > nWindowEnd) {
Pieter Wuille's avatar
Pieter Wuille committed
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
                    // We reached the end of the window.
                    if (vBlocks.size() == 0 && waitingfor != nodeid) {
                        // We aren't able to fetch anything, but we would be if the download window was one larger.
                        nodeStaller = waitingfor;
                    }
                    return;
                }
                vBlocks.push_back(pindex);
                if (vBlocks.size() == count) {
                    return;
                }
            } else if (waitingfor == -1) {
                // This is the first already-in-flight block.
                waitingfor = mapBlocksInFlight[pindex->GetBlockHash()].first;
            }
        }
    }
}

491
} // anon namespace
Pieter Wuille's avatar
Pieter Wuille committed
492
493
494
495
496
497
498

bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) {
    LOCK(cs_main);
    CNodeState *state = State(nodeid);
    if (state == NULL)
        return false;
    stats.nMisbehavior = state->nMisbehavior;
Pieter Wuille's avatar
Pieter Wuille committed
499
    stats.nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
500
501
502
503
504
    stats.nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1;
    BOOST_FOREACH(const QueuedBlock& queue, state->vBlocksInFlight) {
        if (queue.pindex)
            stats.vHeightInFlight.push_back(queue.pindex->nHeight);
    }
Pieter Wuille's avatar
Pieter Wuille committed
505
506
507
    return true;
}

508
509
void RegisterNodeSignals(CNodeSignals& nodeSignals)
{
510
    nodeSignals.GetHeight.connect(&GetHeight);
511
512
    nodeSignals.ProcessMessages.connect(&ProcessMessages);
    nodeSignals.SendMessages.connect(&SendMessages);
Pieter Wuille's avatar
Pieter Wuille committed
513
514
    nodeSignals.InitializeNode.connect(&InitializeNode);
    nodeSignals.FinalizeNode.connect(&FinalizeNode);
515
}
Pieter Wuille's avatar
Pieter Wuille committed
516

517
518
void UnregisterNodeSignals(CNodeSignals& nodeSignals)
{
519
    nodeSignals.GetHeight.disconnect(&GetHeight);
520
521
    nodeSignals.ProcessMessages.disconnect(&ProcessMessages);
    nodeSignals.SendMessages.disconnect(&SendMessages);
Pieter Wuille's avatar
Pieter Wuille committed
522
523
    nodeSignals.InitializeNode.disconnect(&InitializeNode);
    nodeSignals.FinalizeNode.disconnect(&FinalizeNode);
524
}
Pieter Wuille's avatar
Pieter Wuille committed
525

jtimon's avatar
jtimon committed
526
527
CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator)
{
528
    // Find the first block the caller has in the main chain
529
    BOOST_FOREACH(const uint256& hash, locator.vHave) {
530
        BlockMap::iterator mi = mapBlockIndex.find(hash);
531
532
533
        if (mi != mapBlockIndex.end())
        {
            CBlockIndex* pindex = (*mi).second;
jtimon's avatar
jtimon committed
534
            if (chain.Contains(pindex))
535
536
537
                return pindex;
        }
    }
jtimon's avatar
jtimon committed
538
    return chain.Genesis();
539
540
}

541
CCoinsViewCache *pcoinsTip = NULL;
542
CBlockTreeDB *pblocktree = NULL;
Pieter Wuille's avatar
Pieter Wuille committed
543

s_nakamoto's avatar
s_nakamoto committed
544
545
546
547
548
//////////////////////////////////////////////////////////////////////////////
//
// mapOrphanTransactions
//

549
bool AddOrphanTx(const CTransaction& tx, NodeId peer)
s_nakamoto's avatar
s_nakamoto committed
550
551
552
{
    uint256 hash = tx.GetHash();
    if (mapOrphanTransactions.count(hash))
553
554
555
556
557
558
559
560
561
        return false;

    // Ignore big transactions, to avoid a
    // send-big-orphans memory exhaustion attack. If a peer has a legitimate
    // large transaction with a missing parent then we assume
    // it will rebroadcast it later, after the parent transaction(s)
    // have been mined or received.
    // 10,000 orphans, each of which is at most 5,000 bytes big is
    // at most 500 megabytes of orphans:
562
563
    unsigned int sz = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION);
    if (sz > 5000)
564
    {
565
        LogPrint("mempool", "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString());
566
567
        return false;
    }
568

569
570
    mapOrphanTransactions[hash].tx = tx;
    mapOrphanTransactions[hash].fromPeer = peer;
571
    BOOST_FOREACH(const CTxIn& txin, tx.vin)
572
        mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash);
573

574
575
    LogPrint("mempool", "stored orphan tx %s (mapsz %u prevsz %u)\n", hash.ToString(),
             mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
576
    return true;
s_nakamoto's avatar
s_nakamoto committed
577
578
}

Pieter Wuille's avatar
Pieter Wuille committed
579
void static EraseOrphanTx(uint256 hash)
s_nakamoto's avatar
s_nakamoto committed
580
{
581
    map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
582
    if (it == mapOrphanTransactions.end())
s_nakamoto's avatar
s_nakamoto committed
583
        return;
584
    BOOST_FOREACH(const CTxIn& txin, it->second.tx.vin)
s_nakamoto's avatar
s_nakamoto committed
585
    {
586
        map<uint256, set<uint256> >::iterator itPrev = mapOrphanTransactionsByPrev.find(txin.prevout.hash);
587
588
        if (itPrev == mapOrphanTransactionsByPrev.end())
            continue;
589
590
591
        itPrev->second.erase(hash);
        if (itPrev->second.empty())
            mapOrphanTransactionsByPrev.erase(itPrev);
s_nakamoto's avatar
s_nakamoto committed
592
    }
593
    mapOrphanTransactions.erase(it);
s_nakamoto's avatar
s_nakamoto committed
594
595
}

596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
void EraseOrphansFor(NodeId peer)
{
    int nErased = 0;
    map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
    while (iter != mapOrphanTransactions.end())
    {
        map<uint256, COrphanTx>::iterator maybeErase = iter++; // increment to avoid iterator becoming invalid
        if (maybeErase->second.fromPeer == peer)
        {
            EraseOrphanTx(maybeErase->second.tx.GetHash());
            ++nErased;
        }
    }
    if (nErased > 0) LogPrint("mempool", "Erased %d orphan tx from peer %d\n", nErased, peer);
}


613
unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
614
{
615
    unsigned int nEvicted = 0;
616
617
618
    while (mapOrphanTransactions.size() > nMaxOrphans)
    {
        // Evict a random orphan:
619
        uint256 randomhash = GetRandHash();
620
        map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
621
622
623
624
625
626
627
        if (it == mapOrphanTransactions.end())
            it = mapOrphanTransactions.begin();
        EraseOrphanTx(it->first);
        ++nEvicted;
    }
    return nEvicted;
}
s_nakamoto's avatar
s_nakamoto committed
628
629
630
631
632
633
634







635
bool IsStandardTx(const CTransaction& tx, string& reason)
Gavin Andresen's avatar
Gavin Andresen committed
636
{
637
    AssertLockHeld(cs_main);
638
    if (tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) {
639
        reason = "version";
640
        return false;
641
    }
642

643
644
645
    // Treat non-final transactions as non-standard to prevent a specific type
    // of double-spend attack, as well as DoS attacks. (if the transaction
    // can't be mined, the attacker isn't expending resources broadcasting it)
646
    // Basically we don't want to propagate transactions that can't be included in
647
648
649
650
651
652
653
654
655
656
657
658
659
660
    // the next block.
    //
    // However, IsFinalTx() is confusing... Without arguments, it uses
    // chainActive.Height() to evaluate nLockTime; when a block is accepted, chainActive.Height()
    // is set to the value of nHeight in the block. However, when IsFinalTx()
    // is called within CBlock::AcceptBlock(), the height of the block *being*
    // evaluated is what is used. Thus if we want to know if a transaction can
    // be part of the *next* block, we need to call IsFinalTx() with one more
    // than chainActive.Height().
    //
    // Timestamps on the other hand don't get any special treatment, because we
    // can't know what timestamp the next block will have, and there aren't
    // timestamp applications where it matters.
    if (!IsFinalTx(tx, chainActive.Height() + 1)) {
661
        reason = "non-final";
662
        return false;
663
    }
664

665
666
667
668
    // Extremely large transactions with lots of inputs can cost the network
    // almost as much to process as they cost the sender in fees, because
    // computing signature hashes is O(ninputs*txsize). Limiting transactions
    // to MAX_STANDARD_TX_SIZE mitigates CPU exhaustion attacks.
669
    unsigned int sz = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION);
670
671
    if (sz >= MAX_STANDARD_TX_SIZE) {
        reason = "tx-size";
672
        return false;
673
    }
674

675
    BOOST_FOREACH(const CTxIn& txin, tx.vin)
Gavin Andresen's avatar
Gavin Andresen committed
676
    {
677
678
        // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
        // keys. (remember the 520 byte limit on redeemScript size) That works
679
        // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627
680
681
682
683
684
        // bytes of scriptSig, which we round off to 1650 bytes for some minor
        // future-proofing. That's also enough to spend a 20-of-20
        // CHECKMULTISIG scriptPubKey, though such a scriptPubKey is not
        // considered standard)
        if (txin.scriptSig.size() > 1650) {
685
            reason = "scriptsig-size";
686
            return false;
687
688
689
        }
        if (!txin.scriptSig.IsPushOnly()) {
            reason = "scriptsig-not-pushonly";
690
            return false;
691
        }
Gavin Andresen's avatar
Gavin Andresen committed
692
    }
693
694
695

    unsigned int nDataOut = 0;
    txnouttype whichType;
696
    BOOST_FOREACH(const CTxOut& txout, tx.vout) {
697
        if (!::IsStandard(txout.scriptPubKey, whichType)) {
698
            reason = "scriptpubkey";
699
            return false;
700
        }
701

702
703
        if (whichType == TX_NULL_DATA)
            nDataOut++;
704
705
706
707
        else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) {
            reason = "bare-multisig";
            return false;
        } else if (txout.IsDust(::minRelayTxFee)) {
708
            reason = "dust";
709
            return false;
710
        }
711
    }
712

713
714
    // only one OP_RETURN txout is permitted
    if (nDataOut > 1) {
715
        reason = "multi-op-return";
716
717
718
        return false;
    }

Gavin Andresen's avatar
Gavin Andresen committed
719
720
721
    return true;
}

722
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
723
{
724
    AssertLockHeld(cs_main);
725
726
727
728
    // Time based nLockTime implemented in 0.1.6
    if (tx.nLockTime == 0)
        return true;
    if (nBlockHeight == 0)
729
        nBlockHeight = chainActive.Height();
730
731
    if (nBlockTime == 0)
        nBlockTime = GetAdjustedTime();
732
    if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
733
734
735
736
737
738
739
        return true;
    BOOST_FOREACH(const CTxIn& txin, tx.vin)
        if (!txin.IsFinal())
            return false;
    return true;
}

740
741
742
743
744
745
746
747
748
/**
 * Check transaction inputs to mitigate two
 * potential denial-of-service attacks:
 * 
 * 1. scriptSigs with extra data stuffed into them,
 *    not consumed by scriptPubKey (or P2SH script)
 * 2. P2SH scripts with a crazy number of expensive
 *    CHECKSIG/CHECKMULTISIG operations
 */
749
bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
Gavin Andresen's avatar
Gavin Andresen committed
750
{
751
    if (tx.IsCoinBase())
752
        return true; // Coinbases don't use vin normally
753

754
    for (unsigned int i = 0; i < tx.vin.size(); i++)
Gavin Andresen's avatar
Gavin Andresen committed
755
    {
756
        const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]);
Gavin Andresen's avatar
Gavin Andresen committed
757
758

        vector<vector<unsigned char> > vSolutions;
759
760
        txnouttype whichType;
        // get the scriptPubKey corresponding to this input:
761
        const CScript& prevScript = prev.scriptPubKey;
762
        if (!Solver(prevScript, whichType, vSolutions))
763
            return false;
764
        int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions);
765
766
        if (nArgsExpected < 0)
            return false;
767
768
769
770

        // Transactions with extra stuff in their scriptSigs are
        // non-standard. Note that this EvalScript() call will
        // be quick, because if there are any operations
771
772
773
        // beside "push data" in the scriptSig
        // IsStandard() will have already returned false
        // and this method isn't called.
774
        vector<vector<unsigned char> > stack;
Pieter Wuille's avatar
Pieter Wuille committed
775
        if (!EvalScript(stack, tx.vin[i].scriptSig, false, BaseSignatureChecker()))
776
777
            return false;

Gavin Andresen's avatar
Gavin Andresen committed
778
779
        if (whichType == TX_SCRIPTHASH)
        {
780
            if (stack.empty())
Gavin Andresen's avatar
Gavin Andresen committed
781
                return false;
782
            CScript subscript(stack.back().begin(), stack.back().end());
783
784
            vector<vector<unsigned char> > vSolutions2;
            txnouttype whichType2;
785
786
787
788
789
790
791
792
793
794
795
796
797
798
            if (Solver(subscript, whichType2, vSolutions2))
            {
                int tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2);
                if (tmpExpected < 0)
                    return false;
                nArgsExpected += tmpExpected;
            }
            else
            {
                // Any other Script with less than 15 sigops OK:
                unsigned int sigops = subscript.GetSigOpCount(true);
                // ... extra data left on the stack after execution is OK, too:
                return (sigops <= MAX_P2SH_SIGOPS);
            }
Gavin Andresen's avatar
Gavin Andresen committed
799
        }
800

801
        if (stack.size() != (unsigned int)nArgsExpected)
802
            return false;
Gavin Andresen's avatar
Gavin Andresen committed
803
804
805
806
807
    }

    return true;
}

808
unsigned int GetLegacySigOpCount(const CTransaction& tx)
809
{
810
    unsigned int nSigOps = 0;
811
    BOOST_FOREACH(const CTxIn& txin, tx.vin)
812
813
814
    {
        nSigOps += txin.scriptSig.GetSigOpCount(false);
    }
815
    BOOST_FOREACH(const CTxOut& txout, tx.vout)
816
817
818
819
820
    {
        nSigOps += txout.scriptPubKey.GetSigOpCount(false);
    }
    return nSigOps;
}
s_nakamoto's avatar
s_nakamoto committed
821

822
unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
823
824
825
826
827
828
829
830
831
832
833
834
835
{
    if (tx.IsCoinBase())
        return 0;

    unsigned int nSigOps = 0;
    for (unsigned int i = 0; i < tx.vin.size(); i++)
    {
        const CTxOut &prevout = inputs.GetOutputFor(tx.vin[i]);
        if (prevout.scriptPubKey.IsPayToScriptHash())
            nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
    }
    return nSigOps;
}
s_nakamoto's avatar
s_nakamoto committed
836
837
838
839
840
841
842
843








844
bool CheckTransaction(const CTransaction& tx, CValidationState &state)
845
846
{
    // Basic checks that don't depend on any context
847
    if (tx.vin.empty())
Gavin Andresen's avatar
Gavin Andresen committed
848
        return state.DoS(10, error("CheckTransaction() : vin empty"),
849
                         REJECT_INVALID, "bad-txns-vin-empty");
850
    if (tx.vout.empty())
Gavin Andresen's avatar
Gavin Andresen committed
851
        return state.DoS(10, error("CheckTransaction() : vout empty"),
852
                         REJECT_INVALID, "bad-txns-vout-empty");
853
    // Size limits
854
    if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
855
        return state.DoS(100, error("CheckTransaction() : size limits failed"),
856
                         REJECT_INVALID, "bad-txns-oversize");
857
858

    // Check for negative or overflow output values
859
    CAmount nValueOut = 0;
860
    BOOST_FOREACH(const CTxOut& txout, tx.vout)
861
862
    {
        if (txout.nValue < 0)
Gavin Andresen's avatar
Gavin Andresen committed
863
            return state.DoS(100, error("CheckTransaction() : txout.nValue negative"),
864
                             REJECT_INVALID, "bad-txns-vout-negative");
865
        if (txout.nValue > MAX_MONEY)
Gavin Andresen's avatar
Gavin Andresen committed
866
            return state.DoS(100, error("CheckTransaction() : txout.nValue too high"),
867
                             REJECT_INVALID, "bad-txns-vout-toolarge");
868
869
        nValueOut += txout.nValue;
        if (!MoneyRange(nValueOut))
870
            return state.DoS(100, error("CheckTransaction() : txout total out of range"),
871
                             REJECT_INVALID, "bad-txns-txouttotal-toolarge");
872
873
    }

874
875
    // Check for duplicate inputs
    set<COutPoint> vInOutPoints;
876
    BOOST_FOREACH(const CTxIn& txin, tx.vin)
877
878
    {
        if (vInOutPoints.count(txin.prevout))
879
            return state.DoS(100, error("CheckTransaction() : duplicate inputs"),
880
                             REJECT_INVALID, "bad-txns-inputs-duplicate");
881
882
883
        vInOutPoints.insert(txin.prevout);
    }

884
    if (tx.IsCoinBase())
885
    {
886
        if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
Gavin Andresen's avatar
Gavin Andresen committed
887
            return state.DoS(100, error("CheckTransaction() : coinbase script size"),
888
                             REJECT_INVALID, "bad-cb-length");
889
890
891
    }
    else
    {
892
        BOOST_FOREACH(const CTxIn& txin, tx.vin)
893
            if (txin.prevout.IsNull())
Gavin Andresen's avatar
Gavin Andresen committed
894
                return state.DoS(10, error("CheckTransaction() : prevout is null"),
895
                                 REJECT_INVALID, "bad-txns-prevout-null");
896
897
898
899
900
    }

    return true;
}

901
CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree)
902
{
903
904
905
906
    {
        LOCK(mempool.cs);
        uint256 hash = tx.GetHash();
        double dPriorityDelta = 0;
907
        CAmount nFeeDelta = 0;
908
909
910
911
912
        mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
        if (dPriorityDelta > 0 || nFeeDelta > 0)
            return 0;
    }

913
    CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes);
914
915
916

    if (fAllowFree)
    {
917
918
        // There is a free transaction area in blocks created by most miners,
        // * If we are relaying we allow transactions up to DEFAULT_BLOCK_PRIORITY_SIZE - 1000
919
920
        //   to be considered to fall into this category. We don't want to encourage sending
        //   multiple transactions instead of one big transaction to avoid fees.
921
        if (nBytes < (DEFAULT_BLOCK_PRIORITY_SIZE - 1000))
922
            nMinFee = 0;
923
924
925
926
927
928
929
    }

    if (!MoneyRange(nMinFee))
        nMinFee = MAX_MONEY;
    return nMinFee;
}

Pieter Wuille's avatar
Pieter Wuille committed
930

931
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
932
                        bool* pfMissingInputs, bool fRejectInsaneFee)
s_nakamoto's avatar
s_nakamoto committed
933
{
934
    AssertLockHeld(cs_main);
s_nakamoto's avatar
s_nakamoto committed
935
936
937
    if (pfMissingInputs)
        *pfMissingInputs = false;

938
    if (!CheckTransaction(tx, state))
939
        return error("AcceptToMemoryPool: : CheckTransaction failed");
940

s_nakamoto's avatar
s_nakamoto committed
941
    // Coinbase is only valid in a block, not as a loose transaction
942
    if (tx.IsCoinBase())
Gavin Andresen's avatar
Gavin Andresen committed
943
944
        return state.DoS(100, error("AcceptToMemoryPool: : coinbase as individual tx"),
                         REJECT_INVALID, "coinbase");
s_nakamoto's avatar
s_nakamoto committed
945

946
    // Rather not work on nonstandard transactions (unless -testnet/-regtest)
947
    string reason;
jtimon's avatar
jtimon committed
948
    if (Params().RequireStandard() && !IsStandardTx(tx, reason))
Gavin Andresen's avatar
Gavin Andresen committed
949
        return state.DoS(0,
950
                         error("AcceptToMemoryPool : nonstandard transaction: %s", reason),
Gavin Andresen's avatar
Gavin Andresen committed
951
                         REJECT_NONSTANDARD, reason);
952

Pieter Wuille's avatar
Pieter Wuille committed
953
    // is it already in the memory pool?
954
    uint256 hash = tx.GetHash();
955
956
    if (pool.exists(hash))
        return false;
s_nakamoto's avatar
s_nakamoto committed
957
958

    // Check for conflicts with in-memory transactions
959
960
    {
    LOCK(pool.cs); // protect pool.mapNextTx
961
    for (unsigned int i = 0; i < tx.vin.size(); i++)
s_nakamoto's avatar
s_nakamoto committed
962
    {
963
        COutPoint outpoint = tx.vin[i].prevout;
964
        if (pool.mapNextTx.count(outpoint))
s_nakamoto's avatar
s_nakamoto committed
965
        {
966
            // Disable replacement feature for now
967
            return false;
s_nakamoto's avatar
s_nakamoto committed
968
969
        }
    }
970
    }
s_nakamoto's avatar
s_nakamoto committed
971
972

    {
973
        CCoinsView dummy;
974
        CCoinsViewCache view(&dummy);
975

976
        CAmount nValueIn = 0;
977
        {
978
        LOCK(pool.cs);
979
        CCoinsViewMemPool viewMemPool(pcoinsTip, pool);
980
        view.SetBackend(viewMemPool);
Pieter Wuille's avatar
Pieter Wuille committed
981
982
983

        // do we already have it?
        if (view.HaveCoins(hash))
984
            return false;
Pieter Wuille's avatar
Pieter Wuille committed
985
986

        // do all inputs exist?
Pieter Wuille's avatar
Pieter Wuille committed
987
988
        // Note that this does not check for the presence of actual outputs (see the next check for that),
        // only helps filling in pfMissingInputs (to determine missing vs spent).
Pieter Wuille's avatar
Pieter Wuille committed
989
990
991
992
993
994
        BOOST_FOREACH(const CTxIn txin, tx.vin) {
            if (!view.HaveCoins(txin.prevout.hash)) {
                if (pfMissingInputs)
                    *pfMissingInputs = true;
                return false;
            }
Gavin Andresen's avatar
Gavin Andresen committed
995
996
        }

Pieter Wuille's avatar
Pieter Wuille committed
997
        // are the actual inputs available?
998
        if (!view.HaveInputs(tx))
Gavin Andresen's avatar
Gavin Andresen committed
999
            return state.Invalid(error("AcceptToMemoryPool : inputs already spent"),
1000
                                 REJECT_DUPLICATE, "bad-txns-inputs-spent");
1001

1002
1003
1004
        // Bring the best block into scope
        view.GetBestBlock();

1005
1006
        nValueIn = view.GetValueIn(tx);

1007
1008
1009
        // we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool
        view.SetBackend(dummy);
        }
Pieter Wuille's avatar
Pieter Wuille committed
1010

1011
        // Check for non-standard pay-to-script-hash in inputs
jtimon's avatar
jtimon committed
1012
        if (Params().RequireStandard() && !AreInputsStandard(tx, view))
1013
            return error("AcceptToMemoryPool: : nonstandard transaction input");
Gavin Andresen's avatar
Gavin Andresen committed
1014

1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
        // Check that the transaction doesn't have an excessive number of
        // sigops, making it impossible to mine. Since the coinbase transaction
        // itself can contain sigops MAX_TX_SIGOPS is less than
        // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than
        // merely non-standard transaction.
        unsigned int nSigOps = GetLegacySigOpCount(tx);
        nSigOps += GetP2SHSigOpCount(tx, view);
        if (nSigOps > MAX_TX_SIGOPS)
            return state.DoS(0,
                             error("AcceptToMemoryPool : too many sigops %s, %d > %d",
                                   hash.ToString(), nSigOps, MAX_TX_SIGOPS),
                             REJECT_NONSTANDARD, "bad-txns-too-many-sigops");
1027

1028
1029
        CAmount nValueOut = tx.GetValueOut();
        CAmount nFees = nValueIn-nValueOut;
1030
1031
1032
1033
        double dPriority = view.GetPriority(tx, chainActive.Height());

        CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height());
        unsigned int nSize = entry.GetTxSize();
1034
1035

        // Don't accept it if it can't get into a block
1036
        CAmount txMinFee = GetMinRelayFee(tx, nSize, true);
1037
        if (fLimitFree && nFees < txMinFee)
1038
            return state.DoS(0, error("AcceptToMemoryPool : not enough fees %s, %d < %d",
1039
                                      hash.ToString(), nFees, txMinFee),
Gavin Andresen's avatar
Gavin Andresen committed
1040
                             REJECT_INSUFFICIENTFEE, "insufficient fee");
1041

1042
1043
1044
1045
1046
1047
        // Require that free transactions have sufficient priority to be mined in the next block.
        if (GetBoolArg("-relaypriority", true) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) {
            return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
        }

        // Continuously rate-limit free (really, very-low-fee) transactions
1048
        // This mitigates 'penny-flooding' -- sending thousands of free transactions just to
1049
        // be annoying or make others' transactions take longer to confirm.
Gavin Andresen's avatar
Gavin Andresen committed
1050
        if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize))
1051
        {
1052
            static CCriticalSection csFreeLimiter;
1053
            static double dFreeCount;
1054
1055
1056
1057
            static int64_t nLastTime;
            int64_t nNow = GetTime();

            LOCK(csFreeLimiter);
1058

1059
1060
1061
1062
1063
1064
            // Use an exponentially decaying ~10-minute window:
            dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime));
            nLastTime = nNow;
            // -limitfreerelay unit is thousand-bytes-per-minute
            // At default rate it would take over a month to fill 1GB
            if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000)
Gavin Andresen's avatar
Gavin Andresen committed
1065
                return state.DoS(0, error("AcceptToMemoryPool : free transaction rejected by rate limiter"),
1066
                                 REJECT_INSUFFICIENTFEE, "rate limited free transaction");
1067
            LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
1068
            dFreeCount += nSize;
1069
        }
1070

Gavin Andresen's avatar
Gavin Andresen committed
1071
        if (fRejectInsaneFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000)
1072
            return error("AcceptToMemoryPool: : insane fees %s, %d > %d",
1073
                         hash.ToString(),
Gavin Andresen's avatar
Gavin Andresen committed
1074
                         nFees, ::minRelayTxFee.GetFee(nSize) * 10000);
1075

1076
1077
        // Check against previous transactions
        // This is done last to help prevent CPU exhaustion denial-of-service attacks.
1078
        if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true))
1079
        {
1080
            return error("AcceptToMemoryPool: : ConnectInputs failed %s", hash.ToString());
1081
        }
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096

        // Check again against just the consensus-critical mandatory script
        // verification flags, in case of bugs in the standard flags that cause
        // transactions to pass as valid when they're actually invalid. For
        // instance the STRICTENC flag was incorrectly allowing certain
        // CHECKSIG NOT scripts to pass, even though they were invalid.
        //
        // There is a similar check in CreateNewBlock() to prevent creating
        // invalid blocks, however allowing such transactions into the mempool
        // can be exploited as a DoS attack.
        if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true))
        {
            return error("AcceptToMemoryPool: : BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString());
        }

1097
1098
        // Store transaction in memory
        pool.addUnchecked(hash, entry);
1099
1100
    }

1101
    SyncWithWallets(tx, NULL);
1102

1103
    return true;
1104
1105
}

1106
/** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */
Pieter Wuille's avatar
Pieter Wuille committed
1107
bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
1108
{
Pieter Wuille's avatar
Pieter Wuille committed
1109
    CBlockIndex *pindexSlow = NULL;
1110
1111
1112
    {
        LOCK(cs_main);
        {
1113
            if (mempool.lookup(hash, txOut))
1114
1115
1116
1117
            {
                return true;
            }
        }
Pieter Wuille's avatar
Pieter Wuille committed
1118

1119
1120
1121
1122
        if (fTxIndex) {
            CDiskTxPos postx;
            if (pblocktree->ReadTxIndex(hash, postx)) {
                CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
1123
1124
                if (file.IsNull())
                    return error("%s: OpenBlockFile failed", __func__);
1125
1126
1127
                CBlockHeader header;
                try {
                    file >> header;
1128
                    fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
1129
1130
                    file >> txOut;
                } catch (std::exception &e) {
1131
                    return error("%s : Deserialize or I/O error - %s", __func__, e.what());
1132
1133
1134
                }
                hashBlock = header.GetHash();
                if (txOut.GetHash() != hash)
1135
                    return error("%s : txid mismatch", __func__);
1136
1137
1138
1139
                return true;
            }
        }

Pieter Wuille's avatar
Pieter Wuille committed
1140
1141
1142
        if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
            int nHeight = -1;
            {
1143
                CCoinsViewCache &view = *pcoinsTip;
1144
1145
1146
                const CCoins* coins = view.AccessCoins(hash);
                if (coins)
                    nHeight = coins->nHeight;
Pieter Wuille's avatar
Pieter Wuille committed
1147
1148
            }
            if (nHeight > 0)
1149
                pindexSlow = chainActive[nHeight];
1150
1151
        }
    }
s_nakamoto's avatar
s_nakamoto committed
1152

Pieter Wuille's avatar
Pieter Wuille committed
1153
1154
    if (pindexSlow) {
        CBlock block;
1155
        if (ReadBlockFromDisk(block, pindexSlow)) {
Pieter Wuille's avatar
Pieter Wuille committed
1156
1157
1158
1159
1160
1161
1162
1163
1164
            BOOST_FOREACH(const CTransaction &tx, block.vtx) {
                if (tx.GetHash() == hash) {
                    txOut = tx;
                    hashBlock = pindexSlow->GetBlockHash();
                    return true;
                }
            }
        }
    }
s_nakamoto's avatar
s_nakamoto committed
1165

Pieter Wuille's avatar
Pieter Wuille committed
1166
1167
    return false;
}
s_nakamoto's avatar
s_nakamoto committed
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178






//////////////////////////////////////////////////////////////////////////////
//
// CBlock and CBlockIndex
//

1179
1180
1181
bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos)
{
    // Open history file to append
1182
    CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
1183
    if (fileout.IsNull())
1184
        return error("WriteBlockToDisk : OpenBlockFile failed");
1185
1186
1187
1188
1189
1190

    // Write index header
    unsigned int nSize = fileout.GetSerializeSize(block);
    fileout << FLATDATA(Params().MessageStart()) << nSize;

    // Write block
1191
    long fileOutPos = ftell(fileout.Get());
1192
    if (fileOutPos < 0)
1193
        return error("WriteBlockToDisk : ftell failed");
1194
1195
1196
1197
1198
1199
    pos.nPos = (unsigned int)fileOutPos;
    fileout << block;

    return true;
}

1200
1201
1202
1203
1204
bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos)
{
    block.SetNull();

    // Open history file to read
1205
    CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
1206
    if (filein.IsNull())
1207
        return error("ReadBlockFromDisk : OpenBlockFile failed");
1208
1209
1210
1211
1212
1213

    // Read block
    try {
        filein >> block;
    }
    catch (std::exception &e) {
1214
        return error("%s : Deserialize or I/O error - %s", __func__, e.what());
1215
1216
1217
1218
    }

    // Check the header
    if (!CheckProofOfWork(block.GetHash(), block.nBits))
1219
        return error("ReadBlockFromDisk : Errors in block header");
1220
1221
1222
1223

    return true;
}

1224
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex)
s_nakamoto's avatar
s_nakamoto committed
1225
{
1226
    if (!ReadBlockFromDisk(block, pindex->GetBlockPos()))
s_nakamoto's avatar
s_nakamoto committed
1227
        return false;
1228
1229
    if (block.GetHash() != pindex->GetBlockHash())
        return error("ReadBlockFromDisk(CBlock&, CBlockIndex*) : GetHash() doesn't match index");
s_nakamoto's avatar
s_nakamoto committed
1230
1231
1232
    return true;
}

1233
CAmount GetBlockValue(int nHeight, const CAmount& nFees)
s_nakamoto's avatar
s_nakamoto committed
1234
{
1235
    CAmount nSubsidy = 50 * COIN;
1236
1237
1238
1239
1240
    int halvings = nHeight / Params().SubsidyHalvingInterval();

    // Force block reward to zero when right shift is undefined.
    if (halvings >= 64)
        return nFees;
s_nakamoto's avatar
s_nakamoto committed
1241

1242
    // Subsidy is cut in half every 210,000 blocks which will occur approximately every 4 years.
1243
    nSubsidy >>= halvings;
s_nakamoto's avatar
s_nakamoto committed
1244
1245
1246
1247
1248
1249

    return nSubsidy + nFees;
}

bool IsInitialBlockDownload()
{
1250
    LOCK(cs_main);
1251
    if (fImporting || fReindex || chainActive.Height() < Checkpoints::GetTotalBlocksEstimate())
s_nakamoto's avatar
s_nakamoto committed
1252
        return true;
1253
1254
1255
1256
    static bool lockIBDState = false;
    if (lockIBDState)
        return false;
    bool state = (chainActive.Height() < pindexBestHeader->nHeight - 24 * 6 ||
1257
            pindexBestHeader->GetBlockTime() < GetTime() - 24 * 60 * 60);
1258
1259
1260
    if (!state)
        lockIBDState = true;
    return state;
s_nakamoto's avatar
s_nakamoto committed
1261
1262
}

1263
bool fLargeWorkForkFound = false;
1264
bool fLargeWorkInvalidChainFound = false;
1265
1266
1267
1268
CBlockIndex *pindexBestForkTip = NULL, *pindexBestForkBase = NULL;

void CheckForkWarningConditions()
{
1269
    AssertLockHeld(cs_main);
1270
1271
1272
1273
1274
    // Before we get past initial download, we cannot reliably alert about forks
    // (we assume we don't get stuck on a fork before the last checkpoint)
    if (IsInitialBlockDownload())
        return;

1275
1276
    // If our best fork is no longer within 72 blocks (+/- 12 hours if no one mines it)
    // of our head, drop it
1277
    if (pindexBestForkTip && chainActive.Height() - pindexBestForkTip->nHeight >= 72)
1278
1279
        pindexBestForkTip = NULL;

1280
    if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > chainActive.Tip()->nChainWork + (GetBlockProof(*chainActive.Tip()) * 6)))
1281
    {
21E14's avatar
21E14 committed
1282
        if (!fLargeWorkForkFound && pindexBestForkBase)
1283
        {
Gavin Andresen's avatar
Gavin Andresen committed
1284
1285
1286
            std::string warning = std::string("'Warning: Large-work fork detected, forking after block ") +
                pindexBestForkBase->phashBlock->ToString() + std::string("'");
            CAlert::Notify(warning, true);
1287
        }
21E14's avatar
21E14 committed
1288
        if (pindexBestForkTip && pindexBestForkBase)
1289
        {
1290
            LogPrintf("CheckForkWarningConditions: Warning: Large valid fork found\n  forking the chain at height %d (%s)\n  lasting to height %d (%s).\nChain state database corruption likely.\n",
1291
1292
                   pindexBestForkBase->nHeight, pindexBestForkBase->phashBlock->ToString(),
                   pindexBestForkTip->nHeight, pindexBestForkTip->phashBlock->ToString());
1293
1294
1295
1296
            fLargeWorkForkFound = true;
        }
        else
        {
1297
            LogPrintf("CheckForkWarningConditions: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n");
1298
1299
1300
1301
1302
            fLargeWorkInvalidChainFound = true;
        }
    }
    else
    {
1303
        fLargeWorkForkFound = false;
1304
1305
        fLargeWorkInvalidChainFound = false;
    }
1306
1307
1308
1309
}

void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip)
{
1310
    AssertLockHeld(cs_main);
1311
1312
    // If we are on a fork that is sufficiently large, set a warning flag
    CBlockIndex* pfork = pindexNewForkTip;
1313
    CBlockIndex* plonger = chainActive.Tip();
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
    while (pfork && pfork != plonger)
    {
        while (plonger && plonger->nHeight > pfork->nHeight)
            plonger = plonger->pprev;
        if (pfork == plonger)
            break;
        pfork = pfork->pprev;
    }

    // We define a condition which we should warn the user about as a fork of at least 7 blocks
    // who's tip is within 72 blocks (+/- 12 hours if no one mines it) of ours
    // We use 7 blocks rather arbitrarily as it represents just under 10% of sustained network
    // hash rate operating on the fork.
    // or a chain that is entirely longer than ours and invalid (note that this should be detected by both)
    // We define it this way because it allows us to only store the highest fork tip (+ base) which meets
    // the 7-block condition and from this always have the most-likely-to-cause-warning fork
    if (pfork && (!pindexBestForkTip || (pindexBestForkTip && pindexNewForkTip->nHeight > pindexBestForkTip->nHeight)) &&
1331
            pindexNewForkTip->nChainWork - pfork->nChainWork > (GetBlockProof(*pfork) * 7) &&
1332
            chainActive.Height() - pindexNewForkTip->nHeight < 72)
1333
1334
1335
1336
1337
1338
1339
1340
    {
        pindexBestForkTip = pindexNewForkTip;
        pindexBestForkBase = pfork;
    }

    CheckForkWarningConditions();
}

1341
// Requires cs_main.
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
void Misbehaving(NodeId pnode, int howmuch)
{
    if (howmuch == 0)
        return;

    CNodeState *state = State(pnode);
    if (state == NULL)
        return;

    state->nMisbehavior += howmuch;
Pieter Wuille's avatar
Pieter Wuille committed
1352
1353
    int banscore = GetArg("-banscore", 100);
    if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore)
1354
1355
1356
1357
1358
1359
1360
    {
        LogPrintf("Misbehaving: %s (%d -> %d) BAN THRESHOLD EXCEEDED\n", state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
        state->fShouldBan = true;
    } else
        LogPrintf("Misbehaving: %s (%d -> %d)\n", state->name, state->nMisbehavior-howmuch, state->nMisbehavior);
}

Pieter Wuille's avatar
Pieter Wuille committed
1361
void static InvalidChainFound(CBlockIndex* pindexNew)
s_nakamoto's avatar
s_nakamoto committed
1362
{
1363
1364
    if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
        pindexBestInvalid = pindexNew;
1365

1366
    LogPrintf("InvalidChainFound: invalid block=%s  height=%d  log2_work=%.8g  date=%s\n",
1367
      pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
Pieter Wuille's avatar
Pieter Wuille committed
1368
      log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S",
1369
      pindexNew->GetBlockTime()));
1370
    LogPrintf("InvalidChainFound:  current best=%s  height=%d  log2_work=%.8g  date=%s\n",
1371
1372
      chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0),
      DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()));
1373
    CheckForkWarningConditions();
s_nakamoto's avatar
s_nakamoto committed
1374
1375
}

1376
1377
1378
1379
1380
void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state) {
    int nDoS = 0;
    if (state.IsInvalid(nDoS)) {
        std::map<uint256, NodeId>::iterator it = mapBlockSource.find(pindex->GetBlockHash());
        if (it != mapBlockSource.end() && State(it->second)) {
1381
            CBlockReject reject = {state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), pindex->GetBlockHash()};
1382
1383
1384
            State(it->second)->rejects.push_back(reject);
            if (nDoS > 0)
                Misbehaving(it->second, nDoS);
1385
        }
1386
1387
1388
    }
    if (!state.CorruptionPossible()) {
        pindex->nStatus |= BLOCK_FAILED_VALID;
1389
        setDirtyBlockIndex.insert(pindex);
1390
        setBlockIndexCandidates.erase(pindex);
1391
1392
        InvalidChainFound(pindex);
    }
1393
1394
}

1395
void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight)
Pieter Wuille's avatar
Pieter Wuille committed
1396
1397
{
    // mark inputs spent
1398
    if (!tx.IsCoinBase()) {
Pieter Wuille's avatar
Pieter Wuille committed
1399
        txundo.vprevout.reserve(tx.vin.size());
1400
        BOOST_FOREACH(const CTxIn &txin, tx.vin) {
Pieter Wuille's avatar
Pieter Wuille committed
1401
            txundo.vprevout.push_back(CTxInUndo());
1402
            bool ret = inputs.ModifyCoins(txin.prevout.hash)->Spend(txin.prevout, txundo.vprevout.back());
1403
            assert(ret);
Pieter Wuille's avatar
Pieter Wuille committed
1404
1405
1406
1407
        }
    }

    // add outputs
1408
    inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight);
Pieter Wuille's avatar
Pieter Wuille committed
1409
1410
}

1411
bool CScriptCheck::operator()() {
1412
    const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
1413
    if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, cacheStore), &error)) {
1414
        return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error));
1415
    }
1416
1417
1418
    return true;
}

1419
bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks)
s_nakamoto's avatar
s_nakamoto committed
1420
{
1421
    if (!tx.IsCoinBase())
s_nakamoto's avatar
s_nakamoto committed
1422
    {
1423
        if (pvChecks)
1424
            pvChecks->reserve(tx.vin.size());
1425

Pieter Wuille's avatar
Pieter Wuille committed
1426
1427
        // This doesn't trigger the DoS code on purpose; if it did, it would make it easier
        // for an attacker to attempt to split the network.
1428
        if (!inputs.HaveInputs(tx))
1429
            return state.Invalid(error("CheckInputs() : %s inputs unavailable", tx.GetHash().ToString()));
Pieter Wuille's avatar
Pieter Wuille committed
1430

1431
1432
        // While checking, GetBestBlock() refers to the parent block.
        // This is also true for mempool checks.
1433
1434
        CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
        int nSpendHeight = pindexPrev->nHeight + 1;
1435
1436
        CAmount nValueIn = 0;
        CAmount nFees = 0;
1437
        for (unsigned int i = 0; i < tx.vin.size(); i++)
s_nakamoto's avatar
s_nakamoto committed
1438
        {
1439
            const COutPoint &prevout = tx.vin[i].prevout;
1440
1441
            const CCoins *coins = inputs.AccessCoins(prevout.hash);
            assert(coins);
s_nakamoto's avatar
s_nakamoto committed
1442
1443

            // If prev is coinbase, check that it's matured
1444
1445
            if (coins->IsCoinBase()) {
                if (nSpendHeight - coins->nHeight < COINBASE_MATURITY)
Gavin Andresen's avatar
Gavin Andresen committed
1446
                    return state.Invalid(
1447
                        error("CheckInputs() : tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
1448
                        REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
Pieter Wuille's avatar
Pieter Wuille committed
1449
            }
s_nakamoto's avatar
s_nakamoto committed
1450

1451
            // Check for negative or overflow input values
1452
1453
            nValueIn += coins->vout[prevout.n].nValue;
            if (!MoneyRange(coins->vout[prevout.n].nValue) || !MoneyRange(nValueIn))
Gavin Andresen's avatar
Gavin Andresen committed
1454
                return state.DoS(100, error("CheckInputs() : txin values out of range"),
1455
                                 REJECT_INVALID, "bad-txns-inputvalues-outofrange");
1456
1457

        }
Pieter Wuille's avatar
Pieter Wuille committed
1458

1459
        if (nValueIn < tx.GetValueOut())
1460
1461
            return state.DoS(100, error("CheckInputs() : %s value in (%s) < value out (%s)",
                                        tx.GetHash().ToString(), FormatMoney(nValueIn), FormatMoney(tx.GetValueOut())),
1462
                             REJECT_INVALID, "bad-txns-in-belowout");
Pieter Wuille's avatar
Pieter Wuille committed
1463
1464

        // Tally transaction fees
1465
        CAmount nTxFee = nValueIn - tx.GetValueOut();
Pieter Wuille's avatar
Pieter Wuille committed
1466
        if (nTxFee < 0)
1467
            return state.DoS(100, error("CheckInputs() : %s nTxFee < 0", tx.GetHash().ToString()),
1468
                             REJECT_INVALID, "bad-txns-fee-negative");
Pieter Wuille's avatar
Pieter Wuille committed
1469
1470
        nFees += nTxFee;
        if (!MoneyRange(nFees))
Gavin Andresen's avatar
Gavin Andresen committed
1471
            return state.DoS(100, error("CheckInputs() : nFees out of range"),
1472
                             REJECT_INVALID, "bad-txns-fee-outofrange");
Pieter Wuille's avatar
Pieter Wuille committed
1473

1474
1475
1476
1477
        // The first loop above does all the inexpensive checks.
        // Only if ALL inputs pass do we perform expensive ECDSA signature checks.
        // Helps prevent CPU exhaustion attacks.

Pieter Wuille's avatar
Pieter Wuille committed
1478
        // Skip ECDSA signature verification when connecting blocks
1479
        // before the last block chain checkpoint. This is safe because block merkle hashes are
Pieter Wuille's avatar
Pieter Wuille committed
1480
        // still computed and checked, and any change will be caught at the next checkpoint.
1481
        if (fScriptChecks) {
1482
1483
            for (unsigned int i = 0; i < tx.vin.size(); i++) {
                const COutPoint &prevout = tx.vin[i].prevout;
1484
1485
                const CCoins* coins = inputs.AccessCoins(prevout.hash);
                assert(coins);
1486

1487
                // Verify signature
1488
                CScriptCheck check(*coins, tx, i, flags, cacheStore);
1489
1490
1491
                if (pvChecks) {
                    pvChecks->push_back(CScriptCheck());
                    check.swap(pvChecks->back());
1492
                } else if (!check()) {
1493
1494
1495
1496
1497
1498
1499
                    if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) {
                        // Check whether the failure was caused by a
                        // non-mandatory script verification check, such as
                        // non-standard DER encodings or non-null dummy
                        // arguments; if so, don't trigger DoS protection to
                        // avoid splitting the network between upgraded and
                        // non-upgraded nodes.
1500
                        CScriptCheck check(*coins, tx, i,
1501
                                flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore);
1502
                        if (check())
1503
                            return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError())));
1504
                    }
1505
1506
1507
1508
1509
1510
1511
                    // Failures of other flags indicate a transaction that is
                    // invalid in new blocks, e.g. a invalid P2SH. We DoS ban
                    // such nodes as they are not following the protocol. That
                    // said during an upgrade careful thought should be taken
                    // as to the correct behavior - we may want to continue
                    // peering with non-upgraded nodes even after a soft-fork
                    // super-majority vote has passed.
1512
                    return state.DoS(100,false, REJECT_INVALID, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError())));
1513
                }
1514
            }
s_nakamoto's avatar
s_nakamoto committed
1515
1516
1517
1518
1519
1520
1521
1522
        }
    }

    return true;
}



1523
bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
s_nakamoto's avatar
s_nakamoto committed
1524
{
1525
    assert(pindex->GetBlockHash() == view.GetBestBlock());
s_nakamoto's avatar
s_nakamoto committed
1526

1527
1528
1529
1530
1531
    if (pfClean)
        *pfClean = false;

    bool fClean = true;

Pieter Wuille's avatar
Pieter Wuille committed
1532
    CBlockUndo blockUndo;
Pieter Wuille's avatar
Pieter Wuille committed
1533
1534
1535
1536
1537
    CDiskBlockPos pos = pindex->GetUndoPos();
    if (pos.IsNull())
        return error("DisconnectBlock() : no undo data available");
    if (!blockUndo.ReadFromDisk(pos, pindex->pprev->GetBlockHash()))
        return error("DisconnectBlock() : failure reading undo data");
s_nakamoto's avatar
s_nakamoto committed
1538

1539
    if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
1540
        return error("DisconnectBlock() : block and undo data inconsistent");
Pieter Wuille's avatar
Pieter Wuille committed
1541
1542

    // undo transactions in reverse order
1543
1544
    for (int i = block.vtx.size() - 1; i >= 0; i--) {
        const CTransaction &tx = block.vtx[i];
Pieter Wuille's avatar
Pieter Wuille committed
1545
1546
        uint256 hash = tx.GetHash();

1547
1548
1549
1550
        // Check that all outputs are available and match the outputs in the block itself
        // exactly. Note that transactions with only provably unspendable outputs won't
        // have outputs available even in the block itself, so we handle that case
        // specially with outsEmpty.
1551
        {
1552
        CCoins outsEmpty;
1553
1554
        CCoinsModifier outs = view.ModifyCoins(hash);
        outs->ClearUnspendable();
Pieter Wuille's avatar
Pieter Wuille committed
1555

1556
        CCoins outsBlock(tx, pindex->nHeight);
1557
1558
1559
1560
        // The CCoins serialization does not serialize negative numbers.
        // No network rules currently depend on the version here, so an inconsistency is harmless
        // but it must be corrected before txout nversion ever influences a network rule.
        if (outsBlock.nVersion < 0)
1561
1562
            outs->nVersion = outsBlock.nVersion;
        if (*outs != outsBlock)
1563
            fClean = fClean && error("DisconnectBlock() : added transaction mismatch? database corrupted");
Pieter Wuille's avatar
Pieter Wuille committed
1564
1565

        // remove outputs
1566
1567
        outs->Clear();
        }
Pieter Wuille's avatar
Pieter Wuille committed
1568
1569
1570
1571

        // restore inputs
        if (i > 0) { // not coinbases
            const CTxUndo &txundo = blockUndo.vtxundo[i-1];
1572
1573
            if (txundo.vprevout.size() != tx.vin.size())
                return error("DisconnectBlock() : transaction and undo data inconsistent");
Pieter Wuille's avatar
Pieter Wuille committed
1574
1575
1576
            for (unsigned int j = tx.vin.size(); j-- > 0;) {
                const COutPoint &out = tx.vin[j].prevout;
                const CTxInUndo &undo = txundo.vprevout[j];
1577
                CCoinsModifier coins = view.ModifyCoins(out.hash);
1578
1579
                if (undo.nHeight != 0) {
                    // undo data contains height: this is the last output of the prevout tx being spent
1580
                    if (!coins->IsPruned())
1581
                        fClean = fClean && error("DisconnectBlock() : undo data overwriting existing transaction");
1582
1583
1584
1585
                    coins->Clear();
                    coins->fCoinBase = undo.fCoinBase;
                    coins->nHeight = undo.nHeight;
                    coins->nVersion = undo.nVersion;
Pieter Wuille's avatar
Pieter Wuille committed
1586
                } else {
1587
                    if (coins->IsPruned())
1588
                        fClean = fClean && error("DisconnectBlock() : undo data adding output to missing transaction");
Pieter Wuille's avatar
Pieter Wuille committed
1589
                }
1590
                if (coins->IsAvailable(out.n))
1591
                    fClean = fClean && error("DisconnectBlock() : undo data overwriting existing output");
1592
1593
1594
                if (coins->vout.size() < out.n+1)
                    coins->vout.resize(out.n+1);
                coins->vout[out.n] = undo.txout;
Pieter Wuille's avatar
Pieter Wuille committed
1595
1596
1597
1598
1599
            }
        }
    }

    // move best block pointer to prevout block
1600
    view.SetBestBlock(pindex->pprev->GetBlockHash());
Pieter Wuille's avatar
Pieter Wuille committed
1601

1602
1603
1604
1605
1606
1607
    if (pfClean) {
        *pfClean = fClean;
        return true;
    } else {
        return fClean;
    }
s_nakamoto's avatar
s_nakamoto committed
1608
1609
}

1610
void static FlushBlockFile(bool fFinalize = false)
Pieter Wuille's avatar
Pieter Wuille committed
1611
1612
1613
{
    LOCK(cs_LastBlockFile);

1614
    CDiskBlockPos posOld(nLastBlockFile, 0);
Pieter Wuille's avatar
Pieter Wuille committed
1615
1616

    FILE *fileOld = OpenBlockFile(posOld);
1617
    if (fileOld) {
1618
        if (fFinalize)
1619
            TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nSize);
1620
1621
1622
        FileCommit(fileOld);
        fclose(fileOld);
    }
Pieter Wuille's avatar
Pieter Wuille committed
1623
1624

    fileOld = OpenUndoFile(posOld);
1625
    if (fileOld) {
1626
        if (fFinalize)
1627
            TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nUndoSize);
1628
1629
1630
        FileCommit(fileOld);
        fclose(fileOld);
    }
Pieter Wuille's avatar
Pieter Wuille committed
1631
1632
}

Pieter Wuille's avatar
Pieter Wuille committed
1633
bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize);
Pieter Wuille's avatar
Pieter Wuille committed
1634

1635
1636
static CCheckQueue<CScriptCheck> scriptcheckqueue(128);

1637
void ThreadScriptCheck() {
1638
1639
1640
1641
    RenameThread("bitcoin-scriptch");
    scriptcheckqueue.Thread();
}

1642
1643
1644
1645
1646
1647
static int64_t nTimeVerify = 0;
static int64_t nTimeConnect = 0;
static int64_t nTimeIndex = 0;
static int64_t nTimeCallbacks = 0;
static int64_t nTimeTotal = 0;

1648
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck)
s_nakamoto's avatar
s_nakamoto committed
1649
{
1650
    AssertLockHeld(cs_main);
s_nakamoto's avatar
s_nakamoto committed
1651
    // Check it again in case a previous version let a bad block in
1652
    if (!CheckBlock(block, state, !fJustCheck, !fJustCheck))
s_nakamoto's avatar
s_nakamoto committed
1653
1654
        return false;

Pieter Wuille's avatar
Pieter Wuille committed
1655
    // verify that the view's current state corresponds to the previous block
1656
1657
    uint256 hashPrevBlock = pindex->pprev == NULL ? uint256(0) : pindex->pprev->GetBlockHash();
    assert(hashPrevBlock == view.GetBestBlock());
Pieter Wuille's avatar
Pieter Wuille committed
1658

1659
1660
    // Special case for the genesis block, skipping connection of its transactions
    // (its coinbase is unspendable)
1661
    if (block.GetHash() == Params().HashGenesisBlock()) {
1662
        view.SetBestBlock(pindex->GetBlockHash());
1663
1664
1665
        return true;
    }

1666
1667
    bool fScriptChecks = pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate();

1668
1669
1670
1671
1672
1673
1674
    // Do not allow blocks that contain transactions which 'overwrite' older transactions,
    // unless those are already completely spent.
    // If such overwrites are allowed, coinbases and transactions depending upon those
    // can be duplicated to remove the ability to spend the first instance -- even after
    // being sent to another address.
    // See BIP30 and http://r6.ca/blog/20120206T005236Z.html for more information.
    // This logic is not necessary for memory pool transactions, as AcceptToMemoryPool
1675
    // already refuses previously-known transaction ids entirely.
1676
1677
1678
1679
    // This rule was originally applied all blocks whose timestamp was after March 15, 2012, 0:00 UTC.
    // Now that the whole chain is irreversibly beyond that time it is applied to all blocks except the
    // two in the chain that violate it. This prevents exploiting the issue against nodes in their
    // initial block download.
1680
1681
    bool fEnforceBIP30 = (!pindex->phashBlock) || // Enforce on CreateNewBlock invocations which don't have a hash.
                          !((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
1682
                           (pindex->nHeight==91880 && pindex->GetBlockHash() == uint256("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")));
Pieter Wuille's avatar
Pieter Wuille committed
1683
    if (fEnforceBIP30) {
1684
        BOOST_FOREACH(const CTransaction& tx, block.vtx) {
1685
1686
            const CCoins* coins = view.AccessCoins(tx.GetHash());
            if (coins && !coins->IsPruned())
Gavin Andresen's avatar
Gavin Andresen committed
1687
                return state.DoS(100, error("ConnectBlock() : tried to overwrite transaction"),
1688
                                 REJECT_INVALID, "bad-txns-BIP30");
Pieter Wuille's avatar
Pieter Wuille committed
1689
1690
        }
    }
1691

1692
    // BIP16 didn't become active until Apr 1 2012
1693
    int64_t nBIP16SwitchTime = 1333238400;
jtimon's avatar
jtimon committed
1694
    bool fStrictPayToScriptHash = (pindex->GetBlockTime() >= nBIP16SwitchTime);
1695

1696
    unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE;
1697

Pieter Wuille's avatar
Pieter Wuille committed
1698
1699
1700
1701
1702
    // Start enforcing the DERSIG (BIP66) rules, for block.nVersion=3 blocks, when 75% of the network has upgraded:
    if (block.nVersion >= 3 && CBlockIndex::IsSuperMajority(3, pindex->pprev, Params().EnforceBlockUpgradeMajority())) {
        flags |= SCRIPT_VERIFY_DERSIG;
    }

Pieter Wuille's avatar
Pieter Wuille committed
1703
1704
    CBlockUndo blockundo;

1705
1706
    CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL);

1707
    int64_t nTimeStart = GetTimeMicros();
1708
    CAmount nFees = 0;
1709
    int nInputs = 0;
1710
    unsigned int nSigOps = 0;
1711
    CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
1712
    std::vector<std::pair<uint256, CDiskTxPos> > vPos;
1713
    vPos.reserve(block.vtx.size());
Pieter Wuille's avatar
Pieter Wuille committed
1714
    blockundo.vtxundo.reserve(block.vtx.size() - 1);
1715
    for (unsigned int i = 0; i < block.vtx.size(); i++)
s_nakamoto's avatar
s_nakamoto committed
1716
    {
1717
        const CTransaction &tx = block.vtx[i];
Pieter Wuille's avatar
Pieter Wuille committed
1718

1719
        nInputs += tx.vin.size();
1720
        nSigOps += GetLegacySigOpCount(tx);
1721
        if (nSigOps > MAX_BLOCK_SIGOPS)
Gavin Andresen's avatar
Gavin Andresen committed
1722
            return state.DoS(100, error("ConnectBlock() : too many sigops"),
1723
                             REJECT_INVALID, "bad-blk-sigops");
1724

1725
1726
        if (!tx.IsCoinBase())
        {
1727
            if (!view.HaveInputs(tx))
Gavin Andresen's avatar
Gavin Andresen committed
1728
                return state.DoS(100, error("ConnectBlock() : inputs missing/spent"),
1729
                                 REJECT_INVALID, "bad-txns-inputs-missingorspent");
1730

1731
1732
1733
1734
1735
            if (fStrictPayToScriptHash)
            {
                // Add in sigops done by pay-to-script-hash inputs;
                // this is to prevent a "rogue miner" from creating
                // an incredibly-expensive-to-validate block.
1736
                nSigOps += GetP2SHSigOpCount(tx, view);
1737
                if (nSigOps > MAX_BLOCK_SIGOPS)
Gavin Andresen's avatar
Gavin Andresen committed
1738
                    return state.DoS(100, error("ConnectBlock() : too many sigops"),
1739
                                     REJECT_INVALID, "bad-blk-sigops");
1740
            }
1741

1742
            nFees += view.GetValueIn(tx)-tx.GetValueOut();
Pieter Wuille's avatar
Pieter Wuille committed
1743

1744
            std::vector<CScriptCheck> vChecks;
1745
            if (!CheckInputs(tx, state, view, fScriptChecks, flags, false, nScriptCheckThreads ? &vChecks : NULL))
1746
                return false;
1747
            control.Add(vChecks);
1748
1749
        }

Pieter Wuille's avatar
Pieter Wuille committed
1750
1751
1752
1753
1754
        CTxUndo undoDummy;
        if (i > 0) {
            blockundo.vtxundo.push_back(CTxUndo());
        }
        UpdateCoins(tx, state, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight);
1755

1756
        vPos.push_back(std::make_pair(tx.GetHash(), pos));
1757
        pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
s_nakamoto's avatar
s_nakamoto committed
1758
    }
1759
1760
    int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart;
    LogPrint("bench", "      - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime1 - nTimeStart), 0.001 * (nTime1 - nTimeStart) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime1 - nTimeStart) / (nInputs-1), nTimeConnect * 0.000001);
Gavin Andresen's avatar
Gavin Andresen committed
1761

1762
    if (block.vtx[0].GetValueOut() > GetBlockValue(pindex->nHeight, nFees))
Gavin Andresen's avatar
Gavin Andresen committed
1763
        return state.DoS(100,
1764
                         error("ConnectBlock() : coinbase pays too much (actual=%d vs limit=%d)",
1765
                               block.vtx[0].GetValueOut(), GetBlockValue(pindex->nHeight, nFees)),
Philip Kaufmann's avatar
Philip Kaufmann committed
1766
                               REJECT_INVALID, "bad-cb-amount");
Pieter Wuille's avatar
Pieter Wuille committed
1767

1768
    if (!control.Wait())
Pieter Wuille's avatar
Pieter Wuille committed
1769
        return state.DoS(100, false);
1770
1771
    int64_t nTime2 = GetTimeMicros(); nTimeVerify += nTime2 - nTimeStart;
    LogPrint("bench", "    - Verify %u txins: %.2fms (%.3fms/txin) [%.2fs]\n", nInputs - 1, 0.001 * (nTime2 - nTimeStart), nInputs <= 1 ? 0 : 0.001 * (nTime2 - nTimeStart) / (nInputs-1), nTimeVerify * 0.000001);
1772

1773
1774
1775
    if (fJustCheck)
        return true;

Pieter Wuille's avatar
Pieter Wuille committed
1776
    // Write undo information to disk
1777
    if (pindex->GetUndoPos().IsNull() || !pindex->IsValid(BLOCK_VALID_SCRIPTS))
Pieter Wuille's avatar
Pieter Wuille committed
1778
    {
1779
1780
        if (pindex->GetUndoPos().IsNull()) {
            CDiskBlockPos pos;
Pieter Wuille's avatar
Pieter Wuille committed
1781
            if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
1782
                return error("ConnectBlock() : FindUndoPos failed");
Pieter Wuille's avatar
Pieter Wuille committed
1783
            if (!blockundo.WriteToDisk(pos, pindex->pprev->GetBlockHash()))
1784
                return state.Abort("Failed to write undo data");
1785
1786
1787
1788
1789
1790

            // update nUndoPos in block index
            pindex->nUndoPos = pos.nPos;
            pindex->nStatus |= BLOCK_HAVE_UNDO;
        }

1791
        pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
1792
        setDirtyBlockIndex.insert(pindex);
s_nakamoto's avatar
s_nakamoto committed
1793
1794
    }

1795
    if (fTxIndex)
Pieter Wuille's avatar
Pieter Wuille committed
1796
        if (!pblocktree->WriteTxIndex(vPos))
1797
            return state.Abort("Failed to write transaction index");
1798

1799
    // add this block to the view's block chain
1800
    view.SetBestBlock(pindex->GetBlockHash());
Pieter Wuille's avatar
Pieter Wuille committed
1801

1802
1803
1804
    int64_t nTime3 = GetTimeMicros(); nTimeIndex += nTime3 - nTime2;
    LogPrint("bench", "    - Index writing: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeIndex * 0.000001);

1805
1806
1807
    // Watch for changes to the previous coinbase transaction.
    static uint256 hashPrevBestCoinBase;
    g_signals.UpdatedTransaction(hashPrevBestCoinBase);
1808
    hashPrevBestCoinBase = block.vtx[0].GetHash();
1809

1810
1811
1812
    int64_t nTime4 = GetTimeMicros(); nTimeCallbacks += nTime4 - nTime3;
    LogPrint("bench", "    - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeCallbacks * 0.000001);

s_nakamoto's avatar
s_nakamoto committed
1813
1814
1815
    return true;
}

1816
1817
1818
1819
1820
1821
enum FlushStateMode {
    FLUSH_STATE_IF_NEEDED,
    FLUSH_STATE_PERIODIC,
    FLUSH_STATE_ALWAYS
};

1822
1823
1824
1825
1826
/**
 * Update the on-disk chain state.
 * The caches and indexes are flushed if either they're too large, forceWrite is set, or
 * fast is not set and it's been a while since the last write.
 */
1827
bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
1828
    LOCK(cs_main);
1829
    static int64_t nLastWrite = 0;
1830
    try {
1831
1832
1833
    if ((mode == FLUSH_STATE_ALWAYS) ||
        ((mode == FLUSH_STATE_PERIODIC || mode == FLUSH_STATE_IF_NEEDED) && pcoinsTip->GetCacheSize() > nCoinCacheSize) ||
        (mode == FLUSH_STATE_PERIODIC && GetTimeMicros() > nLastWrite + DATABASE_WRITE_INTERVAL * 1000000)) {
1834
1835
1836
1837
1838
1839
        // Typical CCoins structures on disk are around 100 bytes in size.
        // Pushing a new one to the database can cause it to be written
        // twice (once in the log, and once in the tables). This is already
        // an overestimation, as most will delete an existing entry or
        // overwrite one. Still, use a conservative safety factor of 2.
        if (!CheckDiskSpace(100 * 2 * 2 * pcoinsTip->GetCacheSize()))
1840
            return state.Error("out of disk space");
1841
        // First make sure all block and undo data is flushed to disk.
Pieter Wuille's avatar
Pieter Wuille committed
1842
        FlushBlockFile();
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
        // Then update all block file information (which may refer to block and undo files).
        bool fileschanged = false;
        for (set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) {
            if (!pblocktree->WriteBlockFileInfo(*it, vinfoBlockFile[*it])) {
                return state.Abort("Failed to write to block index");
            }
            fileschanged = true;
            setDirtyFileInfo.erase(it++);
        }
        if (fileschanged && !pblocktree->WriteLastBlockFile(nLastBlockFile)) {
            return state.Abort("Failed to write to block index");
        }
        for (set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) {
             if (!pblocktree->WriteBlockIndex(CDiskBlockIndex(*it))) {
                 return state.Abort("Failed to write to block index");
             }
             setDirtyBlockIndex.erase(it++);
        }
1861
        pblocktree->Sync();
1862
        // Finally flush the chainstate (which may refer to block index entries).
Pieter Wuille's avatar
Pieter Wuille committed
1863
        if (!pcoinsTip->Flush())
1864
            return state.Abort("Failed to write to coin database");
1865
        // Update best block in wallet (so we can detect restored wallets).
1866
        if (mode != FLUSH_STATE_IF_NEEDED) {
1867
1868
            g_signals.SetBestChain(chainActive.GetLocator());
        }
1869
        nLastWrite = GetTimeMicros();
Pieter Wuille's avatar
Pieter Wuille committed
1870
    }
1871
1872
1873
    } catch (const std::runtime_error& e) {
        return state.Abort(std::string("System error while flushing: ") + e.what());
    }
1874
1875
    return true;
}
Pieter Wuille's avatar
Pieter Wuille committed
1876

1877
1878
void FlushStateToDisk() {
    CValidationState state;
1879
    FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
1880
1881
}

1882
/** Update chainActive and related internal data structures. */
1883
void static UpdateTip(CBlockIndex *pindexNew) {
1884
    chainActive.SetTip(pindexNew);
s_nakamoto's avatar
s_nakamoto committed
1885
1886
1887

    // New best block
    nTimeBestReceived = GetTime();
1888
    mempool.AddTransactionsUpdated(1);
1889

1890
    LogPrintf("UpdateTip: new best=%s  height=%d  log2_work=%.8g  tx=%lu  date=%s progress=%f  cache=%u\n",
1891
      chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.Tip()->nChainTx,
1892
      DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
1893
      Checkpoints::GuessVerificationProgress(chainActive.Tip()), (unsigned int)pcoinsTip->GetCacheSize());
s_nakamoto's avatar
s_nakamoto committed
1894

1895
1896
    cvBlockChange.notify_all();

1897
    // Check the version of the last 100 blocks to see if we need to upgrade:
1898
1899
    static bool fWarned = false;
    if (!IsInitialBlockDownload() && !fWarned)
1900
1901
    {
        int nUpgraded = 0;
1902
        const CBlockIndex* pindex = chainActive.Tip();
1903
1904
1905
1906
1907
1908
1909
        for (int i = 0; i < 100 && pindex != NULL; i++)
        {
            if (pindex->nVersion > CBlock::CURRENT_VERSION)
                ++nUpgraded;
            pindex = pindex->pprev;
        }
        if (nUpgraded > 0)
1910
            LogPrintf("SetBestChain: %d of last 100 blocks above version %d\n", nUpgraded, (int)CBlock::CURRENT_VERSION);
1911
        if (nUpgraded > 100/2)
1912
        {
1913
            // strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user:
1914
            strMiscWarning = _("Warning: This version is obsolete, upgrade required!");
1915
1916
1917
            CAlert::Notify(strMiscWarning, true);
            fWarned = true;
        }
1918
    }
1919
}
1920

1921
/** Disconnect chainActive's tip. */
1922
1923
1924
1925
1926
1927
1928
bool static DisconnectTip(CValidationState &state) {
    CBlockIndex *pindexDelete = chainActive.Tip();
    assert(pindexDelete);
    mempool.check(pcoinsTip);
    // Read block from disk.
    CBlock block;
    if (!ReadBlockFromDisk(block, pindexDelete))
1929
        return state.Abort("Failed to read block");
1930
1931
    // Apply the block atomically to the chain state.
    int64_t nStart = GetTimeMicros();
1932
    {
1933
        CCoinsViewCache view(pcoinsTip);
1934
1935
1936
        if (!DisconnectBlock(block, state, pindexDelete, view))
            return error("DisconnectTip() : DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
        assert(view.Flush());
1937
    }
1938
    LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
1939
    // Write the chain state to disk, if necessary.
1940
    if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
1941
        return false;
Gavin Andresen's avatar
Gavin Andresen committed
1942
    // Resurrect mempool transactions from the disconnected block.
1943
1944
    BOOST_FOREACH(const CTransaction &tx, block.vtx) {
        // ignore validation errors in resurrected transactions
Gavin Andresen's avatar
Gavin Andresen committed
1945
        list<CTransaction> removed;
1946
        CValidationState stateDummy;
1947
1948
        if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
            mempool.remove(tx, removed, true);
1949
    }
1950
    mempool.removeCoinbaseSpends(pcoinsTip, pindexDelete->nHeight);
1951
1952
1953
    mempool.check(pcoinsTip);
    // Update chainActive and related variables.
    UpdateTip(pindexDelete->pprev);
Gavin Andresen's avatar
Gavin Andresen committed
1954
1955
1956
    // Let wallets know transactions went from 1-confirmed to
    // 0-confirmed or conflicted:
    BOOST_FOREACH(const CTransaction &tx, block.vtx) {
1957
        SyncWithWallets(tx, NULL);
Gavin Andresen's avatar
Gavin Andresen committed
1958
    }
1959
    return true;
1960
}
1961

1962
1963
1964
1965
1966
1967
static int64_t nTimeReadFromDisk = 0;
static int64_t nTimeConnectTotal = 0;
static int64_t nTimeFlush = 0;
static int64_t nTimeChainState = 0;
static int64_t nTimePostConnect = 0;

1968
1969
1970
1971
/** 
 * Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock
 * corresponding to pindexNew, to bypass loading it again from disk.
 */
1972
bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *pblock) {
1973
    assert(pindexNew->pprev == chainActive.Tip());
1974
    mempool.check(pcoinsTip);
1975
    // Read block from disk.
1976
    int64_t nTime1 = GetTimeMicros();
1977
    CBlock block;
1978
1979
    if (!pblock) {
        if (!ReadBlockFromDisk(block, pindexNew))
1980
            return state.Abort("Failed to read block");
1981
1982
        pblock = &block;
    }
1983
    // Apply the block atomically to the chain state.
1984
1985
1986
    int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1;
    int64_t nTime3;
    LogPrint("bench", "  - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001);
s_nakamoto's avatar
s_nakamoto committed
1987
    {
1988
        CCoinsViewCache view(pcoinsTip);
1989
        CInv inv(MSG_BLOCK, pindexNew->GetBlockHash());
1990
1991
1992
        bool rv = ConnectBlock(*pblock, state, pindexNew, view);
        g_signals.BlockChecked(*pblock, state);
        if (!rv) {
1993
1994
1995
            if (state.IsInvalid())
                InvalidBlockFound(pindexNew, state);
            return error("ConnectTip() : ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
1996
        }
1997
        mapBlockSource.erase(inv.hash);
1998
1999
        nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
        LogPrint("bench", "  - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
2000
        assert(view.Flush());
s_nakamoto's avatar
s_nakamoto committed
2001
    }
2002
2003
    int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
    LogPrint("bench", "  - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001);
2004
    // Write the chain state to disk, if necessary.
2005
    if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
2006
        return false;
2007
2008
    int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
    LogPrint("bench", "  - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001);
2009
    // Remove conflicting transactions from the mempool.
Gavin Andresen's avatar
Gavin Andresen committed
2010
    list<CTransaction> txConflicted;
2011
    mempool.removeForBlock(pblock->vtx, pindexNew->nHeight, txConflicted);
2012
2013
2014
    mempool.check(pcoinsTip);
    // Update chainActive & related variables.
    UpdateTip(pindexNew);
Gavin Andresen's avatar
Gavin Andresen committed
2015
2016
2017
    // Tell wallet about transactions that went from mempool
    // to conflicted:
    BOOST_FOREACH(const CTransaction &tx, txConflicted) {
2018
        SyncWithWallets(tx, NULL);
Gavin Andresen's avatar
Gavin Andresen committed
2019
2020
    }
    // ... and about transactions that got confirmed:
2021
2022
    BOOST_FOREACH(const CTransaction &tx, pblock->vtx) {
        SyncWithWallets(tx, pblock);
Gavin Andresen's avatar
Gavin Andresen committed
2023
    }
2024

2025
2026
2027
    int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
    LogPrint("bench", "  - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001);
    LogPrint("bench", "- Connect block: %.2fms [%.2fs]\n", (nTime6 - nTime1) * 0.001, nTimeTotal * 0.000001);
s_nakamoto's avatar
s_nakamoto committed
2028
2029
2030
    return true;
}

2031
2032
2033
2034
/**
 * Return the tip of the chain with the most work in it, that isn't
 * known to be invalid (it's however far from certain to be valid).
 */
2035
static CBlockIndex* FindMostWorkChain() {
2036
    do {
2037
2038
        CBlockIndex *pindexNew = NULL;

2039
2040
        // Find the best candidate header.
        {
2041
2042
            std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexCandidates.rbegin();
            if (it == setBlockIndexCandidates.rend())
2043
                return NULL;
2044
2045
2046
2047
2048
2049
2050
2051
            pindexNew = *it;
        }

        // Check whether all blocks on the path between the currently active chain and the candidate are valid.
        // Just going until the active chain is an optimization, as we know all blocks in it are valid already.
        CBlockIndex *pindexTest = pindexNew;
        bool fInvalidAncestor = false;
        while (pindexTest && !chainActive.Contains(pindexTest)) {
Pieter Wuille's avatar
Pieter Wuille committed
2052
2053
            assert(pindexTest->nStatus & BLOCK_HAVE_DATA);
            assert(pindexTest->nChainTx || pindexTest->nHeight == 0);
2054
            if (pindexTest->nStatus & BLOCK_FAILED_MASK) {
2055
2056
                // Candidate has an invalid ancestor, remove entire chain from the set.
                if (pindexBestInvalid == NULL || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
2057
2058
                    pindexBestInvalid = pindexNew;
                CBlockIndex *pindexFailed = pindexNew;
2059
2060
                while (pindexTest != pindexFailed) {
                    pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
2061
                    setBlockIndexCandidates.erase(pindexFailed);
2062
2063
                    pindexFailed = pindexFailed->pprev;
                }
2064
                setBlockIndexCandidates.erase(pindexTest);
2065
2066
                fInvalidAncestor = true;
                break;
Pieter Wuille's avatar
Pieter Wuille committed
2067
            }
2068
            pindexTest = pindexTest->pprev;
s_nakamoto's avatar
s_nakamoto committed
2069
        }
2070
2071
        if (!fInvalidAncestor)
            return pindexNew;
2072
2073
    } while(true);
}
s_nakamoto's avatar
s_nakamoto committed
2074

2075
/** Delete all entries in setBlockIndexCandidates that are worse than the current tip. */
2076
2077
2078
2079
static void PruneBlockIndexCandidates() {
    // Note that we can't delete the current block itself, as we may need to return to it later in case a
    // reorganization to a better block fails.
    std::set<CBlockIndex*, CBlockIndexWorkComparator>::iterator it = setBlockIndexCandidates.begin();
2080
    while (it != setBlockIndexCandidates.end() && setBlockIndexCandidates.value_comp()(*it, chainActive.Tip())) {
2081
2082
        setBlockIndexCandidates.erase(it++);
    }
2083
2084
    // Either the current tip or a successor of it we're working towards is left in setBlockIndexCandidates.
    assert(!setBlockIndexCandidates.empty());
2085
2086
}

2087
2088
2089
2090
/**
 * Try to make some progress towards making pindexMostWork the active block.
 * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork.
 */
2091
static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, CBlock *pblock) {
2092
    AssertLockHeld(cs_main);
2093
    bool fInvalidFound = false;
2094
2095
    const CBlockIndex *pindexOldTip = chainActive.Tip();
    const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork);
s_nakamoto's avatar
s_nakamoto committed
2096

2097
2098
2099
2100
2101
    // Disconnect active blocks which are no longer in the best chain.
    while (chainActive.Tip() && chainActive.Tip() != pindexFork) {
        if (!DisconnectTip(state))
            return false;
    }
2102

2103
2104
    // Build list of new blocks to connect.
    std::vector<CBlockIndex*> vpindexToConnect;
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
    bool fContinue = true;
    int nHeight = pindexFork ? pindexFork->nHeight : -1;
    while (fContinue && nHeight != pindexMostWork->nHeight) {
    // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need
    // a few blocks along the way.
    int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight);
    vpindexToConnect.clear();
    vpindexToConnect.reserve(nTargetHeight - nHeight);
    CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight);
    while (pindexIter && pindexIter->nHeight != nHeight) {
2115
2116
        vpindexToConnect.push_back(pindexIter);
        pindexIter = pindexIter->pprev;
2117
    }
2118
    nHeight = nTargetHeight;
2119

2120
2121
    // Connect new blocks.
    BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) {
2122
        if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) {
2123
2124
2125
2126
2127
            if (state.IsInvalid()) {
                // The block violates a consensus rule.
                if (!state.CorruptionPossible())
                    InvalidChainFound(vpindexToConnect.back());
                state = CValidationState();
2128
                fInvalidFound = true;
2129
                fContinue = false;
2130
2131
2132
2133
2134
2135
                break;
            } else {
                // A system error occurred (disk space, database error, ...).
                return false;
            }
        } else {
2136
            PruneBlockIndexCandidates();
2137
2138
            if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) {
                // We're in a better position than we were. Return temporarily to release the lock.
2139
                fContinue = false;
2140
                break;
2141
2142
            }
        }
2143
    }
2144
    }
s_nakamoto's avatar
s_nakamoto committed
2145

2146
2147
2148
2149
2150
2151
    // Callbacks/notifications for a new best chain.
    if (fInvalidFound)
        CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
    else
        CheckForkWarningConditions();

s_nakamoto's avatar
s_nakamoto committed
2152
2153
2154
    return true;
}

2155
2156
2157
2158
2159
/**
 * Make the best chain active, in multiple steps. The result is either failure
 * or an activated best chain. pblock is either NULL or a pointer to a block
 * that is already loaded (to avoid loading it again from disk).
 */
2160
bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
2161
2162
    CBlockIndex *pindexNewTip = NULL;
    CBlockIndex *pindexMostWork = NULL;
2163
2164
2165
    do {
        boost::this_thread::interruption_point();

2166
2167
2168
2169
        bool fInitialDownload;
        {
            LOCK(cs_main);
            pindexMostWork = FindMostWorkChain();
2170

2171
2172
2173
            // Whether we have anything to do at all.
            if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip())
                return true;
2174

2175
            if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL))
2176
                return false;
2177

2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
            pindexNewTip = chainActive.Tip();
            fInitialDownload = IsInitialBlockDownload();
        }
        // When we reach this point, we switched to a new tip (stored in pindexNewTip).

        // Notifications/callbacks that can run without cs_main
        if (!fInitialDownload) {
            uint256 hashNewTip = pindexNewTip->GetBlockHash();
            // Relay inventory, but don't relay old inventory during initial block download.
            int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate();
2188
            {
2189
2190
2191
2192
                LOCK(cs_vNodes);
                BOOST_FOREACH(CNode* pnode, vNodes)
                    if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
                        pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip));
2193
            }
2194
            // Notify external listeners about the new tip.
2195
            uiInterface.NotifyBlockTip(hashNewTip);
2196
2197
        }
    } while(pindexMostWork != chainActive.Tip());
2198

2199
    // Write changes periodically to disk, after relay.
2200
    if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) {
2201
2202
2203
        return false;
    }

2204
2205
    return true;
}
2206

2207
2208
2209
2210
2211
bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
    AssertLockHeld(cs_main);

    // Mark the block itself as invalid.
    pindex->nStatus |= BLOCK_FAILED_VALID;
2212
    setDirtyBlockIndex.insert(pindex);
2213
2214
2215
2216
2217
    setBlockIndexCandidates.erase(pindex);

    while (chainActive.Contains(pindex)) {
        CBlockIndex *pindexWalk = chainActive.Tip();
        pindexWalk->nStatus |= BLOCK_FAILED_CHILD;
2218
        setDirtyBlockIndex.insert(pindexWalk);
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
        setBlockIndexCandidates.erase(pindexWalk);
        // ActivateBestChain considers blocks already in chainActive
        // unconditionally valid already, so force disconnect away from it.
        if (!DisconnectTip(state)) {
            return false;
        }
    }

    // The resulting new best tip may not be in setBlockIndexCandidates anymore, so
    // add them again.
    BlockMap::iterator it = mapBlockIndex.begin();
    while (it != mapBlockIndex.end()) {
        if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) {
2232
            setBlockIndexCandidates.insert(it->second);
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
        }
        it++;
    }

    InvalidChainFound(pindex);
    return true;
}

bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex) {
    AssertLockHeld(cs_main);

    int nHeight = pindex->nHeight;

    // Remove the invalidity flag from this block and all its descendants.
    BlockMap::iterator it = mapBlockIndex.begin();
    while (it != mapBlockIndex.end()) {
        if (!it->second->IsValid() && it->second->GetAncestor(nHeight) == pindex) {
            it->second->nStatus &= ~BLOCK_FAILED_MASK;
2251
            setDirtyBlockIndex.insert(it->second);
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
            if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) {
                setBlockIndexCandidates.insert(it->second);
            }
            if (it->second == pindexBestInvalid) {
                // Reset invalid block marker if it was pointing to one of those.
                pindexBestInvalid = NULL;
            }
        }
        it++;
    }

    // Remove the invalidity flag from all ancestors too.
    while (pindex != NULL) {
2265
2266
2267
        if (pindex->nStatus & BLOCK_FAILED_MASK) {
            pindex->nStatus &= ~BLOCK_FAILED_MASK;
            setDirtyBlockIndex.insert(pindex);
2268
2269
2270
2271
2272
2273
        }
        pindex = pindex->pprev;
    }
    return true;
}

Pieter Wuille's avatar
Pieter Wuille committed
2274
CBlockIndex* AddToBlockIndex(const CBlockHeader& block)
s_nakamoto's avatar
s_nakamoto committed
2275
2276
{
    // Check for duplicate
2277
    uint256 hash = block.GetHash();
2278
    BlockMap::iterator it = mapBlockIndex.find(hash);
2279
2280
    if (it != mapBlockIndex.end())
        return it->second;
s_nakamoto's avatar
s_nakamoto committed
2281
2282

    // Construct new block index object
2283
    CBlockIndex* pindexNew = new CBlockIndex(block);
2284
    assert(pindexNew);
Pieter Wuille's avatar
Pieter Wuille committed
2285
2286
2287
2288
    // We assign the sequence id to blocks only when the full data is available,
    // to avoid miners withholding blocks but broadcasting headers, to get a
    // competitive advantage.
    pindexNew->nSequenceId = 0;
2289
    BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
s_nakamoto's avatar
s_nakamoto committed
2290
    pindexNew->phashBlock = &((*mi).first);
2291
    BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock);
s_nakamoto's avatar
s_nakamoto committed
2292
2293
2294
2295
    if (miPrev != mapBlockIndex.end())
    {
        pindexNew->pprev = (*miPrev).second;
        pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
2296
        pindexNew->BuildSkip();
s_nakamoto's avatar
s_nakamoto committed
2297
    }
2298
    pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew);
2299
    pindexNew->RaiseValidity(BLOCK_VALID_TREE);
Pieter Wuille's avatar
Pieter Wuille committed
2300
2301
2302
    if (pindexBestHeader == NULL || pindexBestHeader->nChainWork < pindexNew->nChainWork)
        pindexBestHeader = pindexNew;

2303
    setDirtyBlockIndex.insert(pindexNew);
2304
2305
2306
2307

    return pindexNew;
}

2308
/** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */
2309
2310
2311
bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos)
{
    pindexNew->nTx = block.vtx.size();
Pieter Wuille's avatar
Pieter Wuille committed
2312
    pindexNew->nChainTx = 0;
2313
2314
    pindexNew->nFile = pos.nFile;
    pindexNew->nDataPos = pos.nPos;
Pieter Wuille's avatar
Pieter Wuille committed
2315
    pindexNew->nUndoPos = 0;
2316
    pindexNew->nStatus |= BLOCK_HAVE_DATA;
Pieter Wuille's avatar
Pieter Wuille committed
2317
2318
2319
2320
2321
    pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
    {
         LOCK(cs_nBlockSequenceId);
         pindexNew->nSequenceId = nBlockSequenceId++;
    }
2322
    setDirtyBlockIndex.insert(pindexNew);
2323

Pieter Wuille's avatar
Pieter Wuille committed
2324
2325
2326
2327
    if (pindexNew->pprev == NULL || pindexNew->pprev->nChainTx) {
        // If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS.
        deque<CBlockIndex*> queue;
        queue.push_back(pindexNew);
s_nakamoto's avatar
s_nakamoto committed
2328

Pieter Wuille's avatar
Pieter Wuille committed
2329
2330
2331
2332
2333
        // Recursively process any descendant blocks that now may be eligible to be connected.
        while (!queue.empty()) {
            CBlockIndex *pindex = queue.front();
            queue.pop_front();
            pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
2334
            setBlockIndexCandidates.insert(pindex);
Pieter Wuille's avatar
Pieter Wuille committed
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
            std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex);
            while (range.first != range.second) {
                std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
                queue.push_back(it->second);
                range.first++;
                mapBlocksUnlinked.erase(it);
            }
        }
    } else {
        if (pindexNew->pprev && pindexNew->pprev->IsValid(BLOCK_VALID_TREE)) {
            mapBlocksUnlinked.insert(std::make_pair(pindexNew->pprev, pindexNew));
        }
    }
s_nakamoto's avatar
s_nakamoto committed
2348

2349
    return true;
s_nakamoto's avatar
s_nakamoto committed
2350
2351
}

2352
bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false)
Pieter Wuille's avatar
Pieter Wuille committed
2353
2354
2355
{
    LOCK(cs_LastBlockFile);

2356
2357
2358
2359
2360
2361
2362
2363
    unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile;
    if (vinfoBlockFile.size() <= nFile) {
        vinfoBlockFile.resize(nFile + 1);
    }

    if (!fKnown) {
        while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
            LogPrintf("Leaving block file %i: %s\n", nFile, vinfoBlockFile[nFile].ToString());
2364
            FlushBlockFile(true);
2365
2366
2367
2368
            nFile++;
            if (vinfoBlockFile.size() <= nFile) {
                vinfoBlockFile.resize(nFile + 1);
            }
2369
        }
2370
2371
        pos.nFile = nFile;
        pos.nPos = vinfoBlockFile[nFile].nSize;
Pieter Wuille's avatar
Pieter Wuille committed
2372
2373
    }

2374
2375
    nLastBlockFile = nFile;
    vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
2376
2377
2378
2379
    if (fKnown)
        vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
    else
        vinfoBlockFile[nFile].nSize += nAddSize;
Pieter Wuille's avatar
Pieter Wuille committed
2380

2381
2382
    if (!fKnown) {
        unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
2383
        unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
2384
        if (nNewChunks > nOldChunks) {
2385
2386
2387
            if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) {
                FILE *file = OpenBlockFile(pos);
                if (file) {
2388
                    LogPrintf("Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile);
2389
2390
2391
                    AllocateFileRange(file, pos.nPos, nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos);
                    fclose(file);
                }
2392
            }
2393
            else
2394
                return state.Error("out of disk space");
2395
2396
2397
        }
    }

2398
    setDirtyFileInfo.insert(nFile);
Pieter Wuille's avatar
Pieter Wuille committed
2399
2400
2401
    return true;
}

Pieter Wuille's avatar
Pieter Wuille committed
2402
bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize)
Pieter Wuille's avatar
Pieter Wuille committed
2403
2404
2405
2406
2407
{
    pos.nFile = nFile;

    LOCK(cs_LastBlockFile);

2408
    unsigned int nNewSize;
2409
2410
    pos.nPos = vinfoBlockFile[nFile].nUndoSize;
    nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize;
2411
    setDirtyFileInfo.insert(nFile);
2412
2413
2414
2415

    unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
    unsigned int nNewChunks = (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
    if (nNewChunks > nOldChunks) {
2416
2417
2418
        if (CheckDiskSpace(nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos)) {
            FILE *file = OpenUndoFile(pos);
            if (file) {
2419
                LogPrintf("Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile);
2420
2421
2422
                AllocateFileRange(file, pos.nPos, nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos);
                fclose(file);
            }
2423
        }
2424
        else
2425
            return state.Error("out of disk space");
Pieter Wuille's avatar
Pieter Wuille committed
2426
2427
2428
2429
2430
    }

    return true;
}

2431
bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW)
s_nakamoto's avatar
s_nakamoto committed
2432
{
2433
    // Check proof of work matches claimed amount
2434
    if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits))
2435
        return state.DoS(50, error("CheckBlockHeader() : proof of work failed"),
2436
                         REJECT_INVALID, "high-hash");
2437

s_nakamoto's avatar
s_nakamoto committed
2438
    // Check timestamp
2439
    if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
2440
        return state.Invalid(error("CheckBlockHeader() : block timestamp too far in the future"),
2441
                             REJECT_INVALID, "time-too-new");
s_nakamoto's avatar
s_nakamoto committed
2442

2443
2444
2445
    return true;
}

2446
bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot)
s_nakamoto's avatar
s_nakamoto committed
2447
{
Pieter Wuille's avatar
Pieter Wuille committed
2448
    // These are checks that are independent of context.
s_nakamoto's avatar
s_nakamoto committed
2449

2450
2451
    // Check that the header is valid (particularly PoW).  This is mostly
    // redundant with the call in AcceptBlockHeader.
2452
2453
2454
    if (!CheckBlockHeader(block, state, fCheckPOW))
        return false;

Pieter Wuille's avatar
Pieter Wuille committed
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
    // Check the merkle root.
    if (fCheckMerkleRoot) {
        bool mutated;
        uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated);
        if (block.hashMerkleRoot != hashMerkleRoot2)
            return state.DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"),
                             REJECT_INVALID, "bad-txnmrklroot", true);

        // Check for merkle tree malleability (CVE-2012-2459): repeating sequences
        // of transactions in a block without affecting the merkle root of a block,
        // while still invalidating it.
        if (mutated)
            return state.DoS(100, error("CheckBlock() : duplicate transaction"),
                             REJECT_INVALID, "bad-txns-duplicate", true);
    }

    // All potential-corruption validation must be done before we do any
    // transaction validation, as otherwise we may mark the header as invalid
    // because we receive the wrong transactions for it.

s_nakamoto's avatar
s_nakamoto committed
2475
    // Size limits
2476
    if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
Gavin Andresen's avatar
Gavin Andresen committed
2477
        return state.DoS(100, error("CheckBlock() : size limits failed"),
2478
                         REJECT_INVALID, "bad-blk-length");
s_nakamoto's avatar
s_nakamoto committed
2479
2480

    // First transaction must be coinbase, the rest must not be
2481
    if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
Gavin Andresen's avatar
Gavin Andresen committed
2482
        return state.DoS(100, error("CheckBlock() : first tx is not coinbase"),
2483
                         REJECT_INVALID, "bad-cb-missing");
2484
2485
    for (unsigned int i = 1; i < block.vtx.size(); i++)
        if (block.vtx[i].IsCoinBase())
Gavin Andresen's avatar
Gavin Andresen committed
2486
            return state.DoS(100, error("CheckBlock() : more than one coinbase"),
2487
                             REJECT_INVALID, "bad-cb-multiple");
s_nakamoto's avatar
s_nakamoto committed
2488
2489

    // Check transactions
2490
    BOOST_FOREACH(const CTransaction& tx, block.vtx)
2491
        if (!CheckTransaction(tx, state))
Pieter Wuille's avatar
Pieter Wuille committed
2492
            return error("CheckBlock() : CheckTransaction failed");
s_nakamoto's avatar
s_nakamoto committed
2493

2494
    unsigned int nSigOps = 0;
2495
    BOOST_FOREACH(const CTransaction& tx, block.vtx)
Gavin Andresen's avatar
Gavin Andresen committed
2496
    {
2497
        nSigOps += GetLegacySigOpCount(tx);
Gavin Andresen's avatar
Gavin Andresen committed
2498
2499
    }
    if (nSigOps > MAX_BLOCK_SIGOPS)
Gavin Andresen's avatar
Gavin Andresen committed
2500
        return state.DoS(100, error("CheckBlock() : out-of-bounds SigOpCount"),
2501
                         REJECT_INVALID, "bad-blk-sigops", true);
s_nakamoto's avatar
s_nakamoto committed
2502
2503
2504
2505

    return true;
}

2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev)
{
    uint256 hash = block.GetHash();
    if (hash == Params().HashGenesisBlock())
        return true;

    assert(pindexPrev);

    int nHeight = pindexPrev->nHeight+1;

    // Check proof of work
    if ((!Params().SkipProofOfWorkCheck()) &&
       (block.nBits != GetNextWorkRequired(pindexPrev, &block)))
        return state.DoS(100, error("%s : incorrect proof of work", __func__),
                         REJECT_INVALID, "bad-diffbits");

    // Check timestamp against prev
    if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
        return state.Invalid(error("%s : block's timestamp is too early", __func__),
                             REJECT_INVALID, "time-too-old");

    // Check that the block chain matches the known block chain up to a checkpoint
    if (!Checkpoints::CheckBlock(nHeight, hash))
        return state.DoS(100, error("%s : rejected by checkpoint lock-in at %d", __func__, nHeight),
                         REJECT_CHECKPOINT, "checkpoint mismatch");

    // Don't accept any forks from the main chain prior to last checkpoint
    CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint();
    if (pcheckpoint && nHeight < pcheckpoint->nHeight)
        return state.DoS(100, error("%s : forked chain older than last checkpoint (height %d)", __func__, nHeight));

    // Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
    if (block.nVersion < 2 && 
        CBlockIndex::IsSuperMajority(2, pindexPrev, Params().RejectBlockOutdatedMajority()))
    {
        return state.Invalid(error("%s : rejected nVersion=1 block", __func__),
                             REJECT_OBSOLETE, "bad-version");
    }

Pieter Wuille's avatar
Pieter Wuille committed
2545
2546
2547
2548
2549
2550
2551
    // Reject block.nVersion=2 blocks when 95% (75% on testnet) of the network has upgraded:
    if (block.nVersion < 3 && CBlockIndex::IsSuperMajority(3, pindexPrev, Params().RejectBlockOutdatedMajority()))
    {
        return state.Invalid(error("%s : rejected nVersion=2 block", __func__),
                             REJECT_OBSOLETE, "bad-version");
    }

2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
    return true;
}

bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex * const pindexPrev)
{
    const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->nHeight + 1;

    // Check that all transactions are finalized
    BOOST_FOREACH(const CTransaction& tx, block.vtx)
        if (!IsFinalTx(tx, nHeight, block.GetBlockTime())) {
            return state.DoS(10, error("%s : contains a non-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal");
        }

    // Enforce block.nVersion=2 rule that the coinbase starts with serialized block height
    // if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet):
    if (block.nVersion >= 2 && 
        CBlockIndex::IsSuperMajority(2, pindexPrev, Params().EnforceBlockUpgradeMajority()))
    {
        CScript expect = CScript() << nHeight;
        if (block.vtx[0].vin[0].scriptSig.size() < expect.size() ||
            !std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) {
            return state.DoS(100, error("%s : block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height");
        }
    }

    return true;
}

Pieter Wuille's avatar
Pieter Wuille committed
2580
bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex)
s_nakamoto's avatar
s_nakamoto committed
2581
{
2582
    AssertLockHeld(cs_main);
s_nakamoto's avatar
s_nakamoto committed
2583
    // Check for duplicate
2584
    uint256 hash = block.GetHash();
2585
    BlockMap::iterator miSelf = mapBlockIndex.find(hash);
2586
2587
    CBlockIndex *pindex = NULL;
    if (miSelf != mapBlockIndex.end()) {
Pieter Wuille's avatar
Pieter Wuille committed
2588
        // Block header is already known.
2589
        pindex = miSelf->second;
Pieter Wuille's avatar
Pieter Wuille committed
2590
2591
        if (ppindex)
            *ppindex = pindex;
2592
        if (pindex->nStatus & BLOCK_FAILED_MASK)
2593
            return state.Invalid(error("%s : block is marked invalid", __func__), 0, "duplicate");
Pieter Wuille's avatar
Pieter Wuille committed
2594
        return true;
2595
    }
s_nakamoto's avatar
s_nakamoto committed
2596

2597
2598
2599
    if (!CheckBlockHeader(block, state))
        return false;

s_nakamoto's avatar
s_nakamoto committed
2600
    // Get prev block index
2601
    CBlockIndex* pindexPrev = NULL;
2602
    if (hash != Params().HashGenesisBlock()) {
2603
        BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
2604
        if (mi == mapBlockIndex.end())
2605
            return state.DoS(10, error("%s : prev block not found", __func__), 0, "bad-prevblk");
2606
        pindexPrev = (*mi).second;
2607
2608
        if (pindexPrev->nStatus & BLOCK_FAILED_MASK)
            return state.DoS(100, error("%s : prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
2609
2610
    }

2611
2612
2613
    if (!ContextualCheckBlockHeader(block, state, pindexPrev))
        return false;

2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
    if (pindex == NULL)
        pindex = AddToBlockIndex(block);

    if (ppindex)
        *ppindex = pindex;

    return true;
}

bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, CDiskBlockPos* dbp)
{
    AssertLockHeld(cs_main);

    CBlockIndex *&pindex = *ppindex;

    if (!AcceptBlockHeader(block, state, &pindex))
        return false;

Pieter Wuille's avatar
Pieter Wuille committed
2632
2633
2634
2635
2636
2637
    if (pindex->nStatus & BLOCK_HAVE_DATA) {
        // TODO: deal better with duplicate blocks.
        // return state.DoS(20, error("AcceptBlock() : already have block %d %s", pindex->nHeight, pindex->GetBlockHash().ToString()), REJECT_DUPLICATE, "duplicate");
        return true;
    }

2638
    if ((!CheckBlock(block, state)) || !ContextualCheckBlock(block, state, pindex->pprev)) {
2639
        if (state.IsInvalid() && !state.CorruptionPossible()) {
2640
            pindex->nStatus |= BLOCK_FAILED_VALID;
2641
            setDirtyBlockIndex.insert(pindex);
2642
2643
2644
2645
2646
2647
        }
        return false;
    }

    int nHeight = pindex->nHeight;

s_nakamoto's avatar
s_nakamoto committed
2648
    // Write block to history file
Pieter Wuille's avatar
Pieter Wuille committed
2649
    try {
2650
        unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
Pieter Wuille's avatar
Pieter Wuille committed
2651
2652
2653
        CDiskBlockPos blockPos;
        if (dbp != NULL)
            blockPos = *dbp;
jtimon's avatar
jtimon committed
2654
        if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL))
Pieter Wuille's avatar
Pieter Wuille committed
2655
2656
            return error("AcceptBlock() : FindBlockPos failed");
        if (dbp == NULL)
2657
            if (!WriteBlockToDisk(block, blockPos))
2658
                return state.Abort("Failed to write block");
2659
2660
        if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
            return error("AcceptBlock() : ReceivedBlockTransactions failed");
Pieter Wuille's avatar
Pieter Wuille committed
2661
    } catch(std::runtime_error &e) {
2662
        return state.Abort(std::string("System error: ") + e.what());
Pieter Wuille's avatar
Pieter Wuille committed
2663
    }
s_nakamoto's avatar
s_nakamoto committed
2664
2665
2666
2667

    return true;
}

2668
bool CBlockIndex::IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired)
2669
{
2670
    unsigned int nToCheck = Params().ToCheckBlockUpgradeMajority();
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
    unsigned int nFound = 0;
    for (unsigned int i = 0; i < nToCheck && nFound < nRequired && pstart != NULL; i++)
    {
        if (pstart->nVersion >= minVersion)
            ++nFound;
        pstart = pstart->pprev;
    }
    return (nFound >= nRequired);
}

2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
/** Turn the lowest '1' bit in the binary representation of a number into a '0'. */
int static inline InvertLowestOne(int n) { return n & (n - 1); }

/** Compute what height to jump back to with the CBlockIndex::pskip pointer. */
int static inline GetSkipHeight(int height) {
    if (height < 2)
        return 0;

    // Determine which height to jump back to. Any number strictly lower than height is acceptable,
    // but the following expression seems to perform well in simulations (max 110 steps to go back
    // up to 2**18 blocks).
    return (height & 1) ? InvertLowestOne(InvertLowestOne(height - 1)) + 1 : InvertLowestOne(height);
}

CBlockIndex* CBlockIndex::GetAncestor(int height)
{
    if (height > nHeight || height < 0)
        return NULL;

    CBlockIndex* pindexWalk = this;
    int heightWalk = nHeight;
    while (heightWalk > height) {
        int heightSkip = GetSkipHeight(heightWalk);
        int heightSkipPrev = GetSkipHeight(heightWalk - 1);
        if (heightSkip == height ||
            (heightSkip > height && !(heightSkipPrev < heightSkip - 2 &&
                                      heightSkipPrev >= height))) {
            // Only follow pskip if pprev->pskip isn't better than pskip->pprev.
            pindexWalk = pindexWalk->pskip;
            heightWalk = heightSkip;
        } else {
            pindexWalk = pindexWalk->pprev;
            heightWalk--;
        }
    }
    return pindexWalk;
}

const CBlockIndex* CBlockIndex::GetAncestor(int height) const
{
    return const_cast<CBlockIndex*>(this)->GetAncestor(height);
}

void CBlockIndex::BuildSkip()
{
    if (pprev)
        pskip = pprev->GetAncestor(GetSkipHeight(nHeight));
}

2730
bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp)
s_nakamoto's avatar
s_nakamoto committed
2731
2732
{
    // Preliminary checks
Pieter Wuille's avatar
Pieter Wuille committed
2733
    bool checked = CheckBlock(*pblock, state);
s_nakamoto's avatar
s_nakamoto committed
2734
2735

    {
Pieter Wuille's avatar
Pieter Wuille committed
2736
2737
2738
        LOCK(cs_main);
        MarkBlockAsReceived(pblock->GetHash());
        if (!checked) {
2739
            return error("%s : CheckBlock FAILED", __func__);
2740
        }
s_nakamoto's avatar
s_nakamoto committed
2741

Pieter Wuille's avatar
Pieter Wuille committed
2742
2743
2744
2745
2746
        // Store to disk
        CBlockIndex *pindex = NULL;
        bool ret = AcceptBlock(*pblock, state, &pindex, dbp);
        if (pindex && pfrom) {
            mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId();
s_nakamoto's avatar
s_nakamoto committed
2747
        }
Pieter Wuille's avatar
Pieter Wuille committed
2748
        if (!ret)
2749
            return error("%s : AcceptBlock FAILED", __func__);
2750
2751
    }

2752
    if (!ActivateBestChain(state, pblock))
2753
        return error("%s : ActivateBestChain failed", __func__);
2754

s_nakamoto's avatar
s_nakamoto committed
2755
2756
2757
    return true;
}

2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot)
{
    AssertLockHeld(cs_main);
    assert(pindexPrev == chainActive.Tip());

    CCoinsViewCache viewNew(pcoinsTip);
    CBlockIndex indexDummy(block);
    indexDummy.pprev = pindexPrev;
    indexDummy.nHeight = pindexPrev->nHeight + 1;

    // NOTE: CheckBlockHeader is called by CheckBlock
    if (!ContextualCheckBlockHeader(block, state, pindexPrev))
        return false;
    if (!CheckBlock(block, state, fCheckPOW, fCheckMerkleRoot))
        return false;
    if (!ContextualCheckBlock(block, state, pindexPrev))
        return false;
    if (!ConnectBlock(block, state, &indexDummy, viewNew, true))
        return false;
    assert(state.IsValid());

    return true;
}

s_nakamoto's avatar
s_nakamoto committed
2782
2783
2784
2785
2786
2787
2788







2789
bool AbortNode(const std::string &strMessage, const std::string &userMessage) {
2790
    strMiscWarning = strMessage;
2791
    LogPrintf("*** %s\n", strMessage);
2792
2793
2794
    uiInterface.ThreadSafeMessageBox(
        userMessage.empty() ? _("Error: A fatal internal error occured, see debug.log for details") : userMessage,
        "", CClientUIInterface::MSG_ERROR);
2795
2796
2797
    StartShutdown();
    return false;
}
Pieter Wuille's avatar
Pieter Wuille committed
2798

2799
bool CheckDiskSpace(uint64_t nAdditionalBytes)
s_nakamoto's avatar
s_nakamoto committed
2800
{
2801
    uint64_t nFreeBytesAvailable = filesystem::space(GetDataDir()).available;
s_nakamoto's avatar
s_nakamoto committed
2802

2803
2804
    // Check for nMinDiskSpace bytes (currently 50MB)
    if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
2805
        return AbortNode("Disk space is low!", _("Error: Disk space is low!"));
2806

s_nakamoto's avatar
s_nakamoto committed
2807
2808
2809
    return true;
}

Pieter Wuille's avatar
Pieter Wuille committed
2810
FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly)
2811
{
Pieter Wuille's avatar
Pieter Wuille committed
2812
    if (pos.IsNull())
s_nakamoto's avatar
s_nakamoto committed
2813
        return NULL;
2814
    boost::filesystem::path path = GetBlockPosFilename(pos, prefix);
Pieter Wuille's avatar
Pieter Wuille committed
2815
2816
2817
2818
    boost::filesystem::create_directories(path.parent_path());
    FILE* file = fopen(path.string().c_str(), "rb+");
    if (!file && !fReadOnly)
        file = fopen(path.string().c_str(), "wb+");
Pieter Wuille's avatar
Pieter Wuille committed
2819
    if (!file) {
2820
        LogPrintf("Unable to open file %s\n", path.string());
s_nakamoto's avatar
s_nakamoto committed
2821
        return NULL;
Pieter Wuille's avatar
Pieter Wuille committed
2822
    }
Pieter Wuille's avatar
Pieter Wuille committed
2823
2824
    if (pos.nPos) {
        if (fseek(file, pos.nPos, SEEK_SET)) {
2825
            LogPrintf("Unable to seek to position %u of %s\n", pos.nPos, path.string());
Pieter Wuille's avatar
Pieter Wuille committed
2826
2827
2828
2829
            fclose(file);
            return NULL;
        }
    }
s_nakamoto's avatar
s_nakamoto committed
2830
2831
2832
    return file;
}

Pieter Wuille's avatar
Pieter Wuille committed
2833
2834
2835
2836
FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly) {
    return OpenDiskFile(pos, "blk", fReadOnly);
}

2837
FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly) {
Pieter Wuille's avatar
Pieter Wuille committed
2838
2839
2840
    return OpenDiskFile(pos, "rev", fReadOnly);
}

2841
2842
boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix)
{
Suhas Daftuar's avatar
Suhas Daftuar committed
2843
    return GetDataDir() / "blocks" / strprintf("%s%05u.dat", prefix, pos.nFile);
2844
2845
}

2846
2847
2848
2849
2850
2851
CBlockIndex * InsertBlockIndex(uint256 hash)
{
    if (hash == 0)
        return NULL;

    // Return existing
2852
    BlockMap::iterator mi = mapBlockIndex.find(hash);
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
    if (mi != mapBlockIndex.end())
        return (*mi).second;

    // Create new
    CBlockIndex* pindexNew = new CBlockIndex();
    if (!pindexNew)
        throw runtime_error("LoadBlockIndex() : new CBlockIndex failed");
    mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
    pindexNew->phashBlock = &((*mi).first);

    return pindexNew;
}

bool static LoadBlockIndexDB()
{
    if (!pblocktree->LoadBlockIndexGuts())
        return false;

Gavin Andresen's avatar
Gavin Andresen committed
2871
    boost::this_thread::interruption_point();
2872

Pieter Wuille's avatar
Pieter Wuille committed
2873
    // Calculate nChainWork
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
    vector<pair<int, CBlockIndex*> > vSortedByHeight;
    vSortedByHeight.reserve(mapBlockIndex.size());
    BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
    {
        CBlockIndex* pindex = item.second;
        vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex));
    }
    sort(vSortedByHeight.begin(), vSortedByHeight.end());
    BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight)
    {
        CBlockIndex* pindex = item.second;
2885
        pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + GetBlockProof(*pindex);
Pieter Wuille's avatar
Pieter Wuille committed
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
        if (pindex->nStatus & BLOCK_HAVE_DATA) {
            if (pindex->pprev) {
                if (pindex->pprev->nChainTx) {
                    pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx;
                } else {
                    pindex->nChainTx = 0;
                    mapBlocksUnlinked.insert(std::make_pair(pindex->pprev, pindex));
                }
            } else {
                pindex->nChainTx = pindex->nTx;
            }
        }
        if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && (pindex->nChainTx || pindex->pprev == NULL))
2899
            setBlockIndexCandidates.insert(pindex);
2900
2901
        if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->nChainWork > pindexBestInvalid->nChainWork))
            pindexBestInvalid = pindex;
2902
2903
        if (pindex->pprev)
            pindex->BuildSkip();
Pieter Wuille's avatar
Pieter Wuille committed
2904
2905
        if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == NULL || CBlockIndexWorkComparator()(pindexBestHeader, pindex)))
            pindexBestHeader = pindex;
2906
2907
2908
2909
    }

    // Load block file info
    pblocktree->ReadLastBlockFile(nLastBlockFile);
2910
    vinfoBlockFile.resize(nLastBlockFile + 1);
2911
    LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile);
2912
2913
2914
    for (int nFile = 0; nFile <= nLastBlockFile; nFile++) {
        pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
    }
2915
    LogPrintf("%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString());
2916
2917
2918
2919
2920
2921
2922
2923
    for (int nFile = nLastBlockFile + 1; true; nFile++) {
        CBlockFileInfo info;
        if (pblocktree->ReadBlockFileInfo(nFile, info)) {
            vinfoBlockFile.push_back(info);
        } else {
            break;
        }
    }
2924

2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
    // Check presence of blk files
    LogPrintf("Checking all blk files are present...\n");
    set<int> setBlkDataFiles;
    BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
    {
        CBlockIndex* pindex = item.second;
        if (pindex->nStatus & BLOCK_HAVE_DATA) {
            setBlkDataFiles.insert(pindex->nFile);
        }
    }
    for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++)
    {
        CDiskBlockPos pos(*it, 0);
2938
        if (CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION).IsNull()) {
2939
2940
2941
2942
            return false;
        }
    }

2943
2944
2945
2946
2947
    // Check whether we need to continue reindexing
    bool fReindexing = false;
    pblocktree->ReadReindexing(fReindexing);
    fReindex |= fReindexing;

2948
2949
    // Check whether we have a transaction index
    pblocktree->ReadFlag("txindex", fTxIndex);
2950
    LogPrintf("LoadBlockIndexDB(): transaction index %s\n", fTxIndex ? "enabled" : "disabled");
2951

2952
    // Load pointer to end of best chain
2953
    BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
2954
    if (it == mapBlockIndex.end())
2955
        return true;
2956
    chainActive.SetTip(it->second);
2957
2958
2959

    PruneBlockIndexCandidates();

2960
    LogPrintf("LoadBlockIndexDB(): hashBestChain=%s height=%d date=%s progress=%f\n",
2961
        chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(),
2962
2963
        DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
        Checkpoints::GuessVerificationProgress(chainActive.Tip()));
2964

Pieter Wuille's avatar
Pieter Wuille committed
2965
2966
2967
    return true;
}

Cozz Lovan's avatar
Cozz Lovan committed
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
CVerifyDB::CVerifyDB()
{
    uiInterface.ShowProgress(_("Verifying blocks..."), 0);
}

CVerifyDB::~CVerifyDB()
{
    uiInterface.ShowProgress("", 100);
}

2978
bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth)
2979
{
2980
    LOCK(cs_main);
2981
    if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL)
Pieter Wuille's avatar
Pieter Wuille committed
2982
2983
        return true;

2984
    // Verify blocks in the best chain
2985
    if (nCheckDepth <= 0)
2986
        nCheckDepth = 1000000000; // suffices until the year 19000
2987
2988
    if (nCheckDepth > chainActive.Height())
        nCheckDepth = chainActive.Height();
Pieter Wuille's avatar
Pieter Wuille committed
2989
    nCheckLevel = std::max(0, std::min(4, nCheckLevel));
2990
    LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
2991
    CCoinsViewCache coins(coinsview);
2992
    CBlockIndex* pindexState = chainActive.Tip();
Pieter Wuille's avatar
Pieter Wuille committed
2993
2994
    CBlockIndex* pindexFailure = NULL;
    int nGoodTransactions = 0;
Pieter Wuille's avatar
Pieter Wuille committed
2995
    CValidationState state;
2996
    for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev)
2997
    {
Gavin Andresen's avatar
Gavin Andresen committed
2998
        boost::this_thread::interruption_point();
Cozz Lovan's avatar
Cozz Lovan committed
2999
        uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100)))));
3000
        if (pindex->nHeight < chainActive.Height()-nCheckDepth)
3001
3002
            break;
        CBlock block;
Pieter Wuille's avatar
Pieter Wuille committed
3003
        // check level 0: read from disk
3004
        if (!ReadBlockFromDisk(block, pindex))
3005
            return error("VerifyDB() : *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
3006
        // check level 1: verify block validity
3007
        if (nCheckLevel >= 1 && !CheckBlock(block, state))
3008
            return error("VerifyDB() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
Pieter Wuille's avatar
Pieter Wuille committed
3009
3010
3011
3012
3013
3014
        // check level 2: verify undo validity
        if (nCheckLevel >= 2 && pindex) {
            CBlockUndo undo;
            CDiskBlockPos pos = pindex->GetUndoPos();
            if (!pos.IsNull()) {
                if (!undo.ReadFromDisk(pos, pindex->pprev->GetBlockHash()))
3015
                    return error("VerifyDB() : *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
Pieter Wuille's avatar
Pieter Wuille committed
3016
3017
3018
            }
        }
        // check level 3: check for inconsistencies during memory-only disconnect of tip blocks
3019
        if (nCheckLevel >= 3 && pindex == pindexState && (coins.GetCacheSize() + pcoinsTip->GetCacheSize()) <= nCoinCacheSize) {
Pieter Wuille's avatar
Pieter Wuille committed
3020
            bool fClean = true;
3021
            if (!DisconnectBlock(block, state, pindex, coins, &fClean))
3022
                return error("VerifyDB() : *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
Pieter Wuille's avatar
Pieter Wuille committed
3023
3024
3025
3026
3027
3028
            pindexState = pindex->pprev;
            if (!fClean) {
                nGoodTransactions = 0;
                pindexFailure = pindex;
            } else
                nGoodTransactions += block.vtx.size();
3029
        }
3030
3031
        if (ShutdownRequested())
            return true;
3032
    }
Pieter Wuille's avatar
Pieter Wuille committed
3033
    if (pindexFailure)
3034
        return error("VerifyDB() : *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->nHeight + 1, nGoodTransactions);
Pieter Wuille's avatar
Pieter Wuille committed
3035
3036
3037
3038

    // check level 4: try reconnecting blocks
    if (nCheckLevel >= 4) {
        CBlockIndex *pindex = pindexState;
3039
        while (pindex != chainActive.Tip()) {
Gavin Andresen's avatar
Gavin Andresen committed
3040
            boost::this_thread::interruption_point();
Cozz Lovan's avatar
Cozz Lovan committed
3041
            uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50))));
3042
            pindex = chainActive.Next(pindex);
3043
            CBlock block;
3044
            if (!ReadBlockFromDisk(block, pindex))
3045
                return error("VerifyDB() : *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
3046
            if (!ConnectBlock(block, state, pindex, coins))
3047
                return error("VerifyDB() : *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
Pieter Wuille's avatar
Pieter Wuille committed
3048
        }
3049
3050
    }

3051
    LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", chainActive.Height() - pindexState->nHeight, nGoodTransactions);
Pieter Wuille's avatar
Pieter Wuille committed
3052

3053
3054
3055
    return true;
}

3056
3057
3058
void UnloadBlockIndex()
{
    mapBlockIndex.clear();
3059
    setBlockIndexCandidates.clear();
3060
    chainActive.SetTip(NULL);
3061
    pindexBestInvalid = NULL;
3062
3063
}

3064
bool LoadBlockIndex()
s_nakamoto's avatar
s_nakamoto committed
3065
{
3066
    // Load block index from databases
3067
    if (!fReindex && !LoadBlockIndexDB())
s_nakamoto's avatar
s_nakamoto committed
3068
        return false;
3069
3070
    return true;
}
3071
3072


3073
bool InitBlockIndex() {
3074
    LOCK(cs_main);
3075
    // Check whether we're already initialized
3076
    if (chainActive.Genesis() != NULL)
3077
3078
3079
3080
3081
        return true;

    // Use the provided setting for -txindex in the new database
    fTxIndex = GetBoolArg("-txindex", false);
    pblocktree->WriteFlag("txindex", fTxIndex);
3082
    LogPrintf("Initializing databases...\n");
3083
3084
3085
3086

    // Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
    if (!fReindex) {
        try {
3087
3088
            CBlock &block = const_cast<CBlock&>(Params().GenesisBlock());
            // Start new block file
3089
3090
3091
            unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
            CDiskBlockPos blockPos;
            CValidationState state;
jtimon's avatar
jtimon committed
3092
            if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.GetBlockTime()))
3093
                return error("LoadBlockIndex() : FindBlockPos failed");
3094
            if (!WriteBlockToDisk(block, blockPos))
3095
                return error("LoadBlockIndex() : writing genesis block to disk failed");
3096
3097
            CBlockIndex *pindex = AddToBlockIndex(block);
            if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
3098
                return error("LoadBlockIndex() : genesis block not accepted");
3099
            if (!ActivateBestChain(state, &block))
3100
                return error("LoadBlockIndex() : genesis block cannot be activated");
3101
            // Force a chainstate write so that when we VerifyDB in a moment, it doesnt check stale data
3102
            return FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
3103
3104
3105
        } catch(std::runtime_error &e) {
            return error("LoadBlockIndex() : failed to initialize block database: %s", e.what());
        }
s_nakamoto's avatar
s_nakamoto committed
3106
3107
3108
3109
3110
3111
3112
    }

    return true;
}



3113
bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
3114
{
3115
3116
    // Map of disk positions for blocks with unknown parent (only used for reindex)
    static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent;
3117
    int64_t nStart = GetTimeMillis();
3118

3119
    int nLoaded = 0;
Pieter Wuille's avatar
Pieter Wuille committed
3120
    try {
3121
        // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor
3122
        CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
3123
        uint64_t nRewind = blkdat.GetPos();
3124
        while (!blkdat.eof()) {
3125
3126
            boost::this_thread::interruption_point();

3127
3128
3129
            blkdat.SetPos(nRewind);
            nRewind++; // start one byte further next time, in case of failure
            blkdat.SetLimit(); // remove former limit
3130
            unsigned int nSize = 0;
3131
3132
            try {
                // locate a header
3133
                unsigned char buf[MESSAGE_START_SIZE];
3134
                blkdat.FindByte(Params().MessageStart()[0]);
3135
3136
                nRewind = blkdat.GetPos()+1;
                blkdat >> FLATDATA(buf);
3137
                if (memcmp(buf, Params().MessageStart(), MESSAGE_START_SIZE))
3138
3139
                    continue;
                // read size
3140
                blkdat >> nSize;
3141
3142
                if (nSize < 80 || nSize > MAX_BLOCK_SIZE)
                    continue;
ENikS's avatar
ENikS committed
3143
            } catch (const std::exception &) {
3144
3145
3146
3147
                // no valid block header found; don't complain
                break;
            }
            try {
3148
                // read block
3149
                uint64_t nBlockPos = blkdat.GetPos();
3150
3151
                if (dbp)
                    dbp->nPos = nBlockPos;
3152
                blkdat.SetLimit(nBlockPos + nSize);
3153
3154
3155
                blkdat.SetPos(nBlockPos);
                CBlock block;
                blkdat >> block;
3156
3157
                nRewind = blkdat.GetPos();

3158
3159
3160
                // detect out of order blocks, and store them for later
                uint256 hash = block.GetHash();
                if (hash != Params().HashGenesisBlock() && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) {
3161
                    LogPrint("reindex", "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
3162
                            block.hashPrevBlock.ToString());
3163
                    if (dbp)
3164
                        mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
3165
3166
3167
                    continue;
                }

3168
                // process in case the block isn't known yet
3169
                if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) {
3170
                    CValidationState state;
3171
                    if (ProcessNewBlock(state, NULL, &block, dbp))
3172
3173
3174
                        nLoaded++;
                    if (state.IsError())
                        break;
3175
3176
                } else if (hash != Params().HashGenesisBlock() && mapBlockIndex[hash]->nHeight % 1000 == 0) {
                    LogPrintf("Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->nHeight);
3177
                }
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192

                // Recursively process earlier encountered successors of this block
                deque<uint256> queue;
                queue.push_back(hash);
                while (!queue.empty()) {
                    uint256 head = queue.front();
                    queue.pop_front();
                    std::pair<std::multimap<uint256, CDiskBlockPos>::iterator, std::multimap<uint256, CDiskBlockPos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
                    while (range.first != range.second) {
                        std::multimap<uint256, CDiskBlockPos>::iterator it = range.first;
                        if (ReadBlockFromDisk(block, it->second))
                        {
                            LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
                                    head.ToString());
                            CValidationState dummy;
3193
                            if (ProcessNewBlock(dummy, NULL, &block, &it->second))
3194
3195
3196
3197
3198
3199
3200
3201
                            {
                                nLoaded++;
                                queue.push_back(block.GetHash());
                            }
                        }
                        range.first++;
                        mapBlocksUnknownParent.erase(it);
                    }
3202
                }
3203
            } catch (std::exception &e) {
3204
                LogPrintf("%s : Deserialize or I/O error - %s", __func__, e.what());
3205
3206
            }
        }
Pieter Wuille's avatar
Pieter Wuille committed
3207
    } catch(std::runtime_error &e) {
3208
        AbortNode(std::string("System error: ") + e.what());
3209
    }
3210
    if (nLoaded > 0)
3211
        LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart);
3212
3213
    return nLoaded > 0;
}
s_nakamoto's avatar
s_nakamoto committed
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224

//////////////////////////////////////////////////////////////////////////////
//
// CAlert
//

string GetWarnings(string strFor)
{
    int nPriority = 0;
    string strStatusBar;
    string strRPC;
3225
3226
3227
3228

    if (!CLIENT_VERSION_IS_RELEASE)
        strStatusBar = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications");

3229
3230
3231
    if (GetBoolArg("-testsafemode", false))
        strStatusBar = strRPC = "testsafemode enabled";

s_nakamoto's avatar
s_nakamoto committed
3232
3233
3234
3235
3236
3237
3238
    // Misc warnings like out of disk space and clock is wrong
    if (strMiscWarning != "")
    {
        nPriority = 1000;
        strStatusBar = strMiscWarning;
    }

3239
    if (fLargeWorkForkFound)
s_nakamoto's avatar
s_nakamoto committed
3240
3241
    {
        nPriority = 2000;
3242
3243
3244
        strStatusBar = strRPC = _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.");
    }
    else if (fLargeWorkInvalidChainFound)
s_nakamoto's avatar
s_nakamoto committed
3245
3246
    {
        nPriority = 2000;
3247
        strStatusBar = strRPC = _("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.");
s_nakamoto's avatar
s_nakamoto committed
3248
3249
3250
3251
    }

    // Alerts
    {
3252
        LOCK(cs_mapAlerts);
3253
        BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
s_nakamoto's avatar
s_nakamoto committed
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
        {
            const CAlert& alert = item.second;
            if (alert.AppliesToMe() && alert.nPriority > nPriority)
            {
                nPriority = alert.nPriority;
                strStatusBar = alert.strStatusBar;
            }
        }
    }

    if (strFor == "statusbar")
        return strStatusBar;
    else if (strFor == "rpc")
        return strRPC;
3268
    assert(!"GetWarnings() : invalid parameter");
s_nakamoto's avatar
s_nakamoto committed
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
    return "error";
}








//////////////////////////////////////////////////////////////////////////////
//
// Messages
//


3285
bool static AlreadyHave(const CInv& inv)
s_nakamoto's avatar
s_nakamoto committed
3286
3287
3288
{
    switch (inv.type)
    {
Jeff Garzik's avatar
Jeff Garzik committed
3289
3290
    case MSG_TX:
        {
Pieter Wuille's avatar
Pieter Wuille committed
3291
            bool txInMap = false;
3292
            txInMap = mempool.exists(inv.hash);
Pieter Wuille's avatar
Pieter Wuille committed
3293
            return txInMap || mapOrphanTransactions.count(inv.hash) ||
3294
                pcoinsTip->HaveCoins(inv.hash);
Jeff Garzik's avatar
Jeff Garzik committed
3295
3296
        }
    case MSG_BLOCK:
Pieter Wuille's avatar
Pieter Wuille committed
3297
        return mapBlockIndex.count(inv.hash);
s_nakamoto's avatar
s_nakamoto committed
3298
3299
3300
3301
3302
3303
    }
    // Don't know what it is, just say we already got one
    return true;
}


3304
3305
3306
3307
3308
3309
void static ProcessGetData(CNode* pfrom)
{
    std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();

    vector<CInv> vNotFound;

3310
3311
    LOCK(cs_main);

3312
3313
3314
3315
3316
3317
3318
    while (it != pfrom->vRecvGetData.end()) {
        // Don't bother if send buffer is too full to respond anyway
        if (pfrom->nSendSize >= SendBufferSize())
            break;

        const CInv &inv = *it;
        {
Gavin Andresen's avatar
Gavin Andresen committed
3319
            boost::this_thread::interruption_point();
3320
3321
3322
3323
            it++;

            if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
            {
3324
                bool send = false;
3325
                BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
3326
3327
                if (mi != mapBlockIndex.end())
                {
3328
                    if (chainActive.Contains(mi->second)) {
Philip Kaufmann's avatar
Philip Kaufmann committed
3329
                        send = true;
3330
3331
3332
3333
3334
3335
3336
3337
3338
                    } else {
                        // To prevent fingerprinting attacks, only send blocks outside of the active
                        // chain if they are valid, and no more than a month older than the best header
                        // chain we know about.
                        send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
                            (mi->second->GetBlockTime() > pindexBestHeader->GetBlockTime() - 30 * 24 * 60 * 60);
                        if (!send) {
                            LogPrintf("ProcessGetData(): ignoring request from peer=%i for old block that isn't in the main chain\n", pfrom->GetId());
                        }
3339
3340
3341
3342
3343
                    }
                }
                if (send)
                {
                    // Send block from disk
3344
                    CBlock block;
3345
3346
                    if (!ReadBlockFromDisk(block, (*mi).second))
                        assert(!"cannot load block from disk");
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
                    if (inv.type == MSG_BLOCK)
                        pfrom->PushMessage("block", block);
                    else // MSG_FILTERED_BLOCK)
                    {
                        LOCK(pfrom->cs_filter);
                        if (pfrom->pfilter)
                        {
                            CMerkleBlock merkleBlock(block, *pfrom->pfilter);
                            pfrom->PushMessage("merkleblock", merkleBlock);
                            // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see
                            // This avoids hurting performance by pointlessly requiring a round-trip
                            // Note that there is currently no way for a node to request any single transactions we didnt send here -
                            // they must either disconnect and retry or request the full block.
                            // Thus, the protocol spec specified allows for us to provide duplicate txn here,
                            // however we MUST always provide at least what the remote peer needs
                            typedef std::pair<unsigned int, uint256> PairType;
                            BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn)
                                if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, pair.second)))
                                    pfrom->PushMessage("tx", block.vtx[pair.first]);
                        }
                        // else
                            // no response
                    }

                    // Trigger them to send a getblocks request for the next batch of inventory
                    if (inv.hash == pfrom->hashContinue)
                    {
                        // Bypass PushInventory, this must send even if redundant,
                        // and we want it right after the last block so they don't
                        // wait for other stuff first.
                        vector<CInv> vInv;
3378
                        vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash()));
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
                        pfrom->PushMessage("inv", vInv);
                        pfrom->hashContinue = 0;
                    }
                }
            }
            else if (inv.IsKnownType())
            {
                // Send stream from relay memory
                bool pushed = false;
                {
                    LOCK(cs_mapRelay);
                    map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
                    if (mi != mapRelay.end()) {
                        pfrom->PushMessage(inv.GetCommand(), (*mi).second);
                        pushed = true;
                    }
                }
                if (!pushed && inv.type == MSG_TX) {
3397
3398
                    CTransaction tx;
                    if (mempool.lookup(inv.hash, tx)) {
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
                        CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
                        ss.reserve(1000);
                        ss << tx;
                        pfrom->PushMessage("tx", ss);
                        pushed = true;
                    }
                }
                if (!pushed) {
                    vNotFound.push_back(inv);
                }
            }

            // Track requests for our stuff.
3412
            g_signals.Inventory(inv.hash);
3413

3414
3415
            if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
                break;
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
        }
    }

    pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it);

    if (!vNotFound.empty()) {
        // Let the peer know that we didn't find what it asked for, so it doesn't
        // have to wait around forever. Currently only SPV clients actually care
        // about this message: it's needed when they are recursively walking the
        // dependencies of relevant unconfirmed transactions. SPV clients want to
        // do that because they want to know about (and store and rebroadcast and
        // risk analyze) the dependencies of transactions relevant to them, without
        // having to download the entire memory pool.
        pfrom->PushMessage("notfound", vNotFound);
    }
}

3433
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
s_nakamoto's avatar
s_nakamoto committed
3434
3435
{
    RandAddSeedPerfmon();
3436
    LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
s_nakamoto's avatar
s_nakamoto committed
3437
3438
    if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
    {
3439
        LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
s_nakamoto's avatar
s_nakamoto committed
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
        return true;
    }




    if (strCommand == "version")
    {
        // Each connection can only send one version message
        if (pfrom->nVersion != 0)
3450
        {
Gavin Andresen's avatar
Gavin Andresen committed
3451
            pfrom->PushMessage("reject", strCommand, REJECT_DUPLICATE, string("Duplicate version message"));
Pieter Wuille's avatar
Pieter Wuille committed
3452
            Misbehaving(pfrom->GetId(), 1);
s_nakamoto's avatar
s_nakamoto committed
3453
            return false;
3454
        }
s_nakamoto's avatar
s_nakamoto committed
3455

3456
        int64_t nTime;
s_nakamoto's avatar
s_nakamoto committed
3457
3458
        CAddress addrMe;
        CAddress addrFrom;
3459
        uint64_t nNonce = 1;
s_nakamoto's avatar
s_nakamoto committed
3460
        vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
3461
        if (pfrom->nVersion < MIN_PEER_PROTO_VERSION)
Pieter Wuille's avatar
Pieter Wuille committed
3462
        {
3463
            // disconnect from peers older than this proto version
3464
            LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
Gavin Andresen's avatar
Gavin Andresen committed
3465
3466
            pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
                               strprintf("Version must be %d or greater", MIN_PEER_PROTO_VERSION));
Pieter Wuille's avatar
Pieter Wuille committed
3467
3468
3469
3470
            pfrom->fDisconnect = true;
            return false;
        }

s_nakamoto's avatar
s_nakamoto committed
3471
3472
        if (pfrom->nVersion == 10300)
            pfrom->nVersion = 300;
Pieter Wuille's avatar
Pieter Wuille committed
3473
        if (!vRecv.empty())
s_nakamoto's avatar
s_nakamoto committed
3474
            vRecv >> addrFrom >> nNonce;
Mike Hearn's avatar
Mike Hearn committed
3475
        if (!vRecv.empty()) {
3476
            vRecv >> LIMITED_STRING(pfrom->strSubVer, 256);
Mike Hearn's avatar
Mike Hearn committed
3477
3478
            pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
        }
Pieter Wuille's avatar
Pieter Wuille committed
3479
        if (!vRecv.empty())
s_nakamoto's avatar
s_nakamoto committed
3480
            vRecv >> pfrom->nStartingHeight;
3481
3482
3483
3484
        if (!vRecv.empty())
            vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message
        else
            pfrom->fRelayTxes = true;
s_nakamoto's avatar
s_nakamoto committed
3485
3486
3487
3488

        // Disconnect if we connected to ourself
        if (nNonce == nLocalHostNonce && nNonce > 1)
        {
3489
            LogPrintf("connected to self at %s, disconnecting\n", pfrom->addr.ToString());
s_nakamoto's avatar
s_nakamoto committed
3490
3491
3492
3493
            pfrom->fDisconnect = true;
            return true;
        }

3494
3495
3496
3497
3498
3499
        pfrom->addrLocal = addrMe;
        if (pfrom->fInbound && addrMe.IsRoutable())
        {
            SeenLocal(addrMe);
        }

Gavin Andresen's avatar
Gavin Andresen committed
3500
3501
3502
3503
        // Be shy and don't send version until we hear
        if (pfrom->fInbound)
            pfrom->PushVersion();

s_nakamoto's avatar
s_nakamoto committed
3504
3505
        pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);

3506
3507
        // Potentially mark this peer as a preferred download peer.
        UpdatePreferredDownload(pfrom, State(pfrom->GetId()));
s_nakamoto's avatar
s_nakamoto committed
3508
3509

        // Change version
Pieter Wuille's avatar
Pieter Wuille committed
3510
        pfrom->PushMessage("verack");
3511
        pfrom->ssSend.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
s_nakamoto's avatar
s_nakamoto committed
3512

s_nakamoto's avatar
s_nakamoto committed
3513
3514
3515
        if (!pfrom->fInbound)
        {
            // Advertise our address
3516
            if (fListen && !IsInitialBlockDownload())
s_nakamoto's avatar
s_nakamoto committed
3517
            {
3518
3519
                CAddress addr = GetLocalAddress(&pfrom->addr);
                if (addr.IsRoutable())
3520
3521
3522
3523
                {
                    pfrom->PushAddress(addr);
                } else if (IsPeerAddrLocalGood(pfrom)) {
                    addr.SetIP(pfrom->addrLocal);
3524
                    pfrom->PushAddress(addr);
3525
                }
s_nakamoto's avatar
s_nakamoto committed
3526
3527
3528
            }

            // Get recent addresses
3529
            if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000)
s_nakamoto's avatar
s_nakamoto committed
3530
3531
3532
3533
            {
                pfrom->PushMessage("getaddr");
                pfrom->fGetAddr = true;
            }
3534
3535
3536
3537
3538
3539
3540
            addrman.Good(pfrom->addr);
        } else {
            if (((CNetAddr)pfrom->addr) == (CNetAddr)addrFrom)
            {
                addrman.Add(addrFrom, addrFrom);
                addrman.Good(addrFrom);
            }
s_nakamoto's avatar
s_nakamoto committed
3541
3542
        }

s_nakamoto's avatar
s_nakamoto committed
3543
        // Relay alerts
3544
3545
        {
            LOCK(cs_mapAlerts);
3546
            BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
s_nakamoto's avatar
s_nakamoto committed
3547
                item.second.RelayTo(pfrom);
3548
        }
s_nakamoto's avatar
s_nakamoto committed
3549
3550
3551

        pfrom->fSuccessfullyConnected = true;

3552
3553
3554
3555
3556
3557
3558
3559
        string remoteAddr;
        if (fLogIPs)
            remoteAddr = ", peeraddr=" + pfrom->addr.ToString();

        LogPrintf("receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
                  pfrom->cleanSubVer, pfrom->nVersion,
                  pfrom->nStartingHeight, addrMe.ToString(), pfrom->id,
                  remoteAddr);
3560

3561
        AddTimeData(pfrom->addr, nTime);
s_nakamoto's avatar
s_nakamoto committed
3562
3563
3564
3565
3566
3567
    }


    else if (pfrom->nVersion == 0)
    {
        // Must have a version message before anything else
Pieter Wuille's avatar
Pieter Wuille committed
3568
        Misbehaving(pfrom->GetId(), 1);
s_nakamoto's avatar
s_nakamoto committed
3569
3570
3571
3572
3573
3574
        return false;
    }


    else if (strCommand == "verack")
    {
3575
        pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
3576
3577
3578
3579
3580
3581

        // Mark this node as currently connected, so we update its timestamp later.
        if (pfrom->fNetworkNode) {
            LOCK(cs_main);
            State(pfrom->GetId())->fCurrentlyConnected = true;
        }
s_nakamoto's avatar
s_nakamoto committed
3582
3583
3584
3585
3586
3587
3588
    }


    else if (strCommand == "addr")
    {
        vector<CAddress> vAddr;
        vRecv >> vAddr;
s_nakamoto's avatar
s_nakamoto committed
3589
3590

        // Don't want addr from older versions unless seeding
3591
        if (pfrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000)
s_nakamoto's avatar
s_nakamoto committed
3592
3593
            return true;
        if (vAddr.size() > 1000)
3594
        {
Pieter Wuille's avatar
Pieter Wuille committed
3595
            Misbehaving(pfrom->GetId(), 20);
3596
            return error("message addr size() = %u", vAddr.size());
3597
        }
s_nakamoto's avatar
s_nakamoto committed
3598
3599

        // Store the new addresses
3600
        vector<CAddress> vAddrOk;
3601
3602
        int64_t nNow = GetAdjustedTime();
        int64_t nSince = nNow - 10 * 60;
3603
        BOOST_FOREACH(CAddress& addr, vAddr)
s_nakamoto's avatar
s_nakamoto committed
3604
        {
Gavin Andresen's avatar
Gavin Andresen committed
3605
3606
            boost::this_thread::interruption_point();

s_nakamoto's avatar
s_nakamoto committed
3607
3608
            if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
                addr.nTime = nNow - 5 * 24 * 60 * 60;
s_nakamoto's avatar
s_nakamoto committed
3609
            pfrom->AddAddressKnown(addr);
3610
            bool fReachable = IsReachable(addr);
s_nakamoto's avatar
s_nakamoto committed
3611
            if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
s_nakamoto's avatar
s_nakamoto committed
3612
3613
3614
            {
                // Relay to a limited number of other nodes
                {
3615
                    LOCK(cs_vNodes);
3616
3617
                    // Use deterministic randomness to send to the same nodes for 24 hours
                    // at a time so the setAddrKnowns of the chosen nodes prevent repeats
s_nakamoto's avatar
s_nakamoto committed
3618
3619
                    static uint256 hashSalt;
                    if (hashSalt == 0)
3620
                        hashSalt = GetRandHash();
3621
                    uint64_t hashAddr = addr.GetHash();
Pieter Wuille's avatar
Pieter Wuille committed
3622
                    uint256 hashRand = hashSalt ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60));
3623
                    hashRand = Hash(BEGIN(hashRand), END(hashRand));
s_nakamoto's avatar
s_nakamoto committed
3624
                    multimap<uint256, CNode*> mapMix;
3625
                    BOOST_FOREACH(CNode* pnode, vNodes)
3626
                    {
3627
                        if (pnode->nVersion < CADDR_TIME_VERSION)
s_nakamoto's avatar
s_nakamoto committed
3628
                            continue;
3629
3630
3631
3632
3633
3634
                        unsigned int nPointer;
                        memcpy(&nPointer, &pnode, sizeof(nPointer));
                        uint256 hashKey = hashRand ^ nPointer;
                        hashKey = Hash(BEGIN(hashKey), END(hashKey));
                        mapMix.insert(make_pair(hashKey, pnode));
                    }
3635
                    int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s)
s_nakamoto's avatar
s_nakamoto committed
3636
3637
3638
3639
                    for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
                        ((*mi).second)->PushAddress(addr);
                }
            }
3640
3641
3642
            // Do not store addresses outside our network
            if (fReachable)
                vAddrOk.push_back(addr);
s_nakamoto's avatar
s_nakamoto committed
3643
        }
3644
        addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60);
s_nakamoto's avatar
s_nakamoto committed
3645
3646
        if (vAddr.size() < 1000)
            pfrom->fGetAddr = false;
3647
3648
        if (pfrom->fOneShot)
            pfrom->fDisconnect = true;
s_nakamoto's avatar
s_nakamoto committed
3649
3650
3651
3652
3653
3654
3655
    }


    else if (strCommand == "inv")
    {
        vector<CInv> vInv;
        vRecv >> vInv;
3656
        if (vInv.size() > MAX_INV_SZ)
3657
        {
Pieter Wuille's avatar
Pieter Wuille committed
3658
            Misbehaving(pfrom->GetId(), 20);
3659
            return error("message inv size() = %u", vInv.size());
3660
        }
s_nakamoto's avatar
s_nakamoto committed
3661

3662
3663
        LOCK(cs_main);

Pieter Wuille's avatar
Pieter Wuille committed
3664
3665
        std::vector<CInv> vToFetch;

3666
        for (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
s_nakamoto's avatar
s_nakamoto committed
3667
        {
3668
3669
            const CInv &inv = vInv[nInv];

Gavin Andresen's avatar
Gavin Andresen committed
3670
            boost::this_thread::interruption_point();
s_nakamoto's avatar
s_nakamoto committed
3671
3672
            pfrom->AddInventoryKnown(inv);

3673
            bool fAlreadyHave = AlreadyHave(inv);
3674
            LogPrint("net", "got inv: %s  %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom->id);
s_nakamoto's avatar
s_nakamoto committed
3675

Pieter Wuille's avatar
Pieter Wuille committed
3676
3677
            if (!fAlreadyHave && !fImporting && !fReindex && inv.type != MSG_BLOCK)
                pfrom->AskFor(inv);
s_nakamoto's avatar
s_nakamoto committed
3678

Pieter Wuille's avatar
Pieter Wuille committed
3679
            if (inv.type == MSG_BLOCK) {
Pieter Wuille's avatar
Pieter Wuille committed
3680
                UpdateBlockAvailability(pfrom->GetId(), inv.hash);
Pieter Wuille's avatar
Pieter Wuille committed
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
                if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(inv.hash)) {
                    // First request the headers preceeding the announced block. In the normal fully-synced
                    // case where a new block is announced that succeeds the current tip (no reorganization),
                    // there are no such headers.
                    // Secondly, and only when we are close to being synced, we request the announced block directly,
                    // to avoid an extra round-trip. Note that we must *first* ask for the headers, so by the
                    // time the block arrives, the header chain leading up to it is already validated. Not
                    // doing this will result in the received block being rejected as an orphan in case it is
                    // not a direct successor.
                    pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash);
3691
3692
3693
                    CNodeState *nodestate = State(pfrom->GetId());
                    if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - Params().TargetSpacing() * 20 &&
                        nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
Pieter Wuille's avatar
Pieter Wuille committed
3694
3695
3696
3697
3698
                        vToFetch.push_back(inv);
                        // Mark block as in flight already, even though the actual "getdata" message only goes out
                        // later (within the same cs_main lock, though).
                        MarkBlockAsInFlight(pfrom->GetId(), inv.hash);
                    }
3699
                    LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->nHeight, inv.hash.ToString(), pfrom->id);
Pieter Wuille's avatar
Pieter Wuille committed
3700
3701
                }
            }
Pieter Wuille's avatar
Pieter Wuille committed
3702

s_nakamoto's avatar
s_nakamoto committed
3703
            // Track requests for our stuff
3704
            g_signals.Inventory(inv.hash);
3705
3706
3707
3708
3709

            if (pfrom->nSendSize > (SendBufferSize() * 2)) {
                Misbehaving(pfrom->GetId(), 50);
                return error("send buffer size() = %u", pfrom->nSendSize);
            }
s_nakamoto's avatar
s_nakamoto committed
3710
        }
Pieter Wuille's avatar
Pieter Wuille committed
3711
3712
3713

        if (!vToFetch.empty())
            pfrom->PushMessage("getdata", vToFetch);
s_nakamoto's avatar
s_nakamoto committed
3714
3715
3716
3717
3718
3719
3720
    }


    else if (strCommand == "getdata")
    {
        vector<CInv> vInv;
        vRecv >> vInv;
3721
        if (vInv.size() > MAX_INV_SZ)
3722
        {
Pieter Wuille's avatar
Pieter Wuille committed
3723
            Misbehaving(pfrom->GetId(), 20);
3724
            return error("message getdata size() = %u", vInv.size());
3725
        }
s_nakamoto's avatar
s_nakamoto committed
3726

3727
        if (fDebug || (vInv.size() != 1))
3728
            LogPrint("net", "received getdata (%u invsz) peer=%d\n", vInv.size(), pfrom->id);
3729

3730
        if ((fDebug && vInv.size() > 0) || (vInv.size() == 1))
3731
            LogPrint("net", "received getdata for: %s peer=%d\n", vInv[0].ToString(), pfrom->id);
s_nakamoto's avatar
s_nakamoto committed
3732

3733
3734
        pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end());
        ProcessGetData(pfrom);
s_nakamoto's avatar
s_nakamoto committed
3735
3736
3737
3738
3739
3740
3741
3742
3743
    }


    else if (strCommand == "getblocks")
    {
        CBlockLocator locator;
        uint256 hashStop;
        vRecv >> locator >> hashStop;

3744
3745
        LOCK(cs_main);

3746
        // Find the last block the caller has in the main chain
jtimon's avatar
jtimon committed
3747
        CBlockIndex* pindex = FindForkInGlobalIndex(chainActive, locator);
s_nakamoto's avatar
s_nakamoto committed
3748
3749
3750

        // Send the rest of the chain
        if (pindex)
3751
            pindex = chainActive.Next(pindex);
3752
        int nLimit = 500;
3753
        LogPrint("net", "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop==uint256(0) ? "end" : hashStop.ToString(), nLimit, pfrom->id);
3754
        for (; pindex; pindex = chainActive.Next(pindex))
s_nakamoto's avatar
s_nakamoto committed
3755
3756
3757
        {
            if (pindex->GetBlockHash() == hashStop)
            {
3758
                LogPrint("net", "  getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
s_nakamoto's avatar
s_nakamoto committed
3759
3760
3761
                break;
            }
            pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
3762
            if (--nLimit <= 0)
s_nakamoto's avatar
s_nakamoto committed
3763
3764
3765
            {
                // When this block is requested, we'll send an inv that'll make them
                // getblocks the next batch of inventory.
3766
                LogPrint("net", "  getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
s_nakamoto's avatar
s_nakamoto committed
3767
3768
3769
3770
3771
3772
3773
                pfrom->hashContinue = pindex->GetBlockHash();
                break;
            }
        }
    }


3774
3775
3776
3777
3778
3779
    else if (strCommand == "getheaders")
    {
        CBlockLocator locator;
        uint256 hashStop;
        vRecv >> locator >> hashStop;

3780
3781
        LOCK(cs_main);

3782
3783
3784
3785
        CBlockIndex* pindex = NULL;
        if (locator.IsNull())
        {
            // If locator is null, return the hashStop block
3786
            BlockMap::iterator mi = mapBlockIndex.find(hashStop);
3787
3788
3789
3790
3791
3792
3793
            if (mi == mapBlockIndex.end())
                return true;
            pindex = (*mi).second;
        }
        else
        {
            // Find the last block the caller has in the main chain
jtimon's avatar
jtimon committed
3794
            pindex = FindForkInGlobalIndex(chainActive, locator);
3795
            if (pindex)
3796
                pindex = chainActive.Next(pindex);
3797
3798
        }

3799
        // we must use CBlocks, as CBlockHeaders won't include the 0x00 nTx count at the end
3800
        vector<CBlock> vHeaders;
Pieter Wuille's avatar
Pieter Wuille committed
3801
        int nLimit = MAX_HEADERS_RESULTS;
3802
        LogPrint("net", "getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString(), pfrom->id);
3803
        for (; pindex; pindex = chainActive.Next(pindex))
3804
3805
3806
3807
3808
3809
3810
3811
3812
        {
            vHeaders.push_back(pindex->GetBlockHeader());
            if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
                break;
        }
        pfrom->PushMessage("headers", vHeaders);
    }


s_nakamoto's avatar
s_nakamoto committed
3813
3814
3815
    else if (strCommand == "tx")
    {
        vector<uint256> vWorkQueue;
3816
        vector<uint256> vEraseQueue;
s_nakamoto's avatar
s_nakamoto committed
3817
3818
3819
3820
3821
3822
        CTransaction tx;
        vRecv >> tx;

        CInv inv(MSG_TX, tx.GetHash());
        pfrom->AddInventoryKnown(inv);

3823
3824
        LOCK(cs_main);

s_nakamoto's avatar
s_nakamoto committed
3825
        bool fMissingInputs = false;
Pieter Wuille's avatar
Pieter Wuille committed
3826
        CValidationState state;
3827
3828
3829

        mapAlreadyAskedFor.erase(inv);

3830
        if (AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs))
s_nakamoto's avatar
s_nakamoto committed
3831
        {
3832
            mempool.check(pcoinsTip);
3833
            RelayTransaction(tx);
s_nakamoto's avatar
s_nakamoto committed
3834
            vWorkQueue.push_back(inv.hash);
3835
            vEraseQueue.push_back(inv.hash);
s_nakamoto's avatar
s_nakamoto committed
3836

3837
3838
            LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s : accepted %s (poolsz %u)\n",
                pfrom->id, pfrom->cleanSubVer,
3839
                tx.GetHash().ToString(),
3840
3841
                mempool.mapTx.size());

s_nakamoto's avatar
s_nakamoto committed
3842
            // Recursively process any orphan transactions that depended on this one
3843
            set<NodeId> setMisbehaving;
3844
            for (unsigned int i = 0; i < vWorkQueue.size(); i++)
s_nakamoto's avatar
s_nakamoto committed
3845
            {
3846
3847
3848
3849
3850
                map<uint256, set<uint256> >::iterator itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue[i]);
                if (itByPrev == mapOrphanTransactionsByPrev.end())
                    continue;
                for (set<uint256>::iterator mi = itByPrev->second.begin();
                     mi != itByPrev->second.end();
s_nakamoto's avatar
s_nakamoto committed
3851
3852
                     ++mi)
                {
3853
                    const uint256& orphanHash = *mi;
3854
3855
                    const CTransaction& orphanTx = mapOrphanTransactions[orphanHash].tx;
                    NodeId fromPeer = mapOrphanTransactions[orphanHash].fromPeer;
3856
                    bool fMissingInputs2 = false;
3857
3858
3859
                    // Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan
                    // resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get
                    // anyone relaying LegitTxX banned)
3860
                    CValidationState stateDummy;
s_nakamoto's avatar
s_nakamoto committed
3861

3862
3863
3864
3865
                    vEraseQueue.push_back(orphanHash);

                    if (setMisbehaving.count(fromPeer))
                        continue;
3866
                    if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2))
s_nakamoto's avatar
s_nakamoto committed
3867
                    {
3868
                        LogPrint("mempool", "   accepted orphan tx %s\n", orphanHash.ToString());
3869
                        RelayTransaction(orphanTx);
3870
                        vWorkQueue.push_back(orphanHash);
3871
3872
3873
                    }
                    else if (!fMissingInputs2)
                    {
3874
3875
3876
3877
3878
3879
3880
3881
3882
                        int nDos = 0;
                        if (stateDummy.IsInvalid(nDos) && nDos > 0)
                        {
                            // Punish peer that gave us an invalid orphan tx
                            Misbehaving(fromPeer, nDos);
                            setMisbehaving.insert(fromPeer);
                            LogPrint("mempool", "   invalid orphan tx %s\n", orphanHash.ToString());
                        }
                        // too-little-fee orphan
3883
                        LogPrint("mempool", "   removed orphan tx %s\n", orphanHash.ToString());
s_nakamoto's avatar
s_nakamoto committed
3884
                    }
3885
                    mempool.check(pcoinsTip);
s_nakamoto's avatar
s_nakamoto committed
3886
3887
3888
                }
            }

3889
            BOOST_FOREACH(uint256 hash, vEraseQueue)
s_nakamoto's avatar
s_nakamoto committed
3890
3891
3892
3893
                EraseOrphanTx(hash);
        }
        else if (fMissingInputs)
        {
3894
            AddOrphanTx(tx, pfrom->GetId());
3895
3896

            // DoS prevention: do not allow mapOrphanTransactions to grow unbounded
3897
3898
            unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
            unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
3899
            if (nEvicted > 0)
3900
                LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted);
Pieter Wuille's avatar
Pieter Wuille committed
3901
3902
3903
3904
3905
        } else if (pfrom->fWhitelisted) {
            // Always relay transactions received from whitelisted peers, even
            // if they are already in the mempool (allowing the node to function
            // as a gateway for nodes hidden behind it).
            RelayTransaction(tx);
s_nakamoto's avatar
s_nakamoto committed
3906
        }
3907
        int nDoS = 0;
3908
        if (state.IsInvalid(nDoS))
Philip Kaufmann's avatar
Philip Kaufmann committed
3909
        {
3910
3911
            LogPrint("mempool", "%s from peer=%d %s was not accepted into the memory pool: %s\n", tx.GetHash().ToString(),
                pfrom->id, pfrom->cleanSubVer,
3912
                state.GetRejectReason());
Gavin Andresen's avatar
Gavin Andresen committed
3913
            pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
3914
                               state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
3915
            if (nDoS > 0)
Pieter Wuille's avatar
Pieter Wuille committed
3916
                Misbehaving(pfrom->GetId(), nDoS);
Gavin Andresen's avatar
Gavin Andresen committed
3917
        }
s_nakamoto's avatar
s_nakamoto committed
3918
3919
3920
    }


Pieter Wuille's avatar
Pieter Wuille committed
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
    else if (strCommand == "headers" && !fImporting && !fReindex) // Ignore headers received while importing
    {
        std::vector<CBlockHeader> headers;

        // Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
        unsigned int nCount = ReadCompactSize(vRecv);
        if (nCount > MAX_HEADERS_RESULTS) {
            Misbehaving(pfrom->GetId(), 20);
            return error("headers message size = %u", nCount);
        }
        headers.resize(nCount);
        for (unsigned int n = 0; n < nCount; n++) {
            vRecv >> headers[n];
            ReadCompactSize(vRecv); // ignore tx count; assume it is 0.
        }

        LOCK(cs_main);

        if (nCount == 0) {
            // Nothing interesting. Stop asking this peers for more headers.
            return true;
        }

        CBlockIndex *pindexLast = NULL;
        BOOST_FOREACH(const CBlockHeader& header, headers) {
            CValidationState state;
            if (pindexLast != NULL && header.hashPrevBlock != pindexLast->GetBlockHash()) {
                Misbehaving(pfrom->GetId(), 20);
                return error("non-continuous headers sequence");
            }
            if (!AcceptBlockHeader(header, state, &pindexLast)) {
                int nDoS;
                if (state.IsInvalid(nDoS)) {
                    if (nDoS > 0)
                        Misbehaving(pfrom->GetId(), nDoS);
                    return error("invalid header received");
                }
            }
        }

        if (pindexLast)
            UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash());

        if (nCount == MAX_HEADERS_RESULTS && pindexLast) {
            // Headers message had its maximum size; the peer may have more headers.
            // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue
            // from there instead.
3968
            LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight);
Pieter Wuille's avatar
Pieter Wuille committed
3969
3970
3971
3972
            pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256(0));
        }
    }

3973
    else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing
s_nakamoto's avatar
s_nakamoto committed
3974
    {
3975
3976
        CBlock block;
        vRecv >> block;
s_nakamoto's avatar
s_nakamoto committed
3977

3978
        CInv inv(MSG_BLOCK, block.GetHash());
Pieter Wuille's avatar
Pieter Wuille committed
3979
        LogPrint("net", "received block %s peer=%d\n", inv.hash.ToString(), pfrom->id);
s_nakamoto's avatar
s_nakamoto committed
3980

Pieter Wuille's avatar
Pieter Wuille committed
3981
        pfrom->AddInventoryKnown(inv);
3982

Pieter Wuille's avatar
Pieter Wuille committed
3983
        CValidationState state;
3984
        ProcessNewBlock(state, pfrom, &block);
3985
3986
3987
        int nDoS;
        if (state.IsInvalid(nDoS)) {
            pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
3988
                               state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
3989
3990
3991
3992
3993
3994
            if (nDoS > 0) {
                LOCK(cs_main);
                Misbehaving(pfrom->GetId(), nDoS);
            }
        }

s_nakamoto's avatar
s_nakamoto committed
3995
3996
3997
    }


3998
3999
4000
4001
4002
4003
    // This asymmetric behavior for inbound and outbound connections was introduced
    // to prevent a fingerprinting attack: an attacker can send specific fake addresses
    // to users' AddrMan and later request them by sending getaddr messages. 
    // Making users (which are behind NAT and can only make outgoing connections) ignore 
    // getaddr message mitigates the attack.
    else if ((strCommand == "getaddr") && (pfrom->fInbound))
s_nakamoto's avatar
s_nakamoto committed
4004
4005
    {
        pfrom->vAddrToSend.clear();
4006
4007
4008
        vector<CAddress> vAddr = addrman.GetAddr();
        BOOST_FOREACH(const CAddress &addr, vAddr)
            pfrom->PushAddress(addr);
s_nakamoto's avatar
s_nakamoto committed
4009
4010
4011
    }


4012
4013
    else if (strCommand == "mempool")
    {
4014
        LOCK2(cs_main, pfrom->cs_filter);
4015

4016
4017
4018
        std::vector<uint256> vtxid;
        mempool.queryHashes(vtxid);
        vector<CInv> vInv;
Matt Corallo's avatar
Matt Corallo committed
4019
4020
        BOOST_FOREACH(uint256& hash, vtxid) {
            CInv inv(MSG_TX, hash);
4021
4022
4023
            CTransaction tx;
            bool fInMemPool = mempool.lookup(hash, tx);
            if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
4024
            if ((pfrom->pfilter && pfrom->pfilter->IsRelevantAndUpdate(tx)) ||
Matt Corallo's avatar
Matt Corallo committed
4025
4026
               (!pfrom->pfilter))
                vInv.push_back(inv);
4027
4028
4029
4030
            if (vInv.size() == MAX_INV_SZ) {
                pfrom->PushMessage("inv", vInv);
                vInv.clear();
            }
4031
4032
4033
4034
4035
4036
        }
        if (vInv.size() > 0)
            pfrom->PushMessage("inv", vInv);
    }


s_nakamoto's avatar
s_nakamoto committed
4037
4038
    else if (strCommand == "ping")
    {
Jeff Garzik's avatar
Jeff Garzik committed
4039
4040
        if (pfrom->nVersion > BIP0031_VERSION)
        {
4041
            uint64_t nonce = 0;
Jeff Garzik's avatar
Jeff Garzik committed
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
            vRecv >> nonce;
            // Echo the message back with the nonce. This allows for two useful features:
            //
            // 1) A remote node can quickly check if the connection is operational
            // 2) Remote nodes can measure the latency of the network thread. If this node
            //    is overloaded it won't respond to pings quickly and the remote node can
            //    avoid sending us more work, like chain download requests.
            //
            // The nonce stops the remote getting confused between different pings: without
            // it, if the remote node sends a ping once per second and this node takes 5
            // seconds to respond to each, the 5th ping the remote sends would appear to
            // return very quickly.
            pfrom->PushMessage("pong", nonce);
        }
s_nakamoto's avatar
s_nakamoto committed
4056
4057
4058
    }


Josh Lehan's avatar
Josh Lehan committed
4059
4060
    else if (strCommand == "pong")
    {
4061
        int64_t pingUsecEnd = nTimeReceived;
4062
        uint64_t nonce = 0;
Josh Lehan's avatar
Josh Lehan committed
4063
4064
4065
        size_t nAvail = vRecv.in_avail();
        bool bPingFinished = false;
        std::string sProblem;
4066

Josh Lehan's avatar
Josh Lehan committed
4067
4068
        if (nAvail >= sizeof(nonce)) {
            vRecv >> nonce;
4069

Josh Lehan's avatar
Josh Lehan committed
4070
4071
4072
4073
4074
            // Only process pong message if there is an outstanding ping (old ping without nonce should never pong)
            if (pfrom->nPingNonceSent != 0) {
                if (nonce == pfrom->nPingNonceSent) {
                    // Matching pong received, this ping is no longer outstanding
                    bPingFinished = true;
4075
                    int64_t pingUsecTime = pingUsecEnd - pfrom->nPingUsecStart;
Josh Lehan's avatar
Josh Lehan committed
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
                    if (pingUsecTime > 0) {
                        // Successful ping time measurement, replace previous
                        pfrom->nPingUsecTime = pingUsecTime;
                    } else {
                        // This should never happen
                        sProblem = "Timing mishap";
                    }
                } else {
                    // Nonce mismatches are normal when pings are overlapping
                    sProblem = "Nonce mismatch";
                    if (nonce == 0) {
                        // This is most likely a bug in another implementation somewhere, cancel this ping
                        bPingFinished = true;
                        sProblem = "Nonce zero";
                    }
                }
            } else {
                sProblem = "Unsolicited pong without ping";
            }
        } else {
            // This is most likely a bug in another implementation somewhere, cancel this ping
            bPingFinished = true;
            sProblem = "Short payload";
        }
4100

Josh Lehan's avatar
Josh Lehan committed
4101
        if (!(sProblem.empty())) {
4102
4103
            LogPrint("net", "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n",
                pfrom->id,
4104
4105
                pfrom->cleanSubVer,
                sProblem,
4106
4107
4108
                pfrom->nPingNonceSent,
                nonce,
                nAvail);
Josh Lehan's avatar
Josh Lehan committed
4109
4110
4111
4112
4113
        }
        if (bPingFinished) {
            pfrom->nPingNonceSent = 0;
        }
    }
4114
4115


s_nakamoto's avatar
s_nakamoto committed
4116
4117
4118
4119
4120
    else if (strCommand == "alert")
    {
        CAlert alert;
        vRecv >> alert;

Gavin Andresen's avatar
Gavin Andresen committed
4121
4122
        uint256 alertHash = alert.GetHash();
        if (pfrom->setKnown.count(alertHash) == 0)
s_nakamoto's avatar
s_nakamoto committed
4123
        {
Gavin Andresen's avatar
Gavin Andresen committed
4124
            if (alert.ProcessAlert())
4125
            {
Gavin Andresen's avatar
Gavin Andresen committed
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
                // Relay
                pfrom->setKnown.insert(alertHash);
                {
                    LOCK(cs_vNodes);
                    BOOST_FOREACH(CNode* pnode, vNodes)
                        alert.RelayTo(pnode);
                }
            }
            else {
                // Small DoS penalty so peers that send us lots of
                // duplicate/expired/invalid-signature/whatever alerts
                // eventually get banned.
                // This isn't a Misbehaving(100) (immediate ban) because the
                // peer might be an older or different implementation with
                // a different signature key, etc.
Pieter Wuille's avatar
Pieter Wuille committed
4141
                Misbehaving(pfrom->GetId(), 10);
4142
            }
s_nakamoto's avatar
s_nakamoto committed
4143
4144
4145
4146
        }
    }


4147
4148
4149
4150
4151
4152
4153
    else if (strCommand == "filterload")
    {
        CBloomFilter filter;
        vRecv >> filter;

        if (!filter.IsWithinSizeConstraints())
            // There is no excuse for sending a too-large filter
Pieter Wuille's avatar
Pieter Wuille committed
4154
            Misbehaving(pfrom->GetId(), 100);
4155
4156
4157
4158
4159
        else
        {
            LOCK(pfrom->cs_filter);
            delete pfrom->pfilter;
            pfrom->pfilter = new CBloomFilter(filter);
4160
            pfrom->pfilter->UpdateEmptyFull();
4161
        }
4162
        pfrom->fRelayTxes = true;
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
    }


    else if (strCommand == "filteradd")
    {
        vector<unsigned char> vData;
        vRecv >> vData;

        // Nodes must NEVER send a data item > 520 bytes (the max size for a script data object,
        // and thus, the maximum size any matched object can have) in a filteradd message
4173
        if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE)
4174
        {
Pieter Wuille's avatar
Pieter Wuille committed
4175
            Misbehaving(pfrom->GetId(), 100);
4176
4177
4178
4179
4180
        } else {
            LOCK(pfrom->cs_filter);
            if (pfrom->pfilter)
                pfrom->pfilter->insert(vData);
            else
Pieter Wuille's avatar
Pieter Wuille committed
4181
                Misbehaving(pfrom->GetId(), 100);
4182
4183
4184
4185
4186
4187
4188
4189
        }
    }


    else if (strCommand == "filterclear")
    {
        LOCK(pfrom->cs_filter);
        delete pfrom->pfilter;
4190
        pfrom->pfilter = new CBloomFilter();
4191
        pfrom->fRelayTxes = true;
4192
4193
4194
    }


Gavin Andresen's avatar
Gavin Andresen committed
4195
4196
    else if (strCommand == "reject")
    {
4197
4198
4199
        if (fDebug) {
            try {
                string strMsg; unsigned char ccode; string strReason;
4200
                vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, MAX_REJECT_MESSAGE_LENGTH);
Gavin Andresen's avatar
Gavin Andresen committed
4201

4202
4203
                ostringstream ss;
                ss << strMsg << " code " << itostr(ccode) << ": " << strReason;
Gavin Andresen's avatar
Gavin Andresen committed
4204

4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
                if (strMsg == "block" || strMsg == "tx")
                {
                    uint256 hash;
                    vRecv >> hash;
                    ss << ": hash " << hash.ToString();
                }
                LogPrint("net", "Reject %s\n", SanitizeString(ss.str()));
            } catch (std::ios_base::failure& e) {
                // Avoid feedback loops by preventing reject messages from triggering a new reject message.
                LogPrint("net", "Unparseable reject message received\n");
Gavin Andresen's avatar
Gavin Andresen committed
4215
4216
4217
4218
            }
        }
    }

s_nakamoto's avatar
s_nakamoto committed
4219
4220
4221
    else
    {
        // Ignore unknown commands for extensibility
4222
        LogPrint("net", "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->id);
s_nakamoto's avatar
s_nakamoto committed
4223
4224
4225
4226
4227
4228
4229
    }



    return true;
}

4230
// requires LOCK(cs_vRecvMsg)
4231
4232
4233
bool ProcessMessages(CNode* pfrom)
{
    //if (fDebug)
4234
    //    LogPrintf("ProcessMessages(%u messages)\n", pfrom->vRecvMsg.size());
s_nakamoto's avatar
s_nakamoto committed
4235

4236
4237
4238
4239
4240
4241
4242
4243
    //
    // Message format
    //  (4) message start
    //  (12) command
    //  (4) size
    //  (4) checksum
    //  (x) data
    //
4244
    bool fOk = true;
s_nakamoto's avatar
s_nakamoto committed
4245

4246
4247
    if (!pfrom->vRecvGetData.empty())
        ProcessGetData(pfrom);
4248

4249
4250
    // this maintains the order of responses
    if (!pfrom->vRecvGetData.empty()) return fOk;
4251

4252
    std::deque<CNetMessage>::iterator it = pfrom->vRecvMsg.begin();
4253
    while (!pfrom->fDisconnect && it != pfrom->vRecvMsg.end()) {
4254
        // Don't bother if send buffer is too full to respond anyway
4255
        if (pfrom->nSendSize >= SendBufferSize())
4256
4257
            break;

4258
4259
        // get next message
        CNetMessage& msg = *it;
4260
4261

        //if (fDebug)
4262
        //    LogPrintf("ProcessMessages(message %u msgsz, %u bytes, complete:%s)\n",
4263
4264
4265
        //            msg.hdr.nMessageSize, msg.vRecv.size(),
        //            msg.complete() ? "Y" : "N");

4266
        // end, if an incomplete message is found
4267
        if (!msg.complete())
4268
            break;
4269

4270
4271
4272
        // at this point, any failure means we can delete the current message
        it++;

4273
        // Scan for message start
4274
        if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
4275
            LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id);
4276
4277
            fOk = false;
            break;
4278
        }
s_nakamoto's avatar
s_nakamoto committed
4279

4280
        // Read header
4281
        CMessageHeader& hdr = msg.hdr;
4282
4283
        if (!hdr.IsValid())
        {
4284
            LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id);
4285
4286
4287
4288
4289
4290
4291
4292
            continue;
        }
        string strCommand = hdr.GetCommand();

        // Message size
        unsigned int nMessageSize = hdr.nMessageSize;

        // Checksum
4293
        CDataStream& vRecv = msg.vRecv;
Pieter Wuille's avatar
Pieter Wuille committed
4294
4295
4296
4297
        uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
        unsigned int nChecksum = 0;
        memcpy(&nChecksum, &hash, sizeof(nChecksum));
        if (nChecksum != hdr.nChecksum)
4298
        {
4299
4300
            LogPrintf("ProcessMessages(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
               SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum);
Pieter Wuille's avatar
Pieter Wuille committed
4301
            continue;
4302
4303
4304
4305
4306
4307
        }

        // Process message
        bool fRet = false;
        try
        {
4308
            fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime);
Gavin Andresen's avatar
Gavin Andresen committed
4309
            boost::this_thread::interruption_point();
4310
4311
4312
        }
        catch (std::ios_base::failure& e)
        {
Gavin Andresen's avatar
Gavin Andresen committed
4313
            pfrom->PushMessage("reject", strCommand, REJECT_MALFORMED, string("error parsing message"));
4314
4315
            if (strstr(e.what(), "end of data"))
            {
4316
                // Allow exceptions from under-length message on vRecv
4317
                LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", SanitizeString(strCommand), nMessageSize, e.what());
4318
4319
4320
            }
            else if (strstr(e.what(), "size too large"))
            {
4321
                // Allow exceptions from over-long size
4322
                LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught\n", SanitizeString(strCommand), nMessageSize, e.what());
4323
4324
4325
            }
            else
            {
4326
                PrintExceptionContinue(&e, "ProcessMessages()");
4327
4328
            }
        }
Gavin Andresen's avatar
Gavin Andresen committed
4329
4330
4331
        catch (boost::thread_interrupted) {
            throw;
        }
4332
        catch (std::exception& e) {
4333
            PrintExceptionContinue(&e, "ProcessMessages()");
4334
        } catch (...) {
4335
            PrintExceptionContinue(NULL, "ProcessMessages()");
4336
4337
4338
        }

        if (!fRet)
4339
            LogPrintf("ProcessMessage(%s, %u bytes) FAILED peer=%d\n", SanitizeString(strCommand), nMessageSize, pfrom->id);
4340

4341
        break;
4342
4343
    }

4344
4345
4346
4347
    // In case the connection got shut down, its receive buffer was wiped
    if (!pfrom->fDisconnect)
        pfrom->vRecvMsg.erase(pfrom->vRecvMsg.begin(), it);

4348
    return fOk;
4349
}
s_nakamoto's avatar
s_nakamoto committed
4350
4351
4352
4353


bool SendMessages(CNode* pto, bool fSendTrickle)
{
4354
    {
s_nakamoto's avatar
s_nakamoto committed
4355
4356
4357
4358
        // Don't send anything until we get their version message
        if (pto->nVersion == 0)
            return true;

Josh Lehan's avatar
Josh Lehan committed
4359
4360
4361
4362
4363
4364
4365
4366
        //
        // Message: ping
        //
        bool pingSend = false;
        if (pto->fPingQueued) {
            // RPC ping request by user
            pingSend = true;
        }
4367
4368
        if (pto->nPingNonceSent == 0 && pto->nPingUsecStart + PING_INTERVAL * 1000000 < GetTimeMicros()) {
            // Ping automatically sent as a latency probe & keepalive.
Josh Lehan's avatar
Josh Lehan committed
4369
4370
4371
            pingSend = true;
        }
        if (pingSend) {
4372
            uint64_t nonce = 0;
Josh Lehan's avatar
Josh Lehan committed
4373
            while (nonce == 0) {
4374
                GetRandBytes((unsigned char*)&nonce, sizeof(nonce));
Josh Lehan's avatar
Josh Lehan committed
4375
4376
            }
            pto->fPingQueued = false;
4377
            pto->nPingUsecStart = GetTimeMicros();
Josh Lehan's avatar
Josh Lehan committed
4378
            if (pto->nVersion > BIP0031_VERSION) {
4379
                pto->nPingNonceSent = nonce;
Pieter Wuille's avatar
Pieter Wuille committed
4380
                pto->PushMessage("ping", nonce);
Josh Lehan's avatar
Josh Lehan committed
4381
            } else {
4382
4383
                // Peer is too old to support ping command with nonce, pong will never arrive.
                pto->nPingNonceSent = 0;
Jeff Garzik's avatar
Jeff Garzik committed
4384
                pto->PushMessage("ping");
Josh Lehan's avatar
Josh Lehan committed
4385
            }
Jeff Garzik's avatar
Jeff Garzik committed
4386
        }
s_nakamoto's avatar
s_nakamoto committed
4387

4388
4389
4390
4391
        TRY_LOCK(cs_main, lockMain); // Acquire cs_main for IsInitialBlockDownload() and CNodeState()
        if (!lockMain)
            return true;

s_nakamoto's avatar
s_nakamoto committed
4392
        // Address refresh broadcast
4393
        static int64_t nLastRebroadcast;
4394
        if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
s_nakamoto's avatar
s_nakamoto committed
4395
        {
4396
4397
            LOCK(cs_vNodes);
            BOOST_FOREACH(CNode* pnode, vNodes)
s_nakamoto's avatar
s_nakamoto committed
4398
            {
4399
4400
4401
                // Periodically clear setAddrKnown to allow refresh broadcasts
                if (nLastRebroadcast)
                    pnode->setAddrKnown.clear();
s_nakamoto's avatar
s_nakamoto committed
4402

4403
4404
                // Rebroadcast our address
                AdvertizeLocal(pnode);
s_nakamoto's avatar
s_nakamoto committed
4405
            }
4406
4407
            if (!vNodes.empty())
                nLastRebroadcast = GetTime();
s_nakamoto's avatar
s_nakamoto committed
4408
4409
4410
4411
4412
4413
4414
4415
4416
        }

        //
        // Message: addr
        //
        if (fSendTrickle)
        {
            vector<CAddress> vAddr;
            vAddr.reserve(pto->vAddrToSend.size());
4417
            BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend)
s_nakamoto's avatar
s_nakamoto committed
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
            {
                // returns true if wasn't already contained in the set
                if (pto->setAddrKnown.insert(addr).second)
                {
                    vAddr.push_back(addr);
                    // receiver rejects addr messages larger than 1000
                    if (vAddr.size() >= 1000)
                    {
                        pto->PushMessage("addr", vAddr);
                        vAddr.clear();
                    }
                }
            }
            pto->vAddrToSend.clear();
            if (!vAddr.empty())
                pto->PushMessage("addr", vAddr);
        }

4436
4437
        CNodeState &state = *State(pto->GetId());
        if (state.fShouldBan) {
Pieter Wuille's avatar
Pieter Wuille committed
4438
4439
            if (pto->fWhitelisted)
                LogPrintf("Warning: not punishing whitelisted peer %s!\n", pto->addr.ToString());
Pieter Wuille's avatar
Pieter Wuille committed
4440
4441
            else {
                pto->fDisconnect = true;
Pieter Wuille's avatar
Pieter Wuille committed
4442
4443
4444
                if (pto->addr.IsLocal())
                    LogPrintf("Warning: not banning local peer %s!\n", pto->addr.ToString());
                else
4445
                {
Pieter Wuille's avatar
Pieter Wuille committed
4446
                    CNode::Ban(pto->addr);
4447
                }
Pieter Wuille's avatar
Pieter Wuille committed
4448
            }
4449
            state.fShouldBan = false;
Pieter Wuille's avatar
Pieter Wuille committed
4450
4451
        }

4452
4453
4454
4455
        BOOST_FOREACH(const CBlockReject& reject, state.rejects)
            pto->PushMessage("reject", (string)"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock);
        state.rejects.clear();

4456
        // Start block sync
Pieter Wuille's avatar
Pieter Wuille committed
4457
4458
        if (pindexBestHeader == NULL)
            pindexBestHeader = chainActive.Tip();
4459
        bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->fOneShot); // Download if this is a nice peer, or we have no nice peers and this one might do.
Pieter Wuille's avatar
Pieter Wuille committed
4460
4461
4462
4463
4464
4465
        if (!state.fSyncStarted && !pto->fClient && fFetch && !fImporting && !fReindex) {
            // Only actively request headers from a single peer, unless we're close to today.
            if (nSyncStarted == 0 || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) {
                state.fSyncStarted = true;
                nSyncStarted++;
                CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader;
4466
                LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight);
Pieter Wuille's avatar
Pieter Wuille committed
4467
4468
                pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256(0));
            }
4469
4470
4471
4472
4473
4474
4475
        }

        // Resend wallet transactions that haven't gotten in a block yet
        // Except during reindex, importing and IBD, when old wallet
        // transactions become unconfirmed and spams other nodes.
        if (!fReindex && !fImporting && !IsInitialBlockDownload())
        {
4476
            g_signals.Broadcast();
4477
        }
s_nakamoto's avatar
s_nakamoto committed
4478
4479
4480
4481
4482
4483
4484

        //
        // Message: inventory
        //
        vector<CInv> vInv;
        vector<CInv> vInvWait;
        {
4485
            LOCK(pto->cs_inventory);
s_nakamoto's avatar
s_nakamoto committed
4486
4487
            vInv.reserve(pto->vInventoryToSend.size());
            vInvWait.reserve(pto->vInventoryToSend.size());
4488
            BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
s_nakamoto's avatar
s_nakamoto committed
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
            {
                if (pto->setInventoryKnown.count(inv))
                    continue;

                // trickle out tx inv to protect privacy
                if (inv.type == MSG_TX && !fSendTrickle)
                {
                    // 1/4 of tx invs blast to all immediately
                    static uint256 hashSalt;
                    if (hashSalt == 0)
4499
                        hashSalt = GetRandHash();
s_nakamoto's avatar
s_nakamoto committed
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
                    uint256 hashRand = inv.hash ^ hashSalt;
                    hashRand = Hash(BEGIN(hashRand), END(hashRand));
                    bool fTrickleWait = ((hashRand & 3) != 0);

                    if (fTrickleWait)
                    {
                        vInvWait.push_back(inv);
                        continue;
                    }
                }

                // returns true if wasn't already contained in the set
                if (pto->setInventoryKnown.insert(inv).second)
                {
                    vInv.push_back(inv);
                    if (vInv.size() >= 1000)
                    {
                        pto->PushMessage("inv", vInv);
                        vInv.clear();
                    }
                }
            }
            pto->vInventoryToSend = vInvWait;
        }
        if (!vInv.empty())
            pto->PushMessage("inv", vInv);

Pieter Wuille's avatar
Pieter Wuille committed
4527
        // Detect whether we're stalling
4528
        int64_t nNow = GetTimeMicros();
Pieter Wuille's avatar
Pieter Wuille committed
4529
4530
4531
4532
4533
        if (!pto->fDisconnect && state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
            // Stalling only triggers when the block download window cannot move. During normal steady state,
            // the download window should be much larger than the to-be-downloaded set of blocks, so disconnection
            // should only happen during initial block download.
            LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id);
4534
4535
            pto->fDisconnect = true;
        }
4536
        // In case there is a block that has been in flight from this peer for (2 + 0.5 * N) times the block interval
4537
4538
4539
4540
        // (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to
        // timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link
        // being saturated. We only count validated in-flight blocks so peers can't advertize nonexisting block hashes
        // to unreasonably increase our timeout.
4541
        if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0 && state.vBlocksInFlight.front().nTime < nNow - 500000 * Params().TargetSpacing() * (4 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) {
4542
4543
4544
            LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", state.vBlocksInFlight.front().hash.ToString(), pto->id);
            pto->fDisconnect = true;
        }
4545

s_nakamoto's avatar
s_nakamoto committed
4546
        //
4547
        // Message: getdata (blocks)
s_nakamoto's avatar
s_nakamoto committed
4548
4549
        //
        vector<CInv> vGetData;
Pieter Wuille's avatar
Pieter Wuille committed
4550
4551
4552
4553
4554
4555
4556
        if (!pto->fDisconnect && !pto->fClient && fFetch && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
            vector<CBlockIndex*> vToDownload;
            NodeId staller = -1;
            FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller);
            BOOST_FOREACH(CBlockIndex *pindex, vToDownload) {
                vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash()));
                MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), pindex);
4557
4558
                LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(),
                    pindex->nHeight, pto->id);
Pieter Wuille's avatar
Pieter Wuille committed
4559
4560
            }
            if (state.nBlocksInFlight == 0 && staller != -1) {
R E Broadley's avatar
R E Broadley committed
4561
                if (State(staller)->nStallingSince == 0) {
Pieter Wuille's avatar
Pieter Wuille committed
4562
                    State(staller)->nStallingSince = nNow;
R E Broadley's avatar
R E Broadley committed
4563
4564
                    LogPrint("net", "Stall started peer=%d\n", staller);
                }
4565
4566
4567
4568
4569
4570
4571
            }
        }

        //
        // Message: getdata (non-blocks)
        //
        while (!pto->fDisconnect && !pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
s_nakamoto's avatar
s_nakamoto committed
4572
4573
        {
            const CInv& inv = (*pto->mapAskFor.begin()).second;
4574
            if (!AlreadyHave(inv))
s_nakamoto's avatar
s_nakamoto committed
4575
            {
4576
                if (fDebug)
4577
                    LogPrint("net", "Requesting %s peer=%d\n", inv.ToString(), pto->id);
s_nakamoto's avatar
s_nakamoto committed
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
                vGetData.push_back(inv);
                if (vGetData.size() >= 1000)
                {
                    pto->PushMessage("getdata", vGetData);
                    vGetData.clear();
                }
            }
            pto->mapAskFor.erase(pto->mapAskFor.begin());
        }
        if (!vGetData.empty())
            pto->PushMessage("getdata", vGetData);

    }
    return true;
}


4595
4596
4597
bool CBlockUndo::WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock)
{
    // Open history file to append
4598
    CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
4599
    if (fileout.IsNull())
4600
4601
4602
4603
4604
4605
4606
        return error("CBlockUndo::WriteToDisk : OpenUndoFile failed");

    // Write index header
    unsigned int nSize = fileout.GetSerializeSize(*this);
    fileout << FLATDATA(Params().MessageStart()) << nSize;

    // Write undo data
4607
    long fileOutPos = ftell(fileout.Get());
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
    if (fileOutPos < 0)
        return error("CBlockUndo::WriteToDisk : ftell failed");
    pos.nPos = (unsigned int)fileOutPos;
    fileout << *this;

    // calculate & write checksum
    CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
    hasher << hashBlock;
    hasher << *this;
    fileout << hasher.GetHash();

    return true;
}

bool CBlockUndo::ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock)
{
    // Open history file to read
4625
    CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
4626
    if (filein.IsNull())
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
        return error("CBlockUndo::ReadFromDisk : OpenBlockFile failed");

    // Read block
    uint256 hashChecksum;
    try {
        filein >> *this;
        filein >> hashChecksum;
    }
    catch (std::exception &e) {
        return error("%s : Deserialize or I/O error - %s", __func__, e.what());
    }

    // Verify checksum
    CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
    hasher << hashBlock;
    hasher << *this;
    if (hashChecksum != hasher.GetHash())
        return error("CBlockUndo::ReadFromDisk : Checksum mismatch");

    return true;
}
s_nakamoto's avatar
s_nakamoto committed
4648

4649
 std::string CBlockFileInfo::ToString() const {
4650
     return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, DateTimeStrFormat("%Y-%m-%d", nTimeFirst), DateTimeStrFormat("%Y-%m-%d", nTimeLast));
4651
 }
s_nakamoto's avatar
s_nakamoto committed
4652
4653
4654



4655
4656
4657
4658
4659
4660
class CMainCleanup
{
public:
    CMainCleanup() {}
    ~CMainCleanup() {
        // block headers
4661
        BlockMap::iterator it1 = mapBlockIndex.begin();
4662
4663
4664
4665
4666
4667
        for (; it1 != mapBlockIndex.end(); it1++)
            delete (*it1).second;
        mapBlockIndex.clear();

        // orphan transactions
        mapOrphanTransactions.clear();
4668
        mapOrphanTransactionsByPrev.clear();
4669
4670
    }
} instance_of_cmaincleanup;