main.cpp 175 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
s_nakamoto's avatar
s_nakamoto committed
3
// Distributed under the MIT/X11 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 "net.h"
15
#include "pow.h"
16
17
#include "txdb.h"
#include "txmempool.h"
Pieter Wuille's avatar
Pieter Wuille committed
18
#include "ui_interface.h"
19
#include "util.h"
20
#include "utilmoneystr.h"
21

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

#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
27
#include <boost/thread.hpp>
s_nakamoto's avatar
s_nakamoto committed
28

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

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

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

CCriticalSection cs_main;

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

55

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

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

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

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

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

74
75
// Internal stuff
namespace {
76

R E Broadley's avatar
R E Broadley committed
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
    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;
99
100
101

    // 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.
102
    set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
Pieter Wuille's avatar
Pieter Wuille committed
103
104
105
106
    // Number of nodes with fSyncStarted.
    int nSyncStarted = 0;
    // All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions.
    multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked;
R E Broadley's avatar
R E Broadley committed
107
108

    CCriticalSection cs_LastBlockFile;
109
    std::vector<CBlockFileInfo> vinfoBlockFile;
R E Broadley's avatar
R E Broadley committed
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
    int nLastBlockFile = 0;

    // Every received block is assigned a unique and increasing identifier, so we
    // know which one to give priority in case of a fork.
    CCriticalSection cs_nBlockSequenceId;
    // Blocks loaded from disk are assigned id 0, so start the counter at 1.
    uint32_t nBlockSequenceId = 1;

    // Sources of received blocks, to be able to send them reject messages or ban
    // them, if processing happens afterwards. Protected by cs_main.
    map<uint256, NodeId> mapBlockSource;

    // Blocks that are in flight, and that are in the queue to be downloaded.
    // Protected by cs_main.
    struct QueuedBlock {
        uint256 hash;
Pieter Wuille's avatar
Pieter Wuille committed
126
        CBlockIndex *pindex;  // Optional.
R E Broadley's avatar
R E Broadley committed
127
128
129
        int64_t nTime;  // Time of "getdata" request in microseconds.
    };
    map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;
130
131

} // anon namespace
s_nakamoto's avatar
s_nakamoto committed
132

Pieter Wuille's avatar
Pieter Wuille committed
133
134
135
136
137
//////////////////////////////////////////////////////////////////////////////
//
// dispatching functions
//

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

140
namespace {
141

142
struct CMainSignals {
143
144
    // Notifies listeners of updated transaction data (transaction, and optionally the block it is found in.
    boost::signals2::signal<void (const CTransaction &, const CBlock *)> SyncTransaction;
145
146
147
148
149
150
151
152
153
154
155
    // Notifies listeners of an erased transaction (currently disabled, requires transaction replacement).
    boost::signals2::signal<void (const uint256 &)> EraseTransaction;
    // Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible).
    boost::signals2::signal<void (const uint256 &)> UpdatedTransaction;
    // Notifies listeners of a new active block chain.
    boost::signals2::signal<void (const CBlockLocator &)> SetBestChain;
    // Notifies listeners about an inventory item being seen on the network.
    boost::signals2::signal<void (const uint256 &)> Inventory;
    // Tells listeners to broadcast their data.
    boost::signals2::signal<void ()> Broadcast;
} g_signals;
156
157

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

159
160
161
162
163
164
165
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));
Pieter Wuille's avatar
Pieter Wuille committed
166
167
}

168
169
170
171
172
173
174
void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
    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
175
176
}

177
void UnregisterAllValidationInterfaces() {
178
179
180
181
182
183
    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
184
185
}

186
187
void SyncWithWallets(const CTransaction &tx, const CBlock *pblock) {
    g_signals.SyncTransaction(tx, pblock);
Pieter Wuille's avatar
Pieter Wuille committed
188
189
}

190
191
192
193
194
//////////////////////////////////////////////////////////////////////////////
//
// Registration of network node signals.
//

Pieter Wuille's avatar
Pieter Wuille committed
195
namespace {
196
197
198
199
200
201
202

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

Pieter Wuille's avatar
Pieter Wuille committed
203
204
205
206
207
// 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.
struct CNodeState {
208
    // Accumulated misbehaviour score for this peer.
Pieter Wuille's avatar
Pieter Wuille committed
209
    int nMisbehavior;
Pieter Wuille's avatar
Pieter Wuille committed
210
    // Whether this peer should be disconnected and banned (unless whitelisted).
Pieter Wuille's avatar
Pieter Wuille committed
211
    bool fShouldBan;
212
    // String name of this peer (debugging/logging purposes).
Pieter Wuille's avatar
Pieter Wuille committed
213
    std::string name;
214
215
    // List of asynchronously-determined block rejections to notify this peer about.
    std::vector<CBlockReject> rejects;
Pieter Wuille's avatar
Pieter Wuille committed
216
217
218
219
    // The best known block we know this peer has announced.
    CBlockIndex *pindexBestKnownBlock;
    // The hash of the last unknown block this peer has announced.
    uint256 hashLastUnknownBlock;
Pieter Wuille's avatar
Pieter Wuille committed
220
221
222
223
224
225
    // The last full block we both have.
    CBlockIndex *pindexLastCommonBlock;
    // Whether we've started headers synchronization with this peer.
    bool fSyncStarted;
    // Since when we're stalling block download progress (in microseconds), or 0.
    int64_t nStallingSince;
226
227
    list<QueuedBlock> vBlocksInFlight;
    int nBlocksInFlight;
Pieter Wuille's avatar
Pieter Wuille committed
228
229
230
231

    CNodeState() {
        nMisbehavior = 0;
        fShouldBan = false;
Pieter Wuille's avatar
Pieter Wuille committed
232
233
        pindexBestKnownBlock = NULL;
        hashLastUnknownBlock = uint256(0);
Pieter Wuille's avatar
Pieter Wuille committed
234
235
236
        pindexLastCommonBlock = NULL;
        fSyncStarted = false;
        nStallingSince = 0;
237
        nBlocksInFlight = 0;
Pieter Wuille's avatar
Pieter Wuille committed
238
239
240
    }
};

241
// Map maintaining per-node state. Requires cs_main.
Pieter Wuille's avatar
Pieter Wuille committed
242
243
244
245
246
247
248
249
250
251
252
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()
253
254
255
256
257
{
    LOCK(cs_main);
    return chainActive.Height();
}

Pieter Wuille's avatar
Pieter Wuille committed
258
259
260
261
262
263
264
265
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;
}

void FinalizeNode(NodeId nodeid) {
    LOCK(cs_main);
266
267
    CNodeState *state = State(nodeid);

Pieter Wuille's avatar
Pieter Wuille committed
268
269
270
    if (state->fSyncStarted)
        nSyncStarted--;

271
272
    BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight)
        mapBlocksInFlight.erase(entry.hash);
273
    EraseOrphansFor(nodeid);
274

Pieter Wuille's avatar
Pieter Wuille committed
275
276
    mapNodeState.erase(nodeid);
}
277
278

// Requires cs_main.
Pieter Wuille's avatar
Pieter Wuille committed
279
void MarkBlockAsReceived(const uint256& hash) {
280
281
282
283
284
    map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
    if (itInFlight != mapBlocksInFlight.end()) {
        CNodeState *state = State(itInFlight->second.first);
        state->vBlocksInFlight.erase(itInFlight->second.second);
        state->nBlocksInFlight--;
Pieter Wuille's avatar
Pieter Wuille committed
285
        state->nStallingSince = 0;
286
287
288
289
290
        mapBlocksInFlight.erase(itInFlight);
    }
}

// Requires cs_main.
Pieter Wuille's avatar
Pieter Wuille committed
291
void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, CBlockIndex *pindex = NULL) {
292
293
294
295
296
297
    CNodeState *state = State(nodeid);
    assert(state != NULL);

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

Pieter Wuille's avatar
Pieter Wuille committed
298
    QueuedBlock newentry = {hash, pindex, GetTimeMicros()};
299
300
301
302
303
    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
304
305
306
307
308
309
/** 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) {
310
        BlockMap::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock);
Pieter Wuille's avatar
Pieter Wuille committed
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
        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);

326
    BlockMap::iterator it = mapBlockIndex.find(hash);
Pieter Wuille's avatar
Pieter Wuille committed
327
328
329
330
331
332
333
334
335
336
    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
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
/** 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
388
389
390
391
392
    // 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
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
    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) {
            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
415
                if (pindex->nHeight > nWindowEnd) {
Pieter Wuille's avatar
Pieter Wuille committed
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
                    // 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;
            }
        }
    }
}

435
} // anon namespace
Pieter Wuille's avatar
Pieter Wuille committed
436
437
438
439
440
441
442

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
443
    stats.nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
444
445
446
447
448
    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
449
450
451
    return true;
}

452
453
void RegisterNodeSignals(CNodeSignals& nodeSignals)
{
454
    nodeSignals.GetHeight.connect(&GetHeight);
455
456
    nodeSignals.ProcessMessages.connect(&ProcessMessages);
    nodeSignals.SendMessages.connect(&SendMessages);
Pieter Wuille's avatar
Pieter Wuille committed
457
458
    nodeSignals.InitializeNode.connect(&InitializeNode);
    nodeSignals.FinalizeNode.connect(&FinalizeNode);
459
}
Pieter Wuille's avatar
Pieter Wuille committed
460

461
462
void UnregisterNodeSignals(CNodeSignals& nodeSignals)
{
463
    nodeSignals.GetHeight.disconnect(&GetHeight);
464
465
    nodeSignals.ProcessMessages.disconnect(&ProcessMessages);
    nodeSignals.SendMessages.disconnect(&SendMessages);
Pieter Wuille's avatar
Pieter Wuille committed
466
467
    nodeSignals.InitializeNode.disconnect(&InitializeNode);
    nodeSignals.FinalizeNode.disconnect(&FinalizeNode);
468
}
Pieter Wuille's avatar
Pieter Wuille committed
469

jtimon's avatar
jtimon committed
470
471
CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator)
{
472
    // Find the first block the caller has in the main chain
473
    BOOST_FOREACH(const uint256& hash, locator.vHave) {
474
        BlockMap::iterator mi = mapBlockIndex.find(hash);
475
476
477
        if (mi != mapBlockIndex.end())
        {
            CBlockIndex* pindex = (*mi).second;
jtimon's avatar
jtimon committed
478
            if (chain.Contains(pindex))
479
480
481
                return pindex;
        }
    }
jtimon's avatar
jtimon committed
482
    return chain.Genesis();
483
484
}

485
CCoinsViewCache *pcoinsTip = NULL;
486
CBlockTreeDB *pblocktree = NULL;
Pieter Wuille's avatar
Pieter Wuille committed
487

s_nakamoto's avatar
s_nakamoto committed
488
489
490
491
492
//////////////////////////////////////////////////////////////////////////////
//
// mapOrphanTransactions
//

493
bool AddOrphanTx(const CTransaction& tx, NodeId peer)
s_nakamoto's avatar
s_nakamoto committed
494
495
496
{
    uint256 hash = tx.GetHash();
    if (mapOrphanTransactions.count(hash))
497
498
499
500
501
502
503
504
505
        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:
506
507
    unsigned int sz = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION);
    if (sz > 5000)
508
    {
509
        LogPrint("mempool", "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString());
510
511
        return false;
    }
512

513
514
    mapOrphanTransactions[hash].tx = tx;
    mapOrphanTransactions[hash].fromPeer = peer;
515
    BOOST_FOREACH(const CTxIn& txin, tx.vin)
516
        mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash);
517

518
519
    LogPrint("mempool", "stored orphan tx %s (mapsz %u prevsz %u)\n", hash.ToString(),
             mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
520
    return true;
s_nakamoto's avatar
s_nakamoto committed
521
522
}

Pieter Wuille's avatar
Pieter Wuille committed
523
void static EraseOrphanTx(uint256 hash)
s_nakamoto's avatar
s_nakamoto committed
524
{
525
    map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
526
    if (it == mapOrphanTransactions.end())
s_nakamoto's avatar
s_nakamoto committed
527
        return;
528
    BOOST_FOREACH(const CTxIn& txin, it->second.tx.vin)
s_nakamoto's avatar
s_nakamoto committed
529
    {
530
        map<uint256, set<uint256> >::iterator itPrev = mapOrphanTransactionsByPrev.find(txin.prevout.hash);
531
532
        if (itPrev == mapOrphanTransactionsByPrev.end())
            continue;
533
534
535
        itPrev->second.erase(hash);
        if (itPrev->second.empty())
            mapOrphanTransactionsByPrev.erase(itPrev);
s_nakamoto's avatar
s_nakamoto committed
536
    }
537
    mapOrphanTransactions.erase(it);
s_nakamoto's avatar
s_nakamoto committed
538
539
}

540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
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);
}


557
unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
558
{
559
    unsigned int nEvicted = 0;
560
561
562
    while (mapOrphanTransactions.size() > nMaxOrphans)
    {
        // Evict a random orphan:
563
        uint256 randomhash = GetRandHash();
564
        map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
565
566
567
568
569
570
571
        if (it == mapOrphanTransactions.end())
            it = mapOrphanTransactions.begin();
        EraseOrphanTx(it->first);
        ++nEvicted;
    }
    return nEvicted;
}
s_nakamoto's avatar
s_nakamoto committed
572
573
574
575
576
577
578







579
bool IsStandardTx(const CTransaction& tx, string& reason)
Gavin Andresen's avatar
Gavin Andresen committed
580
{
581
    AssertLockHeld(cs_main);
582
    if (tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) {
583
        reason = "version";
584
        return false;
585
    }
586

587
588
589
    // 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)
590
    // Basically we don't want to propagate transactions that can't be included in
591
592
593
594
595
596
597
598
599
600
601
602
603
604
    // 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)) {
605
        reason = "non-final";
606
        return false;
607
    }
608

609
610
611
612
    // 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.
613
    unsigned int sz = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION);
614
615
    if (sz >= MAX_STANDARD_TX_SIZE) {
        reason = "tx-size";
616
        return false;
617
    }
618

619
    BOOST_FOREACH(const CTxIn& txin, tx.vin)
Gavin Andresen's avatar
Gavin Andresen committed
620
    {
621
622
        // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
        // keys. (remember the 520 byte limit on redeemScript size) That works
623
        // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627
624
625
626
627
628
        // 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) {
629
            reason = "scriptsig-size";
630
            return false;
631
632
633
        }
        if (!txin.scriptSig.IsPushOnly()) {
            reason = "scriptsig-not-pushonly";
634
            return false;
635
        }
Gavin Andresen's avatar
Gavin Andresen committed
636
    }
637
638
639

    unsigned int nDataOut = 0;
    txnouttype whichType;
640
    BOOST_FOREACH(const CTxOut& txout, tx.vout) {
641
        if (!::IsStandard(txout.scriptPubKey, whichType)) {
642
            reason = "scriptpubkey";
643
            return false;
644
        }
645

646
647
        if (whichType == TX_NULL_DATA)
            nDataOut++;
648
649
650
651
        else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) {
            reason = "bare-multisig";
            return false;
        } else if (txout.IsDust(::minRelayTxFee)) {
652
            reason = "dust";
653
            return false;
654
        }
655
    }
656

657
658
    // only one OP_RETURN txout is permitted
    if (nDataOut > 1) {
659
        reason = "multi-op-return";
660
661
662
        return false;
    }

Gavin Andresen's avatar
Gavin Andresen committed
663
664
665
    return true;
}

666
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
667
{
668
    AssertLockHeld(cs_main);
669
670
671
672
    // Time based nLockTime implemented in 0.1.6
    if (tx.nLockTime == 0)
        return true;
    if (nBlockHeight == 0)
673
        nBlockHeight = chainActive.Height();
674
675
    if (nBlockTime == 0)
        nBlockTime = GetAdjustedTime();
676
    if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
677
678
679
680
681
682
683
        return true;
    BOOST_FOREACH(const CTxIn& txin, tx.vin)
        if (!txin.IsFinal())
            return false;
    return true;
}

Gavin Andresen's avatar
Gavin Andresen committed
684
//
685
686
// Check transaction inputs to mitigate two
// potential denial-of-service attacks:
Gavin Andresen's avatar
Gavin Andresen committed
687
//
688
689
690
691
// 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
Gavin Andresen's avatar
Gavin Andresen committed
692
//
693
bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
Gavin Andresen's avatar
Gavin Andresen committed
694
{
695
    if (tx.IsCoinBase())
696
        return true; // Coinbases don't use vin normally
697

698
    for (unsigned int i = 0; i < tx.vin.size(); i++)
Gavin Andresen's avatar
Gavin Andresen committed
699
    {
700
        const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]);
Gavin Andresen's avatar
Gavin Andresen committed
701
702

        vector<vector<unsigned char> > vSolutions;
703
704
        txnouttype whichType;
        // get the scriptPubKey corresponding to this input:
705
        const CScript& prevScript = prev.scriptPubKey;
706
        if (!Solver(prevScript, whichType, vSolutions))
707
            return false;
708
        int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions);
709
710
        if (nArgsExpected < 0)
            return false;
711
712
713
714

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

Gavin Andresen's avatar
Gavin Andresen committed
722
723
        if (whichType == TX_SCRIPTHASH)
        {
724
            if (stack.empty())
Gavin Andresen's avatar
Gavin Andresen committed
725
                return false;
726
            CScript subscript(stack.back().begin(), stack.back().end());
727
728
            vector<vector<unsigned char> > vSolutions2;
            txnouttype whichType2;
729
730
731
732
733
734
735
736
737
738
739
740
741
742
            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
743
        }
744

745
        if (stack.size() != (unsigned int)nArgsExpected)
746
            return false;
Gavin Andresen's avatar
Gavin Andresen committed
747
748
749
750
751
    }

    return true;
}

752
unsigned int GetLegacySigOpCount(const CTransaction& tx)
753
{
754
    unsigned int nSigOps = 0;
755
    BOOST_FOREACH(const CTxIn& txin, tx.vin)
756
757
758
    {
        nSigOps += txin.scriptSig.GetSigOpCount(false);
    }
759
    BOOST_FOREACH(const CTxOut& txout, tx.vout)
760
761
762
763
764
    {
        nSigOps += txout.scriptPubKey.GetSigOpCount(false);
    }
    return nSigOps;
}
s_nakamoto's avatar
s_nakamoto committed
765

766
unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
767
768
769
770
771
772
773
774
775
776
777
778
779
{
    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
780
781
782
783
784
785
786
787








788
bool CheckTransaction(const CTransaction& tx, CValidationState &state)
789
790
{
    // Basic checks that don't depend on any context
791
    if (tx.vin.empty())
Gavin Andresen's avatar
Gavin Andresen committed
792
        return state.DoS(10, error("CheckTransaction() : vin empty"),
793
                         REJECT_INVALID, "bad-txns-vin-empty");
794
    if (tx.vout.empty())
Gavin Andresen's avatar
Gavin Andresen committed
795
        return state.DoS(10, error("CheckTransaction() : vout empty"),
796
                         REJECT_INVALID, "bad-txns-vout-empty");
797
    // Size limits
798
    if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
799
        return state.DoS(100, error("CheckTransaction() : size limits failed"),
800
                         REJECT_INVALID, "bad-txns-oversize");
801
802

    // Check for negative or overflow output values
803
    CAmount nValueOut = 0;
804
    BOOST_FOREACH(const CTxOut& txout, tx.vout)
805
806
    {
        if (txout.nValue < 0)
Gavin Andresen's avatar
Gavin Andresen committed
807
            return state.DoS(100, error("CheckTransaction() : txout.nValue negative"),
808
                             REJECT_INVALID, "bad-txns-vout-negative");
809
        if (txout.nValue > MAX_MONEY)
Gavin Andresen's avatar
Gavin Andresen committed
810
            return state.DoS(100, error("CheckTransaction() : txout.nValue too high"),
811
                             REJECT_INVALID, "bad-txns-vout-toolarge");
812
813
        nValueOut += txout.nValue;
        if (!MoneyRange(nValueOut))
814
            return state.DoS(100, error("CheckTransaction() : txout total out of range"),
815
                             REJECT_INVALID, "bad-txns-txouttotal-toolarge");
816
817
    }

818
819
    // Check for duplicate inputs
    set<COutPoint> vInOutPoints;
820
    BOOST_FOREACH(const CTxIn& txin, tx.vin)
821
822
    {
        if (vInOutPoints.count(txin.prevout))
823
            return state.DoS(100, error("CheckTransaction() : duplicate inputs"),
824
                             REJECT_INVALID, "bad-txns-inputs-duplicate");
825
826
827
        vInOutPoints.insert(txin.prevout);
    }

828
    if (tx.IsCoinBase())
829
    {
830
        if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
Gavin Andresen's avatar
Gavin Andresen committed
831
            return state.DoS(100, error("CheckTransaction() : coinbase script size"),
832
                             REJECT_INVALID, "bad-cb-length");
833
834
835
    }
    else
    {
836
        BOOST_FOREACH(const CTxIn& txin, tx.vin)
837
            if (txin.prevout.IsNull())
Gavin Andresen's avatar
Gavin Andresen committed
838
                return state.DoS(10, error("CheckTransaction() : prevout is null"),
839
                                 REJECT_INVALID, "bad-txns-prevout-null");
840
841
842
843
844
    }

    return true;
}

845
CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree)
846
{
847
848
849
850
    {
        LOCK(mempool.cs);
        uint256 hash = tx.GetHash();
        double dPriorityDelta = 0;
851
        CAmount nFeeDelta = 0;
852
853
854
855
856
        mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
        if (dPriorityDelta > 0 || nFeeDelta > 0)
            return 0;
    }

857
    CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes);
858
859
860

    if (fAllowFree)
    {
861
862
        // 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
863
864
        //   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.
865
        if (nBytes < (DEFAULT_BLOCK_PRIORITY_SIZE - 1000))
866
            nMinFee = 0;
867
868
869
870
871
872
873
    }

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

Pieter Wuille's avatar
Pieter Wuille committed
874

875
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
876
                        bool* pfMissingInputs, bool fRejectInsaneFee)
s_nakamoto's avatar
s_nakamoto committed
877
{
878
    AssertLockHeld(cs_main);
s_nakamoto's avatar
s_nakamoto committed
879
880
881
    if (pfMissingInputs)
        *pfMissingInputs = false;

882
    if (!CheckTransaction(tx, state))
883
        return error("AcceptToMemoryPool: : CheckTransaction failed");
884

s_nakamoto's avatar
s_nakamoto committed
885
    // Coinbase is only valid in a block, not as a loose transaction
886
    if (tx.IsCoinBase())
Gavin Andresen's avatar
Gavin Andresen committed
887
888
        return state.DoS(100, error("AcceptToMemoryPool: : coinbase as individual tx"),
                         REJECT_INVALID, "coinbase");
s_nakamoto's avatar
s_nakamoto committed
889

890
    // Rather not work on nonstandard transactions (unless -testnet/-regtest)
891
    string reason;
jtimon's avatar
jtimon committed
892
    if (Params().RequireStandard() && !IsStandardTx(tx, reason))
Gavin Andresen's avatar
Gavin Andresen committed
893
        return state.DoS(0,
894
                         error("AcceptToMemoryPool : nonstandard transaction: %s", reason),
Gavin Andresen's avatar
Gavin Andresen committed
895
                         REJECT_NONSTANDARD, reason);
896

Pieter Wuille's avatar
Pieter Wuille committed
897
    // is it already in the memory pool?
898
    uint256 hash = tx.GetHash();
899
900
    if (pool.exists(hash))
        return false;
s_nakamoto's avatar
s_nakamoto committed
901
902

    // Check for conflicts with in-memory transactions
903
904
    {
    LOCK(pool.cs); // protect pool.mapNextTx
905
    for (unsigned int i = 0; i < tx.vin.size(); i++)
s_nakamoto's avatar
s_nakamoto committed
906
    {
907
        COutPoint outpoint = tx.vin[i].prevout;
908
        if (pool.mapNextTx.count(outpoint))
s_nakamoto's avatar
s_nakamoto committed
909
        {
910
            // Disable replacement feature for now
911
            return false;
s_nakamoto's avatar
s_nakamoto committed
912
913
        }
    }
914
    }
s_nakamoto's avatar
s_nakamoto committed
915
916

    {
917
        CCoinsView dummy;
918
        CCoinsViewCache view(&dummy);
919

920
        CAmount nValueIn = 0;
921
        {
922
        LOCK(pool.cs);
923
        CCoinsViewMemPool viewMemPool(pcoinsTip, pool);
924
        view.SetBackend(viewMemPool);
Pieter Wuille's avatar
Pieter Wuille committed
925
926
927

        // do we already have it?
        if (view.HaveCoins(hash))
928
            return false;
Pieter Wuille's avatar
Pieter Wuille committed
929
930

        // do all inputs exist?
Pieter Wuille's avatar
Pieter Wuille committed
931
932
        // 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
933
934
935
936
937
938
        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
939
940
        }

Pieter Wuille's avatar
Pieter Wuille committed
941
        // are the actual inputs available?
942
        if (!view.HaveInputs(tx))
Gavin Andresen's avatar
Gavin Andresen committed
943
            return state.Invalid(error("AcceptToMemoryPool : inputs already spent"),
944
                                 REJECT_DUPLICATE, "bad-txns-inputs-spent");
945

946
947
948
        // Bring the best block into scope
        view.GetBestBlock();

949
950
        nValueIn = view.GetValueIn(tx);

951
952
953
        // 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
954

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

959
960
961
962
963
964
965
966
967
968
969
970
        // 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");
971

972
973
        CAmount nValueOut = tx.GetValueOut();
        CAmount nFees = nValueIn-nValueOut;
974
975
976
977
        double dPriority = view.GetPriority(tx, chainActive.Height());

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

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

Gavin Andresen's avatar
Gavin Andresen committed
986
        // Continuously rate-limit free (really, very-low-fee)transactions
987
        // This mitigates 'penny-flooding' -- sending thousands of free transactions just to
988
        // be annoying or make others' transactions take longer to confirm.
Gavin Andresen's avatar
Gavin Andresen committed
989
        if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize))
990
        {
991
            static CCriticalSection csFreeLimiter;
992
            static double dFreeCount;
993
994
995
996
            static int64_t nLastTime;
            int64_t nNow = GetTime();

            LOCK(csFreeLimiter);
997

998
999
1000
1001
1002
1003
            // 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
1004
1005
                return state.DoS(0, error("AcceptToMemoryPool : free transaction rejected by rate limiter"),
                                 REJECT_INSUFFICIENTFEE, "insufficient priority");
1006
            LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
1007
            dFreeCount += nSize;
1008
        }
1009

Gavin Andresen's avatar
Gavin Andresen committed
1010
        if (fRejectInsaneFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000)
1011
            return error("AcceptToMemoryPool: : insane fees %s, %d > %d",
1012
                         hash.ToString(),
Gavin Andresen's avatar
Gavin Andresen committed
1013
                         nFees, ::minRelayTxFee.GetFee(nSize) * 10000);
1014

1015
1016
        // Check against previous transactions
        // This is done last to help prevent CPU exhaustion denial-of-service attacks.
1017
        if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true))
1018
        {
1019
            return error("AcceptToMemoryPool: : ConnectInputs failed %s", hash.ToString());
1020
        }
1021
1022
        // Store transaction in memory
        pool.addUnchecked(hash, entry);
1023
1024
    }

1025
    SyncWithWallets(tx, NULL);
1026

1027
    return true;
1028
1029
}

1030
// 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
1031
bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
1032
{
Pieter Wuille's avatar
Pieter Wuille committed
1033
    CBlockIndex *pindexSlow = NULL;
1034
1035
1036
    {
        LOCK(cs_main);
        {
1037
            if (mempool.lookup(hash, txOut))
1038
1039
1040
1041
            {
                return true;
            }
        }
Pieter Wuille's avatar
Pieter Wuille committed
1042

1043
1044
1045
1046
1047
1048
1049
        if (fTxIndex) {
            CDiskTxPos postx;
            if (pblocktree->ReadTxIndex(hash, postx)) {
                CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
                CBlockHeader header;
                try {
                    file >> header;
1050
                    fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
1051
1052
                    file >> txOut;
                } catch (std::exception &e) {
1053
                    return error("%s : Deserialize or I/O error - %s", __func__, e.what());
1054
1055
1056
                }
                hashBlock = header.GetHash();
                if (txOut.GetHash() != hash)
1057
                    return error("%s : txid mismatch", __func__);
1058
1059
1060
1061
                return true;
            }
        }

Pieter Wuille's avatar
Pieter Wuille committed
1062
1063
1064
        if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
            int nHeight = -1;
            {
1065
                CCoinsViewCache &view = *pcoinsTip;
1066
1067
1068
                const CCoins* coins = view.AccessCoins(hash);
                if (coins)
                    nHeight = coins->nHeight;
Pieter Wuille's avatar
Pieter Wuille committed
1069
1070
            }
            if (nHeight > 0)
1071
                pindexSlow = chainActive[nHeight];
1072
1073
        }
    }
s_nakamoto's avatar
s_nakamoto committed
1074

Pieter Wuille's avatar
Pieter Wuille committed
1075
1076
    if (pindexSlow) {
        CBlock block;
1077
        if (ReadBlockFromDisk(block, pindexSlow)) {
Pieter Wuille's avatar
Pieter Wuille committed
1078
1079
1080
1081
1082
1083
1084
1085
1086
            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
1087

Pieter Wuille's avatar
Pieter Wuille committed
1088
1089
    return false;
}
s_nakamoto's avatar
s_nakamoto committed
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100






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

1101
1102
1103
bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos)
{
    // Open history file to append
1104
    CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
1105
    if (fileout.IsNull())
1106
        return error("WriteBlockToDisk : OpenBlockFile failed");
1107
1108
1109
1110
1111
1112

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

    // Write block
1113
    long fileOutPos = ftell(fileout.Get());
1114
    if (fileOutPos < 0)
1115
        return error("WriteBlockToDisk : ftell failed");
1116
1117
1118
1119
    pos.nPos = (unsigned int)fileOutPos;
    fileout << block;

    // Flush stdio buffers and commit to disk before returning
1120
    fflush(fileout.Get());
1121
    if (!IsInitialBlockDownload())
1122
        FileCommit(fileout.Get());
1123
1124
1125
1126

    return true;
}

1127
1128
1129
1130
1131
bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos)
{
    block.SetNull();

    // Open history file to read
1132
    CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
1133
    if (filein.IsNull())
1134
        return error("ReadBlockFromDisk : OpenBlockFile failed");
1135
1136
1137
1138
1139
1140

    // Read block
    try {
        filein >> block;
    }
    catch (std::exception &e) {
1141
        return error("%s : Deserialize or I/O error - %s", __func__, e.what());
1142
1143
1144
1145
    }

    // Check the header
    if (!CheckProofOfWork(block.GetHash(), block.nBits))
1146
        return error("ReadBlockFromDisk : Errors in block header");
1147
1148
1149
1150

    return true;
}

1151
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex)
s_nakamoto's avatar
s_nakamoto committed
1152
{
1153
    if (!ReadBlockFromDisk(block, pindex->GetBlockPos()))
s_nakamoto's avatar
s_nakamoto committed
1154
        return false;
1155
1156
    if (block.GetHash() != pindex->GetBlockHash())
        return error("ReadBlockFromDisk(CBlock&, CBlockIndex*) : GetHash() doesn't match index");
s_nakamoto's avatar
s_nakamoto committed
1157
1158
1159
    return true;
}

1160
CAmount GetBlockValue(int nHeight, const CAmount& nFees)
s_nakamoto's avatar
s_nakamoto committed
1161
{
1162
    int64_t nSubsidy = 50 * COIN;
1163
1164
1165
1166
1167
    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
1168

1169
    // Subsidy is cut in half every 210,000 blocks which will occur approximately every 4 years.
1170
    nSubsidy >>= halvings;
s_nakamoto's avatar
s_nakamoto committed
1171
1172
1173
1174
1175
1176

    return nSubsidy + nFees;
}

bool IsInitialBlockDownload()
{
1177
    LOCK(cs_main);
1178
    if (fImporting || fReindex || chainActive.Height() < Checkpoints::GetTotalBlocksEstimate())
s_nakamoto's avatar
s_nakamoto committed
1179
        return true;
1180
    static int64_t nLastUpdate;
s_nakamoto's avatar
s_nakamoto committed
1181
    static CBlockIndex* pindexLastBest;
1182
    if (chainActive.Tip() != pindexLastBest)
s_nakamoto's avatar
s_nakamoto committed
1183
    {
1184
        pindexLastBest = chainActive.Tip();
s_nakamoto's avatar
s_nakamoto committed
1185
1186
1187
        nLastUpdate = GetTime();
    }
    return (GetTime() - nLastUpdate < 10 &&
1188
            chainActive.Tip()->GetBlockTime() < GetTime() - 24 * 60 * 60);
s_nakamoto's avatar
s_nakamoto committed
1189
1190
}

1191
bool fLargeWorkForkFound = false;
1192
bool fLargeWorkInvalidChainFound = false;
1193
1194
1195
1196
CBlockIndex *pindexBestForkTip = NULL, *pindexBestForkBase = NULL;

void CheckForkWarningConditions()
{
1197
    AssertLockHeld(cs_main);
1198
1199
1200
1201
1202
    // 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;

1203
1204
    // If our best fork is no longer within 72 blocks (+/- 12 hours if no one mines it)
    // of our head, drop it
1205
    if (pindexBestForkTip && chainActive.Height() - pindexBestForkTip->nHeight >= 72)
1206
1207
        pindexBestForkTip = NULL;

1208
    if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > chainActive.Tip()->nChainWork + (chainActive.Tip()->GetBlockWork() * 6)))
1209
    {
1210
1211
        if (!fLargeWorkForkFound)
        {
Gavin Andresen's avatar
Gavin Andresen committed
1212
1213
1214
            std::string warning = std::string("'Warning: Large-work fork detected, forking after block ") +
                pindexBestForkBase->phashBlock->ToString() + std::string("'");
            CAlert::Notify(warning, true);
1215
        }
1216
1217
        if (pindexBestForkTip)
        {
1218
            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",
1219
1220
                   pindexBestForkBase->nHeight, pindexBestForkBase->phashBlock->ToString(),
                   pindexBestForkTip->nHeight, pindexBestForkTip->phashBlock->ToString());
1221
1222
1223
1224
            fLargeWorkForkFound = true;
        }
        else
        {
1225
            LogPrintf("CheckForkWarningConditions: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n");
1226
1227
1228
1229
1230
            fLargeWorkInvalidChainFound = true;
        }
    }
    else
    {
1231
        fLargeWorkForkFound = false;
1232
1233
        fLargeWorkInvalidChainFound = false;
    }
1234
1235
1236
1237
}

void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip)
{
1238
    AssertLockHeld(cs_main);
1239
1240
    // If we are on a fork that is sufficiently large, set a warning flag
    CBlockIndex* pfork = pindexNewForkTip;
1241
    CBlockIndex* plonger = chainActive.Tip();
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
    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)) &&
1259
            pindexNewForkTip->nChainWork - pfork->nChainWork > (pfork->GetBlockWork() * 7) &&
1260
            chainActive.Height() - pindexNewForkTip->nHeight < 72)
1261
1262
1263
1264
1265
1266
1267
1268
    {
        pindexBestForkTip = pindexNewForkTip;
        pindexBestForkBase = pfork;
    }

    CheckForkWarningConditions();
}

1269
// Requires cs_main.
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
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
1280
1281
    int banscore = GetArg("-banscore", 100);
    if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore)
1282
1283
1284
1285
1286
1287
1288
    {
        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
1289
void static InvalidChainFound(CBlockIndex* pindexNew)
s_nakamoto's avatar
s_nakamoto committed
1290
{
1291
1292
    if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
        pindexBestInvalid = pindexNew;
1293

1294
    LogPrintf("InvalidChainFound: invalid block=%s  height=%d  log2_work=%.8g  date=%s\n",
1295
      pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
Pieter Wuille's avatar
Pieter Wuille committed
1296
      log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S",
1297
      pindexNew->GetBlockTime()));
1298
    LogPrintf("InvalidChainFound:  current best=%s  height=%d  log2_work=%.8g  date=%s\n",
1299
1300
      chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0),
      DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()));
1301
    CheckForkWarningConditions();
s_nakamoto's avatar
s_nakamoto committed
1302
1303
}

1304
1305
1306
1307
1308
1309
1310
1311
1312
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)) {
            CBlockReject reject = {state.GetRejectCode(), state.GetRejectReason(), pindex->GetBlockHash()};
            State(it->second)->rejects.push_back(reject);
            if (nDoS > 0)
                Misbehaving(it->second, nDoS);
1313
        }
1314
1315
1316
1317
    }
    if (!state.CorruptionPossible()) {
        pindex->nStatus |= BLOCK_FAILED_VALID;
        pblocktree->WriteBlockIndex(CDiskBlockIndex(pindex));
1318
        setBlockIndexCandidates.erase(pindex);
1319
1320
        InvalidChainFound(pindex);
    }
1321
1322
}

1323
void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight)
Pieter Wuille's avatar
Pieter Wuille committed
1324
1325
{
    // mark inputs spent
1326
    if (!tx.IsCoinBase()) {
Pieter Wuille's avatar
Pieter Wuille committed
1327
        txundo.vprevout.reserve(tx.vin.size());
1328
        BOOST_FOREACH(const CTxIn &txin, tx.vin) {
Pieter Wuille's avatar
Pieter Wuille committed
1329
            txundo.vprevout.push_back(CTxInUndo());
1330
            bool ret = inputs.ModifyCoins(txin.prevout.hash)->Spend(txin.prevout, txundo.vprevout.back());
1331
            assert(ret);
Pieter Wuille's avatar
Pieter Wuille committed
1332
1333
1334
1335
        }
    }

    // add outputs
1336
    inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight);
Pieter Wuille's avatar
Pieter Wuille committed
1337
1338
}

1339
1340
bool CScriptCheck::operator()() const {
    const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
1341
    if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingSignatureChecker(*ptxTo, nIn, cacheStore)))
1342
        return error("CScriptCheck() : %s:%d VerifySignature failed", ptxTo->GetHash().ToString(), nIn);
1343
1344
1345
    return true;
}

1346
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
1347
{
1348
    if (!tx.IsCoinBase())
s_nakamoto's avatar
s_nakamoto committed
1349
    {
1350
        if (pvChecks)
1351
            pvChecks->reserve(tx.vin.size());
1352

Pieter Wuille's avatar
Pieter Wuille committed
1353
1354
        // 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.
1355
        if (!inputs.HaveInputs(tx))
1356
            return state.Invalid(error("CheckInputs() : %s inputs unavailable", tx.GetHash().ToString()));
Pieter Wuille's avatar
Pieter Wuille committed
1357

1358
1359
        // While checking, GetBestBlock() refers to the parent block.
        // This is also true for mempool checks.
1360
1361
        CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
        int nSpendHeight = pindexPrev->nHeight + 1;
1362
1363
        CAmount nValueIn = 0;
        CAmount nFees = 0;
1364
        for (unsigned int i = 0; i < tx.vin.size(); i++)
s_nakamoto's avatar
s_nakamoto committed
1365
        {
1366
            const COutPoint &prevout = tx.vin[i].prevout;
1367
1368
            const CCoins *coins = inputs.AccessCoins(prevout.hash);
            assert(coins);
s_nakamoto's avatar
s_nakamoto committed
1369
1370

            // If prev is coinbase, check that it's matured
1371
1372
            if (coins->IsCoinBase()) {
                if (nSpendHeight - coins->nHeight < COINBASE_MATURITY)
Gavin Andresen's avatar
Gavin Andresen committed
1373
                    return state.Invalid(
1374
                        error("CheckInputs() : tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
1375
                        REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
Pieter Wuille's avatar
Pieter Wuille committed
1376
            }
s_nakamoto's avatar
s_nakamoto committed
1377

1378
            // Check for negative or overflow input values
1379
1380
            nValueIn += coins->vout[prevout.n].nValue;
            if (!MoneyRange(coins->vout[prevout.n].nValue) || !MoneyRange(nValueIn))
Gavin Andresen's avatar
Gavin Andresen committed
1381
                return state.DoS(100, error("CheckInputs() : txin values out of range"),
1382
                                 REJECT_INVALID, "bad-txns-inputvalues-outofrange");
1383
1384

        }
Pieter Wuille's avatar
Pieter Wuille committed
1385

1386
        if (nValueIn < tx.GetValueOut())
1387
1388
            return state.DoS(100, error("CheckInputs() : %s value in (%s) < value out (%s)",
                                        tx.GetHash().ToString(), FormatMoney(nValueIn), FormatMoney(tx.GetValueOut())),
1389
                             REJECT_INVALID, "bad-txns-in-belowout");
Pieter Wuille's avatar
Pieter Wuille committed
1390
1391

        // Tally transaction fees
1392
        CAmount nTxFee = nValueIn - tx.GetValueOut();
Pieter Wuille's avatar
Pieter Wuille committed
1393
        if (nTxFee < 0)
1394
            return state.DoS(100, error("CheckInputs() : %s nTxFee < 0", tx.GetHash().ToString()),
1395
                             REJECT_INVALID, "bad-txns-fee-negative");
Pieter Wuille's avatar
Pieter Wuille committed
1396
1397
        nFees += nTxFee;
        if (!MoneyRange(nFees))
Gavin Andresen's avatar
Gavin Andresen committed
1398
            return state.DoS(100, error("CheckInputs() : nFees out of range"),
1399
                             REJECT_INVALID, "bad-txns-fee-outofrange");
Pieter Wuille's avatar
Pieter Wuille committed
1400

1401
1402
1403
1404
        // 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
1405
        // Skip ECDSA signature verification when connecting blocks
1406
        // before the last block chain checkpoint. This is safe because block merkle hashes are
Pieter Wuille's avatar
Pieter Wuille committed
1407
        // still computed and checked, and any change will be caught at the next checkpoint.
1408
        if (fScriptChecks) {
1409
1410
            for (unsigned int i = 0; i < tx.vin.size(); i++) {
                const COutPoint &prevout = tx.vin[i].prevout;
1411
1412
                const CCoins* coins = inputs.AccessCoins(prevout.hash);
                assert(coins);
1413

1414
                // Verify signature
1415
                CScriptCheck check(*coins, tx, i, flags, cacheStore);
1416
1417
1418
                if (pvChecks) {
                    pvChecks->push_back(CScriptCheck());
                    check.swap(pvChecks->back());
1419
                } else if (!check()) {
1420
1421
1422
1423
1424
1425
1426
                    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.
1427
                        CScriptCheck check(*coins, tx, i,
1428
                                flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore);
1429
                        if (check())
1430
                            return state.Invalid(false, REJECT_NONSTANDARD, "non-mandatory-script-verify-flag");
1431
                    }
1432
1433
1434
1435
1436
1437
1438
1439
                    // 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.
                    return state.DoS(100,false, REJECT_INVALID, "mandatory-script-verify-flag-failed");
1440
                }
1441
            }
s_nakamoto's avatar
s_nakamoto committed
1442
1443
1444
1445
1446
1447
1448
1449
        }
    }

    return true;
}



1450
bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
s_nakamoto's avatar
s_nakamoto committed
1451
{
1452
    assert(pindex->GetBlockHash() == view.GetBestBlock());
s_nakamoto's avatar
s_nakamoto committed
1453

1454
1455
1456
1457
1458
    if (pfClean)
        *pfClean = false;

    bool fClean = true;

Pieter Wuille's avatar
Pieter Wuille committed
1459
    CBlockUndo blockUndo;
Pieter Wuille's avatar
Pieter Wuille committed
1460
1461
1462
1463
1464
    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
1465

1466
    if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
1467
        return error("DisconnectBlock() : block and undo data inconsistent");
Pieter Wuille's avatar
Pieter Wuille committed
1468
1469

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

1474
1475
1476
1477
        // 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.
1478
        {
1479
        CCoins outsEmpty;
1480
1481
        CCoinsModifier outs = view.ModifyCoins(hash);
        outs->ClearUnspendable();
Pieter Wuille's avatar
Pieter Wuille committed
1482

1483
        CCoins outsBlock(tx, pindex->nHeight);
1484
1485
1486
1487
        // 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)
1488
1489
            outs->nVersion = outsBlock.nVersion;
        if (*outs != outsBlock)
1490
            fClean = fClean && error("DisconnectBlock() : added transaction mismatch? database corrupted");
Pieter Wuille's avatar
Pieter Wuille committed
1491
1492

        // remove outputs
1493
1494
        outs->Clear();
        }
Pieter Wuille's avatar
Pieter Wuille committed
1495
1496
1497
1498

        // restore inputs
        if (i > 0) { // not coinbases
            const CTxUndo &txundo = blockUndo.vtxundo[i-1];
1499
1500
            if (txundo.vprevout.size() != tx.vin.size())
                return error("DisconnectBlock() : transaction and undo data inconsistent");
Pieter Wuille's avatar
Pieter Wuille committed
1501
1502
1503
            for (unsigned int j = tx.vin.size(); j-- > 0;) {
                const COutPoint &out = tx.vin[j].prevout;
                const CTxInUndo &undo = txundo.vprevout[j];
1504
                CCoinsModifier coins = view.ModifyCoins(out.hash);
1505
1506
                if (undo.nHeight != 0) {
                    // undo data contains height: this is the last output of the prevout tx being spent
1507
                    if (!coins->IsPruned())
1508
                        fClean = fClean && error("DisconnectBlock() : undo data overwriting existing transaction");
1509
1510
1511
1512
                    coins->Clear();
                    coins->fCoinBase = undo.fCoinBase;
                    coins->nHeight = undo.nHeight;
                    coins->nVersion = undo.nVersion;
Pieter Wuille's avatar
Pieter Wuille committed
1513
                } else {
1514
                    if (coins->IsPruned())
1515
                        fClean = fClean && error("DisconnectBlock() : undo data adding output to missing transaction");
Pieter Wuille's avatar
Pieter Wuille committed
1516
                }
1517
                if (coins->IsAvailable(out.n))
1518
                    fClean = fClean && error("DisconnectBlock() : undo data overwriting existing output");
1519
1520
1521
                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
1522
1523
1524
1525
1526
            }
        }
    }

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

1529
1530
1531
1532
1533
1534
    if (pfClean) {
        *pfClean = fClean;
        return true;
    } else {
        return fClean;
    }
s_nakamoto's avatar
s_nakamoto committed
1535
1536
}

1537
void static FlushBlockFile(bool fFinalize = false)
Pieter Wuille's avatar
Pieter Wuille committed
1538
1539
1540
{
    LOCK(cs_LastBlockFile);

1541
    CDiskBlockPos posOld(nLastBlockFile, 0);
Pieter Wuille's avatar
Pieter Wuille committed
1542
1543

    FILE *fileOld = OpenBlockFile(posOld);
1544
    if (fileOld) {
1545
        if (fFinalize)
1546
            TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nSize);
1547
1548
1549
        FileCommit(fileOld);
        fclose(fileOld);
    }
Pieter Wuille's avatar
Pieter Wuille committed
1550
1551

    fileOld = OpenUndoFile(posOld);
1552
    if (fileOld) {
1553
        if (fFinalize)
1554
            TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nUndoSize);
1555
1556
1557
        FileCommit(fileOld);
        fclose(fileOld);
    }
Pieter Wuille's avatar
Pieter Wuille committed
1558
1559
}

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

1562
1563
static CCheckQueue<CScriptCheck> scriptcheckqueue(128);

1564
void ThreadScriptCheck() {
1565
1566
1567
1568
    RenameThread("bitcoin-scriptch");
    scriptcheckqueue.Thread();
}

1569
1570
1571
1572
1573
1574
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;

1575
bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck)
s_nakamoto's avatar
s_nakamoto committed
1576
{
1577
    AssertLockHeld(cs_main);
s_nakamoto's avatar
s_nakamoto committed
1578
    // Check it again in case a previous version let a bad block in
1579
    if (!CheckBlock(block, state, !fJustCheck, !fJustCheck))
s_nakamoto's avatar
s_nakamoto committed
1580
1581
        return false;

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

1586
1587
    // Special case for the genesis block, skipping connection of its transactions
    // (its coinbase is unspendable)
1588
    if (block.GetHash() == Params().HashGenesisBlock()) {
1589
        view.SetBestBlock(pindex->GetBlockHash());
1590
1591
1592
        return true;
    }

1593
1594
    bool fScriptChecks = pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate();

1595
1596
1597
1598
1599
1600
1601
    // 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
1602
    // already refuses previously-known transaction ids entirely.
1603
1604
1605
1606
    // 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.
1607
1608
    bool fEnforceBIP30 = (!pindex->phashBlock) || // Enforce on CreateNewBlock invocations which don't have a hash.
                          !((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
1609
                           (pindex->nHeight==91880 && pindex->GetBlockHash() == uint256("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")));
Pieter Wuille's avatar
Pieter Wuille committed
1610
    if (fEnforceBIP30) {
1611
        BOOST_FOREACH(const CTransaction& tx, block.vtx) {
1612
1613
            const CCoins* coins = view.AccessCoins(tx.GetHash());
            if (coins && !coins->IsPruned())
Gavin Andresen's avatar
Gavin Andresen committed
1614
                return state.DoS(100, error("ConnectBlock() : tried to overwrite transaction"),
1615
                                 REJECT_INVALID, "bad-txns-BIP30");
Pieter Wuille's avatar
Pieter Wuille committed
1616
1617
        }
    }
1618

1619
    // BIP16 didn't become active until Apr 1 2012
1620
    int64_t nBIP16SwitchTime = 1333238400;
jtimon's avatar
jtimon committed
1621
    bool fStrictPayToScriptHash = (pindex->GetBlockTime() >= nBIP16SwitchTime);
1622

1623
    unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE;
1624

Pieter Wuille's avatar
Pieter Wuille committed
1625
1626
    CBlockUndo blockundo;

1627
1628
    CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL);

1629
    int64_t nTimeStart = GetTimeMicros();
1630
    CAmount nFees = 0;
1631
    int nInputs = 0;
1632
    unsigned int nSigOps = 0;
1633
    CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
1634
    std::vector<std::pair<uint256, CDiskTxPos> > vPos;
1635
    vPos.reserve(block.vtx.size());
Pieter Wuille's avatar
Pieter Wuille committed
1636
    blockundo.vtxundo.reserve(block.vtx.size() - 1);
1637
    for (unsigned int i = 0; i < block.vtx.size(); i++)
s_nakamoto's avatar
s_nakamoto committed
1638
    {
1639
        const CTransaction &tx = block.vtx[i];
Pieter Wuille's avatar
Pieter Wuille committed
1640

1641
        nInputs += tx.vin.size();
1642
        nSigOps += GetLegacySigOpCount(tx);
1643
        if (nSigOps > MAX_BLOCK_SIGOPS)
Gavin Andresen's avatar
Gavin Andresen committed
1644
            return state.DoS(100, error("ConnectBlock() : too many sigops"),
1645
                             REJECT_INVALID, "bad-blk-sigops");
1646

1647
1648
        if (!tx.IsCoinBase())
        {
1649
            if (!view.HaveInputs(tx))
Gavin Andresen's avatar
Gavin Andresen committed
1650
                return state.DoS(100, error("ConnectBlock() : inputs missing/spent"),
1651
                                 REJECT_INVALID, "bad-txns-inputs-missingorspent");
1652

1653
1654
1655
1656
1657
            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.
1658
                nSigOps += GetP2SHSigOpCount(tx, view);
1659
                if (nSigOps > MAX_BLOCK_SIGOPS)
Gavin Andresen's avatar
Gavin Andresen committed
1660
                    return state.DoS(100, error("ConnectBlock() : too many sigops"),
1661
                                     REJECT_INVALID, "bad-blk-sigops");
1662
            }
1663

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

1666
            std::vector<CScriptCheck> vChecks;
1667
            if (!CheckInputs(tx, state, view, fScriptChecks, flags, false, nScriptCheckThreads ? &vChecks : NULL))
1668
                return false;
1669
            control.Add(vChecks);
1670
1671
        }

Pieter Wuille's avatar
Pieter Wuille committed
1672
1673
1674
1675
1676
        CTxUndo undoDummy;
        if (i > 0) {
            blockundo.vtxundo.push_back(CTxUndo());
        }
        UpdateCoins(tx, state, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight);
1677

1678
        vPos.push_back(std::make_pair(tx.GetHash(), pos));
1679
        pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
s_nakamoto's avatar
s_nakamoto committed
1680
    }
1681
1682
    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
1683

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

1690
    if (!control.Wait())
Pieter Wuille's avatar
Pieter Wuille committed
1691
        return state.DoS(100, false);
1692
1693
    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);
1694

1695
1696
1697
    if (fJustCheck)
        return true;

Pieter Wuille's avatar
Pieter Wuille committed
1698
    // Write undo information to disk
1699
    if (pindex->GetUndoPos().IsNull() || !pindex->IsValid(BLOCK_VALID_SCRIPTS))
Pieter Wuille's avatar
Pieter Wuille committed
1700
    {
1701
1702
        if (pindex->GetUndoPos().IsNull()) {
            CDiskBlockPos pos;
Pieter Wuille's avatar
Pieter Wuille committed
1703
            if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
1704
                return error("ConnectBlock() : FindUndoPos failed");
Pieter Wuille's avatar
Pieter Wuille committed
1705
            if (!blockundo.WriteToDisk(pos, pindex->pprev->GetBlockHash()))
1706
                return state.Abort("Failed to write undo data");
1707
1708
1709
1710
1711
1712

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

1713
        pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
1714

Pieter Wuille's avatar
Pieter Wuille committed
1715
        CDiskBlockIndex blockindex(pindex);
1716
        if (!pblocktree->WriteBlockIndex(blockindex))
1717
            return state.Abort("Failed to write block index");
s_nakamoto's avatar
s_nakamoto committed
1718
1719
    }

1720
    if (fTxIndex)
Pieter Wuille's avatar
Pieter Wuille committed
1721
        if (!pblocktree->WriteTxIndex(vPos))
1722
            return state.Abort("Failed to write transaction index");
1723

1724
    // add this block to the view's block chain
1725
    view.SetBestBlock(pindex->GetBlockHash());
Pieter Wuille's avatar
Pieter Wuille committed
1726

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

1730
1731
1732
    // Watch for changes to the previous coinbase transaction.
    static uint256 hashPrevBestCoinBase;
    g_signals.UpdatedTransaction(hashPrevBestCoinBase);
1733
    hashPrevBestCoinBase = block.vtx[0].GetHash();
1734

1735
1736
1737
    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
1738
1739
1740
    return true;
}

1741
// Update the on-disk chain state.
1742
bool static WriteChainState(CValidationState &state) {
1743
    static int64_t nLastWrite = 0;
1744
    if (pcoinsTip->GetCacheSize() > nCoinCacheSize || (!IsInitialBlockDownload() && GetTimeMicros() > nLastWrite + 600*1000000)) {
1745
1746
1747
1748
1749
1750
        // 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()))
1751
            return state.Error("out of disk space");
Pieter Wuille's avatar
Pieter Wuille committed
1752
        FlushBlockFile();
1753
        pblocktree->Sync();
Pieter Wuille's avatar
Pieter Wuille committed
1754
        if (!pcoinsTip->Flush())
1755
            return state.Abort("Failed to write to coin database");
1756
        nLastWrite = GetTimeMicros();
Pieter Wuille's avatar
Pieter Wuille committed
1757
    }
1758
1759
    return true;
}
Pieter Wuille's avatar
Pieter Wuille committed
1760

1761
// Update chainActive and related internal data structures.
1762
void static UpdateTip(CBlockIndex *pindexNew) {
1763
    chainActive.SetTip(pindexNew);
s_nakamoto's avatar
s_nakamoto committed
1764
1765
1766

    // New best block
    nTimeBestReceived = GetTime();
1767
    mempool.AddTransactionsUpdated(1);
1768

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

1774
1775
    cvBlockChange.notify_all();

1776
    // Check the version of the last 100 blocks to see if we need to upgrade:
1777
1778
    static bool fWarned = false;
    if (!IsInitialBlockDownload() && !fWarned)
1779
1780
    {
        int nUpgraded = 0;
1781
        const CBlockIndex* pindex = chainActive.Tip();
1782
1783
1784
1785
1786
1787
1788
        for (int i = 0; i < 100 && pindex != NULL; i++)
        {
            if (pindex->nVersion > CBlock::CURRENT_VERSION)
                ++nUpgraded;
            pindex = pindex->pprev;
        }
        if (nUpgraded > 0)
1789
            LogPrintf("SetBestChain: %d of last 100 blocks above version %d\n", nUpgraded, (int)CBlock::CURRENT_VERSION);
1790
        if (nUpgraded > 100/2)
1791
        {
1792
            // strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user:
1793
            strMiscWarning = _("Warning: This version is obsolete, upgrade required!");
1794
1795
1796
            CAlert::Notify(strMiscWarning, true);
            fWarned = true;
        }
1797
    }
1798
}
1799

1800
1801
1802
1803
1804
1805
1806
1807
// Disconnect chainActive's tip.
bool static DisconnectTip(CValidationState &state) {
    CBlockIndex *pindexDelete = chainActive.Tip();
    assert(pindexDelete);
    mempool.check(pcoinsTip);
    // Read block from disk.
    CBlock block;
    if (!ReadBlockFromDisk(block, pindexDelete))
1808
        return state.Abort("Failed to read block");
1809
1810
    // Apply the block atomically to the chain state.
    int64_t nStart = GetTimeMicros();
1811
    {
1812
        CCoinsViewCache view(pcoinsTip);
1813
1814
1815
        if (!DisconnectBlock(block, state, pindexDelete, view))
            return error("DisconnectTip() : DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
        assert(view.Flush());
1816
    }
1817
    LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
1818
1819
1820
    // Write the chain state to disk, if necessary.
    if (!WriteChainState(state))
        return false;
Gavin Andresen's avatar
Gavin Andresen committed
1821
    // Resurrect mempool transactions from the disconnected block.
1822
1823
    BOOST_FOREACH(const CTransaction &tx, block.vtx) {
        // ignore validation errors in resurrected transactions
Gavin Andresen's avatar
Gavin Andresen committed
1824
        list<CTransaction> removed;
1825
        CValidationState stateDummy;
1826
1827
        if (!tx.IsCoinBase())
            if (!AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
Gavin Andresen's avatar
Gavin Andresen committed
1828
                mempool.remove(tx, removed, true);
1829
1830
1831
1832
    }
    mempool.check(pcoinsTip);
    // Update chainActive and related variables.
    UpdateTip(pindexDelete->pprev);
Gavin Andresen's avatar
Gavin Andresen committed
1833
1834
1835
    // Let wallets know transactions went from 1-confirmed to
    // 0-confirmed or conflicted:
    BOOST_FOREACH(const CTransaction &tx, block.vtx) {
1836
        SyncWithWallets(tx, NULL);
Gavin Andresen's avatar
Gavin Andresen committed
1837
    }
1838
    return true;
1839
}
1840

1841
1842
1843
1844
1845
1846
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;

1847
1848
1849
// 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.
bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *pblock) {
1850
    assert(pindexNew->pprev == chainActive.Tip());
1851
    mempool.check(pcoinsTip);
1852
    // Read block from disk.
1853
    int64_t nTime1 = GetTimeMicros();
1854
    CBlock block;
1855
1856
    if (!pblock) {
        if (!ReadBlockFromDisk(block, pindexNew))
1857
            return state.Abort("Failed to read block");
1858
1859
        pblock = &block;
    }
1860
    // Apply the block atomically to the chain state.
1861
1862
1863
    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
1864
    {
1865
        CCoinsViewCache view(pcoinsTip);
1866
        CInv inv(MSG_BLOCK, pindexNew->GetBlockHash());
1867
        if (!ConnectBlock(*pblock, state, pindexNew, view)) {
1868
1869
1870
            if (state.IsInvalid())
                InvalidBlockFound(pindexNew, state);
            return error("ConnectTip() : ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
1871
        }
1872
        mapBlockSource.erase(inv.hash);
1873
1874
        nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
        LogPrint("bench", "  - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
1875
        assert(view.Flush());
s_nakamoto's avatar
s_nakamoto committed
1876
    }
1877
1878
    int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
    LogPrint("bench", "  - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001);
1879
1880
1881
    // Write the chain state to disk, if necessary.
    if (!WriteChainState(state))
        return false;
1882
1883
    int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
    LogPrint("bench", "  - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001);
1884
    // Remove conflicting transactions from the mempool.
Gavin Andresen's avatar
Gavin Andresen committed
1885
    list<CTransaction> txConflicted;
1886
    mempool.removeForBlock(pblock->vtx, pindexNew->nHeight, txConflicted);
1887
1888
1889
    mempool.check(pcoinsTip);
    // Update chainActive & related variables.
    UpdateTip(pindexNew);
Gavin Andresen's avatar
Gavin Andresen committed
1890
1891
1892
    // Tell wallet about transactions that went from mempool
    // to conflicted:
    BOOST_FOREACH(const CTransaction &tx, txConflicted) {
1893
        SyncWithWallets(tx, NULL);
Gavin Andresen's avatar
Gavin Andresen committed
1894
1895
    }
    // ... and about transactions that got confirmed:
1896
1897
    BOOST_FOREACH(const CTransaction &tx, pblock->vtx) {
        SyncWithWallets(tx, pblock);
Gavin Andresen's avatar
Gavin Andresen committed
1898
    }
1899
1900
1901
1902
1903
    // Update best block in wallet (so we can detect restored wallets)
    // Emit this signal after the SyncWithWallets signals as the wallet relies on that everything up to this point has been synced
    if ((chainActive.Height() % 20160) == 0 || ((chainActive.Height() % 144) == 0 && !IsInitialBlockDownload()))
        g_signals.SetBestChain(chainActive.GetLocator());

1904
1905
1906
    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
1907
1908
1909
    return true;
}

1910
// Return the tip of the chain with the most work in it, that isn't
1911
// known to be invalid (it's however far from certain to be valid).
1912
static CBlockIndex* FindMostWorkChain() {
1913
    do {
1914
1915
        CBlockIndex *pindexNew = NULL;

1916
1917
        // Find the best candidate header.
        {
1918
1919
            std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexCandidates.rbegin();
            if (it == setBlockIndexCandidates.rend())
1920
                return NULL;
1921
1922
1923
1924
1925
1926
1927
1928
            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
1929
1930
            assert(pindexTest->nStatus & BLOCK_HAVE_DATA);
            assert(pindexTest->nChainTx || pindexTest->nHeight == 0);
1931
            if (pindexTest->nStatus & BLOCK_FAILED_MASK) {
1932
1933
                // Candidate has an invalid ancestor, remove entire chain from the set.
                if (pindexBestInvalid == NULL || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
1934
1935
                    pindexBestInvalid = pindexNew;
                CBlockIndex *pindexFailed = pindexNew;
1936
1937
                while (pindexTest != pindexFailed) {
                    pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
1938
                    setBlockIndexCandidates.erase(pindexFailed);
1939
1940
                    pindexFailed = pindexFailed->pprev;
                }
1941
                setBlockIndexCandidates.erase(pindexTest);
1942
1943
                fInvalidAncestor = true;
                break;
Pieter Wuille's avatar
Pieter Wuille committed
1944
            }
1945
            pindexTest = pindexTest->pprev;
s_nakamoto's avatar
s_nakamoto committed
1946
        }
1947
1948
        if (!fInvalidAncestor)
            return pindexNew;
1949
1950
    } while(true);
}
s_nakamoto's avatar
s_nakamoto committed
1951

1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
// Delete all entries in setBlockIndexCandidates that are worse than the current tip.
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();
    while (setBlockIndexCandidates.value_comp()(*it, chainActive.Tip())) {
        setBlockIndexCandidates.erase(it++);
    }
}

1962
// Try to make some progress towards making pindexMostWork the active block.
1963
1964
// pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork.
static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, CBlock *pblock) {
1965
    AssertLockHeld(cs_main);
1966
    bool fInvalidFound = false;
1967
1968
    const CBlockIndex *pindexOldTip = chainActive.Tip();
    const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork);
s_nakamoto's avatar
s_nakamoto committed
1969

1970
1971
1972
1973
1974
    // Disconnect active blocks which are no longer in the best chain.
    while (chainActive.Tip() && chainActive.Tip() != pindexFork) {
        if (!DisconnectTip(state))
            return false;
    }
1975

1976
1977
    // Build list of new blocks to connect.
    std::vector<CBlockIndex*> vpindexToConnect;
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
    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) {
1988
1989
        vpindexToConnect.push_back(pindexIter);
        pindexIter = pindexIter->pprev;
1990
    }
1991
    nHeight = nTargetHeight;
1992

1993
1994
    // Connect new blocks.
    BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) {
1995
        if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) {
1996
1997
1998
1999
2000
            if (state.IsInvalid()) {
                // The block violates a consensus rule.
                if (!state.CorruptionPossible())
                    InvalidChainFound(vpindexToConnect.back());
                state = CValidationState();
2001
                fInvalidFound = true;
2002
                fContinue = false;
2003
2004
2005
2006
2007
2008
                break;
            } else {
                // A system error occurred (disk space, database error, ...).
                return false;
            }
        } else {
2009
            PruneBlockIndexCandidates();
2010
2011
            // Either the current tip or a successor of it we're working towards is left in setBlockIndexCandidates.
            assert(!setBlockIndexCandidates.empty());
2012
2013
            if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) {
                // We're in a better position than we were. Return temporarily to release the lock.
2014
                fContinue = false;
2015
                break;
2016
2017
            }
        }
2018
    }
2019
    }
s_nakamoto's avatar
s_nakamoto committed
2020

2021
2022
2023
2024
2025
2026
2027
    // Callbacks/notifications for a new best chain.
    if (fInvalidFound)
        CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
    else
        CheckForkWarningConditions();

    if (!pblocktree->Flush())
2028
        return state.Abort("Failed to sync block index");
Pieter Wuille's avatar
Pieter Wuille committed
2029

s_nakamoto's avatar
s_nakamoto committed
2030
2031
2032
    return true;
}

2033
2034
2035
2036
// 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).
bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
2037
2038
    CBlockIndex *pindexNewTip = NULL;
    CBlockIndex *pindexMostWork = NULL;
2039
2040
2041
    do {
        boost::this_thread::interruption_point();

2042
2043
2044
2045
        bool fInitialDownload;
        {
            LOCK(cs_main);
            pindexMostWork = FindMostWorkChain();
2046

2047
2048
2049
            // Whether we have anything to do at all.
            if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip())
                return true;
2050

2051
            if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL))
2052
                return false;
2053

2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
            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();
2064
            {
2065
2066
2067
2068
                LOCK(cs_vNodes);
                BOOST_FOREACH(CNode* pnode, vNodes)
                    if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
                        pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip));
2069
            }
2070
2071

            uiInterface.NotifyBlockTip(hashNewTip);
2072
2073
        }
    } while(pindexMostWork != chainActive.Tip());
2074
2075
2076

    return true;
}
2077

Pieter Wuille's avatar
Pieter Wuille committed
2078
CBlockIndex* AddToBlockIndex(const CBlockHeader& block)
s_nakamoto's avatar
s_nakamoto committed
2079
2080
{
    // Check for duplicate
2081
    uint256 hash = block.GetHash();
2082
    BlockMap::iterator it = mapBlockIndex.find(hash);
2083
2084
    if (it != mapBlockIndex.end())
        return it->second;
s_nakamoto's avatar
s_nakamoto committed
2085
2086

    // Construct new block index object
2087
    CBlockIndex* pindexNew = new CBlockIndex(block);
2088
    assert(pindexNew);
Pieter Wuille's avatar
Pieter Wuille committed
2089
2090
2091
2092
    // 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;
2093
    BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
s_nakamoto's avatar
s_nakamoto committed
2094
    pindexNew->phashBlock = &((*mi).first);
2095
    BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock);
s_nakamoto's avatar
s_nakamoto committed
2096
2097
2098
2099
    if (miPrev != mapBlockIndex.end())
    {
        pindexNew->pprev = (*miPrev).second;
        pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
2100
        pindexNew->BuildSkip();
s_nakamoto's avatar
s_nakamoto committed
2101
    }
2102
    pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + pindexNew->GetBlockWork();
2103
    pindexNew->RaiseValidity(BLOCK_VALID_TREE);
Pieter Wuille's avatar
Pieter Wuille committed
2104
2105
2106
2107
2108
    if (pindexBestHeader == NULL || pindexBestHeader->nChainWork < pindexNew->nChainWork)
        pindexBestHeader = pindexNew;

    // Ok if it fails, we'll download the header again next time.
    pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexNew));
2109
2110
2111
2112
2113
2114
2115
2116

    return pindexNew;
}

// Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS).
bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos)
{
    pindexNew->nTx = block.vtx.size();
Pieter Wuille's avatar
Pieter Wuille committed
2117
    pindexNew->nChainTx = 0;
2118
2119
    pindexNew->nFile = pos.nFile;
    pindexNew->nDataPos = pos.nPos;
Pieter Wuille's avatar
Pieter Wuille committed
2120
    pindexNew->nUndoPos = 0;
2121
    pindexNew->nStatus |= BLOCK_HAVE_DATA;
Pieter Wuille's avatar
Pieter Wuille committed
2122
2123
2124
2125
2126
    pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
    {
         LOCK(cs_nBlockSequenceId);
         pindexNew->nSequenceId = nBlockSequenceId++;
    }
2127

Pieter Wuille's avatar
Pieter Wuille committed
2128
2129
2130
2131
    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
2132

Pieter Wuille's avatar
Pieter Wuille committed
2133
2134
2135
2136
2137
        // 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;
2138
            setBlockIndexCandidates.insert(pindex);
Pieter Wuille's avatar
Pieter Wuille committed
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
            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);
            }
            if (!pblocktree->WriteBlockIndex(CDiskBlockIndex(pindex)))
                return state.Abort("Failed to write block index");
        }
    } else {
        if (pindexNew->pprev && pindexNew->pprev->IsValid(BLOCK_VALID_TREE)) {
            mapBlocksUnlinked.insert(std::make_pair(pindexNew->pprev, pindexNew));
        }
        if (!pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexNew)))
            return state.Abort("Failed to write block index");
    }
s_nakamoto's avatar
s_nakamoto committed
2156

2157
    return true;
s_nakamoto's avatar
s_nakamoto committed
2158
2159
}

2160
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
2161
2162
2163
2164
2165
{
    bool fUpdatedLast = false;

    LOCK(cs_LastBlockFile);

2166
2167
2168
2169
2170
2171
2172
2173
    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());
2174
            FlushBlockFile(true);
2175
2176
2177
2178
            nFile++;
            if (vinfoBlockFile.size() <= nFile) {
                vinfoBlockFile.resize(nFile + 1);
            }
2179
2180
            fUpdatedLast = true;
        }
2181
2182
        pos.nFile = nFile;
        pos.nPos = vinfoBlockFile[nFile].nSize;
Pieter Wuille's avatar
Pieter Wuille committed
2183
2184
    }

2185
2186
2187
    nLastBlockFile = nFile;
    vinfoBlockFile[nFile].nSize += nAddSize;
    vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
Pieter Wuille's avatar
Pieter Wuille committed
2188

2189
2190
    if (!fKnown) {
        unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
2191
        unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
2192
        if (nNewChunks > nOldChunks) {
2193
2194
2195
            if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) {
                FILE *file = OpenBlockFile(pos);
                if (file) {
2196
                    LogPrintf("Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile);
2197
2198
2199
                    AllocateFileRange(file, pos.nPos, nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos);
                    fclose(file);
                }
2200
            }
2201
            else
2202
                return state.Error("out of disk space");
2203
2204
2205
        }
    }

2206
    if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, vinfoBlockFile[nFile]))
2207
        return state.Abort("Failed to write file info");
Pieter Wuille's avatar
Pieter Wuille committed
2208
    if (fUpdatedLast)
2209
        pblocktree->WriteLastBlockFile(nLastBlockFile);
Pieter Wuille's avatar
Pieter Wuille committed
2210
2211
2212
2213

    return true;
}

Pieter Wuille's avatar
Pieter Wuille committed
2214
bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize)
Pieter Wuille's avatar
Pieter Wuille committed
2215
2216
2217
2218
2219
{
    pos.nFile = nFile;

    LOCK(cs_LastBlockFile);

2220
    unsigned int nNewSize;
2221
2222
2223
2224
    pos.nPos = vinfoBlockFile[nFile].nUndoSize;
    nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize;
    if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, vinfoBlockFile[nLastBlockFile])) {
        return state.Abort("Failed to write block info");
2225
2226
2227
2228
2229
    }

    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) {
2230
2231
2232
        if (CheckDiskSpace(nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos)) {
            FILE *file = OpenUndoFile(pos);
            if (file) {
2233
                LogPrintf("Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile);
2234
2235
2236
                AllocateFileRange(file, pos.nPos, nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos);
                fclose(file);
            }
2237
        }
2238
        else
2239
            return state.Error("out of disk space");
Pieter Wuille's avatar
Pieter Wuille committed
2240
2241
2242
2243
2244
    }

    return true;
}

2245
bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW)
s_nakamoto's avatar
s_nakamoto committed
2246
{
2247
    // Check proof of work matches claimed amount
2248
    if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits))
2249
        return state.DoS(50, error("CheckBlockHeader() : proof of work failed"),
2250
                         REJECT_INVALID, "high-hash");
2251

s_nakamoto's avatar
s_nakamoto committed
2252
    // Check timestamp
2253
    if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
2254
        return state.Invalid(error("CheckBlockHeader() : block timestamp too far in the future"),
2255
                             REJECT_INVALID, "time-too-new");
s_nakamoto's avatar
s_nakamoto committed
2256

2257
2258
2259
    return true;
}

2260
bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot)
s_nakamoto's avatar
s_nakamoto committed
2261
{
Pieter Wuille's avatar
Pieter Wuille committed
2262
    // These are checks that are independent of context.
s_nakamoto's avatar
s_nakamoto committed
2263

2264
2265
2266
    if (!CheckBlockHeader(block, state, fCheckPOW))
        return false;

Pieter Wuille's avatar
Pieter Wuille committed
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
    // 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
2287
    // Size limits
2288
    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
2289
        return state.DoS(100, error("CheckBlock() : size limits failed"),
2290
                         REJECT_INVALID, "bad-blk-length");
s_nakamoto's avatar
s_nakamoto committed
2291
2292

    // First transaction must be coinbase, the rest must not be
2293
    if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
Gavin Andresen's avatar
Gavin Andresen committed
2294
        return state.DoS(100, error("CheckBlock() : first tx is not coinbase"),
2295
                         REJECT_INVALID, "bad-cb-missing");
2296
2297
    for (unsigned int i = 1; i < block.vtx.size(); i++)
        if (block.vtx[i].IsCoinBase())
Gavin Andresen's avatar
Gavin Andresen committed
2298
            return state.DoS(100, error("CheckBlock() : more than one coinbase"),
2299
                             REJECT_INVALID, "bad-cb-multiple");
s_nakamoto's avatar
s_nakamoto committed
2300
2301

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

2306
    unsigned int nSigOps = 0;
2307
    BOOST_FOREACH(const CTransaction& tx, block.vtx)
Gavin Andresen's avatar
Gavin Andresen committed
2308
    {
2309
        nSigOps += GetLegacySigOpCount(tx);
Gavin Andresen's avatar
Gavin Andresen committed
2310
2311
    }
    if (nSigOps > MAX_BLOCK_SIGOPS)
Gavin Andresen's avatar
Gavin Andresen committed
2312
        return state.DoS(100, error("CheckBlock() : out-of-bounds SigOpCount"),
2313
                         REJECT_INVALID, "bad-blk-sigops", true);
s_nakamoto's avatar
s_nakamoto committed
2314
2315
2316
2317

    return true;
}

Pieter Wuille's avatar
Pieter Wuille committed
2318
bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex)
s_nakamoto's avatar
s_nakamoto committed
2319
{
2320
    AssertLockHeld(cs_main);
s_nakamoto's avatar
s_nakamoto committed
2321
    // Check for duplicate
2322
    uint256 hash = block.GetHash();
2323
    BlockMap::iterator miSelf = mapBlockIndex.find(hash);
2324
2325
    CBlockIndex *pindex = NULL;
    if (miSelf != mapBlockIndex.end()) {
Pieter Wuille's avatar
Pieter Wuille committed
2326
        // Block header is already known.
2327
        pindex = miSelf->second;
Pieter Wuille's avatar
Pieter Wuille committed
2328
2329
        if (ppindex)
            *ppindex = pindex;
2330
        if (pindex->nStatus & BLOCK_FAILED_MASK)
2331
            return state.Invalid(error("%s : block is marked invalid", __func__), 0, "duplicate");
Pieter Wuille's avatar
Pieter Wuille committed
2332
        return true;
2333
    }
s_nakamoto's avatar
s_nakamoto committed
2334
2335

    // Get prev block index
2336
2337
    CBlockIndex* pindexPrev = NULL;
    int nHeight = 0;
2338
    if (hash != Params().HashGenesisBlock()) {
2339
        BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
2340
        if (mi == mapBlockIndex.end())
2341
            return state.DoS(10, error("%s : prev block not found", __func__), 0, "bad-prevblk");
2342
2343
2344
2345
        pindexPrev = (*mi).second;
        nHeight = pindexPrev->nHeight+1;

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

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

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

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

2366
        // Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
2367
2368
        if (block.nVersion < 2 && 
            CBlockIndex::IsSuperMajority(2, pindexPrev, Params().RejectBlockOutdatedMajority()))
2369
        {
2370
            return state.Invalid(error("%s : rejected nVersion=1 block", __func__),
2371
                                 REJECT_OBSOLETE, "bad-version");
2372
        }
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
    }

    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
2393
2394
2395
2396
2397
2398
    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;
    }

2399
    if (!CheckBlock(block, state)) {
2400
        if (state.IsInvalid() && !state.CorruptionPossible()) {
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
            pindex->nStatus |= BLOCK_FAILED_VALID;
        }
        return false;
    }

    int nHeight = pindex->nHeight;

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

    // Enforce block.nVersion=2 rule that the coinbase starts with serialized block height
2417
2418
2419
    // if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet):
    if (block.nVersion >= 2 && 
        CBlockIndex::IsSuperMajority(2, pindex->pprev, Params().EnforceBlockUpgradeMajority()))
2420
    {
2421
2422
2423
2424
2425
        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())) {
            pindex->nStatus |= BLOCK_FAILED_VALID;
            return state.DoS(100, error("AcceptBlock() : block height mismatch in coinbase"), REJECT_INVALID, "bad-cb-height");
2426
2427
2428
        }
    }

s_nakamoto's avatar
s_nakamoto committed
2429
    // Write block to history file
Pieter Wuille's avatar
Pieter Wuille committed
2430
    try {
2431
        unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
Pieter Wuille's avatar
Pieter Wuille committed
2432
2433
2434
        CDiskBlockPos blockPos;
        if (dbp != NULL)
            blockPos = *dbp;
jtimon's avatar
jtimon committed
2435
        if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL))
Pieter Wuille's avatar
Pieter Wuille committed
2436
2437
            return error("AcceptBlock() : FindBlockPos failed");
        if (dbp == NULL)
2438
            if (!WriteBlockToDisk(block, blockPos))
2439
                return state.Abort("Failed to write block");
2440
2441
        if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
            return error("AcceptBlock() : ReceivedBlockTransactions failed");
Pieter Wuille's avatar
Pieter Wuille committed
2442
    } catch(std::runtime_error &e) {
2443
        return state.Abort(std::string("System error: ") + e.what());
Pieter Wuille's avatar
Pieter Wuille committed
2444
    }
s_nakamoto's avatar
s_nakamoto committed
2445
2446
2447
2448

    return true;
}

2449
bool CBlockIndex::IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired)
2450
{
2451
    unsigned int nToCheck = Params().ToCheckBlockUpgradeMajority();
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
    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);
}

2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
/** 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));
}

Pieter Wuille's avatar
Pieter Wuille committed
2511
bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp)
s_nakamoto's avatar
s_nakamoto committed
2512
2513
{
    // Preliminary checks
Pieter Wuille's avatar
Pieter Wuille committed
2514
    bool checked = CheckBlock(*pblock, state);
s_nakamoto's avatar
s_nakamoto committed
2515
2516

    {
Pieter Wuille's avatar
Pieter Wuille committed
2517
2518
2519
2520
        LOCK(cs_main);
        MarkBlockAsReceived(pblock->GetHash());
        if (!checked) {
            return error("ProcessBlock() : CheckBlock FAILED");
2521
        }
s_nakamoto's avatar
s_nakamoto committed
2522

Pieter Wuille's avatar
Pieter Wuille committed
2523
2524
2525
2526
2527
        // 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
2528
        }
Pieter Wuille's avatar
Pieter Wuille committed
2529
2530
        if (!ret)
            return error("ProcessBlock() : AcceptBlock FAILED");
2531
2532
    }

2533
    if (!ActivateBestChain(state, pblock))
2534
2535
        return error("ProcessBlock() : ActivateBestChain failed");

s_nakamoto's avatar
s_nakamoto committed
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
    return true;
}








2546
2547
2548
2549
CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter& filter)
{
    header = block.GetBlockHeader();

2550
2551
2552
2553
2554
2555
2556
    vector<bool> vMatch;
    vector<uint256> vHashes;

    vMatch.reserve(block.vtx.size());
    vHashes.reserve(block.vtx.size());

    for (unsigned int i = 0; i < block.vtx.size(); i++)
2557
    {
2558
2559
        const uint256& hash = block.vtx[i].GetHash();
        if (filter.IsRelevantAndUpdate(block.vtx[i]))
2560
        {
2561
2562
            vMatch.push_back(true);
            vMatchedTxn.push_back(make_pair(i, hash));
2563
        }
2564
2565
2566
        else
            vMatch.push_back(false);
        vHashes.push_back(hash);
2567
    }
2568
2569

    txn = CPartialMerkleTree(vHashes, vMatch);
2570
2571
2572
2573
2574
2575
2576
2577
2578
}








Pieter Wuille's avatar
Pieter Wuille committed
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::vector<uint256> &vTxid) {
    if (height == 0) {
        // hash at height 0 is the txids themself
        return vTxid[pos];
    } else {
        // calculate left hash
        uint256 left = CalcHash(height-1, pos*2, vTxid), right;
        // calculate right hash if not beyong the end of the array - copy left hash otherwise1
        if (pos*2+1 < CalcTreeWidth(height-1))
            right = CalcHash(height-1, pos*2+1, vTxid);
        else
            right = left;
        // combine subhashes
        return Hash(BEGIN(left), END(left), BEGIN(right), END(right));
    }
}

void CPartialMerkleTree::TraverseAndBuild(int height, unsigned int pos, const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) {
    // determine whether this node is the parent of at least one matched txid
    bool fParentOfMatch = false;
    for (unsigned int p = pos << height; p < (pos+1) << height && p < nTransactions; p++)
        fParentOfMatch |= vMatch[p];
    // store as flag bit
    vBits.push_back(fParentOfMatch);
    if (height==0 || !fParentOfMatch) {
        // if at height 0, or nothing interesting below, store hash and stop
        vHash.push_back(CalcHash(height, pos, vTxid));
    } else {
        // otherwise, don't store any hash, but descend into the subtrees
        TraverseAndBuild(height-1, pos*2, vTxid, vMatch);
        if (pos*2+1 < CalcTreeWidth(height-1))
            TraverseAndBuild(height-1, pos*2+1, vTxid, vMatch);
    }
}

uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<uint256> &vMatch) {
    if (nBitsUsed >= vBits.size()) {
        // overflowed the bits array - failure
        fBad = true;
        return 0;
    }
    bool fParentOfMatch = vBits[nBitsUsed++];
    if (height==0 || !fParentOfMatch) {
        // if at height 0, or nothing interesting below, use stored hash and do not descend
        if (nHashUsed >= vHash.size()) {
            // overflowed the hash array - failure
            fBad = true;
            return 0;
        }
        const uint256 &hash = vHash[nHashUsed++];
        if (height==0 && fParentOfMatch) // in case of height 0, we have a matched txid
            vMatch.push_back(hash);
        return hash;
    } else {
        // otherwise, descend into the subtrees to extract matched txids and hashes
        uint256 left = TraverseAndExtract(height-1, pos*2, nBitsUsed, nHashUsed, vMatch), right;
        if (pos*2+1 < CalcTreeWidth(height-1))
            right = TraverseAndExtract(height-1, pos*2+1, nBitsUsed, nHashUsed, vMatch);
        else
            right = left;
        // and combine them before returning
        return Hash(BEGIN(left), END(left), BEGIN(right), END(right));
    }
}

CPartialMerkleTree::CPartialMerkleTree(const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) : nTransactions(vTxid.size()), fBad(false) {
    // reset state
    vBits.clear();
    vHash.clear();

    // calculate height of tree
    int nHeight = 0;
    while (CalcTreeWidth(nHeight) > 1)
        nHeight++;

    // traverse the partial tree
    TraverseAndBuild(nHeight, 0, vTxid, vMatch);
}

CPartialMerkleTree::CPartialMerkleTree() : nTransactions(0), fBad(true) {}

uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) {
    vMatch.clear();
    // An empty set will not work
    if (nTransactions == 0)
        return 0;
    // check for excessively high numbers of transactions
    if (nTransactions > MAX_BLOCK_SIZE / 60) // 60 is the lower bound for the size of a serialized CTransaction
        return 0;
    // there can never be more hashes provided than one for every txid
    if (vHash.size() > nTransactions)
        return 0;
    // there must be at least one bit per node in the partial tree, and at least one node per hash
    if (vBits.size() < vHash.size())
        return 0;
    // calculate height of tree
    int nHeight = 0;
    while (CalcTreeWidth(nHeight) > 1)
        nHeight++;
    // traverse the partial tree
    unsigned int nBitsUsed = 0, nHashUsed = 0;
    uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch);
    // verify that no problems occured during the tree traversal
    if (fBad)
        return 0;
    // verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence)
    if ((nBitsUsed+7)/8 != (vBits.size()+7)/8)
        return 0;
    // verify that all hashes were consumed
    if (nHashUsed != vHash.size())
        return 0;
    return hashMerkleRoot;
}







2699
bool AbortNode(const std::string &strMessage, const std::string &userMessage) {
2700
    strMiscWarning = strMessage;
2701
    LogPrintf("*** %s\n", strMessage);
2702
2703
2704
    uiInterface.ThreadSafeMessageBox(
        userMessage.empty() ? _("Error: A fatal internal error occured, see debug.log for details") : userMessage,
        "", CClientUIInterface::MSG_ERROR);
2705
2706
2707
    StartShutdown();
    return false;
}
Pieter Wuille's avatar
Pieter Wuille committed
2708

2709
bool CheckDiskSpace(uint64_t nAdditionalBytes)
s_nakamoto's avatar
s_nakamoto committed
2710
{
2711
    uint64_t nFreeBytesAvailable = filesystem::space(GetDataDir()).available;
s_nakamoto's avatar
s_nakamoto committed
2712

2713
2714
    // Check for nMinDiskSpace bytes (currently 50MB)
    if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
2715
        return AbortNode("Disk space is low!", _("Error: Disk space is low!"));
2716

s_nakamoto's avatar
s_nakamoto committed
2717
2718
2719
    return true;
}

Pieter Wuille's avatar
Pieter Wuille committed
2720
FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly)
2721
{
Pieter Wuille's avatar
Pieter Wuille committed
2722
    if (pos.IsNull())
s_nakamoto's avatar
s_nakamoto committed
2723
        return NULL;
2724
    boost::filesystem::path path = GetBlockPosFilename(pos, prefix);
Pieter Wuille's avatar
Pieter Wuille committed
2725
2726
2727
2728
    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
2729
    if (!file) {
2730
        LogPrintf("Unable to open file %s\n", path.string());
s_nakamoto's avatar
s_nakamoto committed
2731
        return NULL;
Pieter Wuille's avatar
Pieter Wuille committed
2732
    }
Pieter Wuille's avatar
Pieter Wuille committed
2733
2734
    if (pos.nPos) {
        if (fseek(file, pos.nPos, SEEK_SET)) {
2735
            LogPrintf("Unable to seek to position %u of %s\n", pos.nPos, path.string());
Pieter Wuille's avatar
Pieter Wuille committed
2736
2737
2738
2739
            fclose(file);
            return NULL;
        }
    }
s_nakamoto's avatar
s_nakamoto committed
2740
2741
2742
    return file;
}

Pieter Wuille's avatar
Pieter Wuille committed
2743
2744
2745
2746
FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly) {
    return OpenDiskFile(pos, "blk", fReadOnly);
}

2747
FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly) {
Pieter Wuille's avatar
Pieter Wuille committed
2748
2749
2750
    return OpenDiskFile(pos, "rev", fReadOnly);
}

2751
2752
boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix)
{
Suhas Daftuar's avatar
Suhas Daftuar committed
2753
    return GetDataDir() / "blocks" / strprintf("%s%05u.dat", prefix, pos.nFile);
2754
2755
}

2756
2757
2758
2759
2760
2761
CBlockIndex * InsertBlockIndex(uint256 hash)
{
    if (hash == 0)
        return NULL;

    // Return existing
2762
    BlockMap::iterator mi = mapBlockIndex.find(hash);
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
    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
2781
    boost::this_thread::interruption_point();
2782

Pieter Wuille's avatar
Pieter Wuille committed
2783
    // Calculate nChainWork
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
    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;
2795
        pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + pindex->GetBlockWork();
Pieter Wuille's avatar
Pieter Wuille committed
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
        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))
2809
            setBlockIndexCandidates.insert(pindex);
2810
2811
        if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->nChainWork > pindexBestInvalid->nChainWork))
            pindexBestInvalid = pindex;
2812
2813
        if (pindex->pprev)
            pindex->BuildSkip();
Pieter Wuille's avatar
Pieter Wuille committed
2814
2815
        if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == NULL || CBlockIndexWorkComparator()(pindexBestHeader, pindex)))
            pindexBestHeader = pindex;
2816
2817
2818
2819
    }

    // Load block file info
    pblocktree->ReadLastBlockFile(nLastBlockFile);
2820
    vinfoBlockFile.resize(nLastBlockFile + 1);
2821
    LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile);
2822
2823
2824
    for (int nFile = 0; nFile <= nLastBlockFile; nFile++) {
        pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
    }
2825
    LogPrintf("%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString());
2826
2827
2828
2829
2830
2831
2832
2833
    for (int nFile = nLastBlockFile + 1; true; nFile++) {
        CBlockFileInfo info;
        if (pblocktree->ReadBlockFileInfo(nFile, info)) {
            vinfoBlockFile.push_back(info);
        } else {
            break;
        }
    }
2834

2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
    // 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);
2848
        if (CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION).IsNull()) {
2849
2850
2851
2852
            return false;
        }
    }

2853
2854
2855
2856
2857
    // Check whether we need to continue reindexing
    bool fReindexing = false;
    pblocktree->ReadReindexing(fReindexing);
    fReindex |= fReindexing;

2858
2859
    // Check whether we have a transaction index
    pblocktree->ReadFlag("txindex", fTxIndex);
2860
    LogPrintf("LoadBlockIndexDB(): transaction index %s\n", fTxIndex ? "enabled" : "disabled");
2861

2862
    // Load pointer to end of best chain
2863
    BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
2864
    if (it == mapBlockIndex.end())
2865
        return true;
2866
    chainActive.SetTip(it->second);
2867
2868
2869

    PruneBlockIndexCandidates();

2870
    LogPrintf("LoadBlockIndexDB(): hashBestChain=%s height=%d date=%s progress=%f\n",
2871
        chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(),
2872
2873
        DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
        Checkpoints::GuessVerificationProgress(chainActive.Tip()));
2874

Pieter Wuille's avatar
Pieter Wuille committed
2875
2876
2877
    return true;
}

Cozz Lovan's avatar
Cozz Lovan committed
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
CVerifyDB::CVerifyDB()
{
    uiInterface.ShowProgress(_("Verifying blocks..."), 0);
}

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

2888
bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth)
2889
{
2890
    LOCK(cs_main);
2891
    if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL)
Pieter Wuille's avatar
Pieter Wuille committed
2892
2893
        return true;

2894
    // Verify blocks in the best chain
2895
    if (nCheckDepth <= 0)
2896
        nCheckDepth = 1000000000; // suffices until the year 19000
2897
2898
    if (nCheckDepth > chainActive.Height())
        nCheckDepth = chainActive.Height();
Pieter Wuille's avatar
Pieter Wuille committed
2899
    nCheckLevel = std::max(0, std::min(4, nCheckLevel));
2900
    LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
2901
    CCoinsViewCache coins(coinsview);
2902
    CBlockIndex* pindexState = chainActive.Tip();
Pieter Wuille's avatar
Pieter Wuille committed
2903
2904
    CBlockIndex* pindexFailure = NULL;
    int nGoodTransactions = 0;
Pieter Wuille's avatar
Pieter Wuille committed
2905
    CValidationState state;
2906
    for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev)
2907
    {
Gavin Andresen's avatar
Gavin Andresen committed
2908
        boost::this_thread::interruption_point();
Cozz Lovan's avatar
Cozz Lovan committed
2909
        uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100)))));
2910
        if (pindex->nHeight < chainActive.Height()-nCheckDepth)
2911
2912
            break;
        CBlock block;
Pieter Wuille's avatar
Pieter Wuille committed
2913
        // check level 0: read from disk
2914
        if (!ReadBlockFromDisk(block, pindex))
2915
            return error("VerifyDB() : *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
2916
        // check level 1: verify block validity
2917
        if (nCheckLevel >= 1 && !CheckBlock(block, state))
2918
            return error("VerifyDB() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
Pieter Wuille's avatar
Pieter Wuille committed
2919
2920
2921
2922
2923
2924
        // 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()))
2925
                    return error("VerifyDB() : *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
Pieter Wuille's avatar
Pieter Wuille committed
2926
2927
2928
            }
        }
        // check level 3: check for inconsistencies during memory-only disconnect of tip blocks
2929
        if (nCheckLevel >= 3 && pindex == pindexState && (coins.GetCacheSize() + pcoinsTip->GetCacheSize()) <= nCoinCacheSize) {
Pieter Wuille's avatar
Pieter Wuille committed
2930
            bool fClean = true;
2931
            if (!DisconnectBlock(block, state, pindex, coins, &fClean))
2932
                return error("VerifyDB() : *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
Pieter Wuille's avatar
Pieter Wuille committed
2933
2934
2935
2936
2937
2938
            pindexState = pindex->pprev;
            if (!fClean) {
                nGoodTransactions = 0;
                pindexFailure = pindex;
            } else
                nGoodTransactions += block.vtx.size();
2939
2940
        }
    }
Pieter Wuille's avatar
Pieter Wuille committed
2941
    if (pindexFailure)
2942
        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
2943
2944
2945
2946

    // check level 4: try reconnecting blocks
    if (nCheckLevel >= 4) {
        CBlockIndex *pindex = pindexState;
2947
        while (pindex != chainActive.Tip()) {
Gavin Andresen's avatar
Gavin Andresen committed
2948
            boost::this_thread::interruption_point();
Cozz Lovan's avatar
Cozz Lovan committed
2949
            uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50))));
2950
            pindex = chainActive.Next(pindex);
2951
            CBlock block;
2952
            if (!ReadBlockFromDisk(block, pindex))
2953
                return error("VerifyDB() : *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
2954
            if (!ConnectBlock(block, state, pindex, coins))
2955
                return error("VerifyDB() : *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
Pieter Wuille's avatar
Pieter Wuille committed
2956
        }
2957
2958
    }

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

2961
2962
2963
    return true;
}

2964
2965
2966
void UnloadBlockIndex()
{
    mapBlockIndex.clear();
2967
    setBlockIndexCandidates.clear();
2968
    chainActive.SetTip(NULL);
2969
    pindexBestInvalid = NULL;
2970
2971
}

2972
bool LoadBlockIndex()
s_nakamoto's avatar
s_nakamoto committed
2973
{
2974
    // Load block index from databases
2975
    if (!fReindex && !LoadBlockIndexDB())
s_nakamoto's avatar
s_nakamoto committed
2976
        return false;
2977
2978
    return true;
}
2979
2980


2981
bool InitBlockIndex() {
2982
    LOCK(cs_main);
2983
    // Check whether we're already initialized
2984
    if (chainActive.Genesis() != NULL)
2985
2986
2987
2988
2989
        return true;

    // Use the provided setting for -txindex in the new database
    fTxIndex = GetBoolArg("-txindex", false);
    pblocktree->WriteFlag("txindex", fTxIndex);
2990
    LogPrintf("Initializing databases...\n");
2991
2992
2993
2994

    // Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
    if (!fReindex) {
        try {
2995
2996
            CBlock &block = const_cast<CBlock&>(Params().GenesisBlock());
            // Start new block file
2997
2998
2999
            unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
            CDiskBlockPos blockPos;
            CValidationState state;
jtimon's avatar
jtimon committed
3000
            if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.GetBlockTime()))
3001
                return error("LoadBlockIndex() : FindBlockPos failed");
3002
            if (!WriteBlockToDisk(block, blockPos))
3003
                return error("LoadBlockIndex() : writing genesis block to disk failed");
3004
3005
            CBlockIndex *pindex = AddToBlockIndex(block);
            if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
3006
                return error("LoadBlockIndex() : genesis block not accepted");
3007
            if (!ActivateBestChain(state, &block))
3008
                return error("LoadBlockIndex() : genesis block cannot be activated");
3009
3010
3011
        } catch(std::runtime_error &e) {
            return error("LoadBlockIndex() : failed to initialize block database: %s", e.what());
        }
s_nakamoto's avatar
s_nakamoto committed
3012
3013
3014
3015
3016
3017
3018
3019
3020
    }

    return true;
}



void PrintBlockTree()
{
3021
    AssertLockHeld(cs_main);
3022
    // pre-compute tree structure
s_nakamoto's avatar
s_nakamoto committed
3023
    map<CBlockIndex*, vector<CBlockIndex*> > mapNext;
3024
    for (BlockMap::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
s_nakamoto's avatar
s_nakamoto committed
3025
3026
3027
3028
3029
3030
3031
3032
3033
    {
        CBlockIndex* pindex = (*mi).second;
        mapNext[pindex->pprev].push_back(pindex);
        // test
        //while (rand() % 3 == 0)
        //    mapNext[pindex->pprev].push_back(pindex);
    }

    vector<pair<int, CBlockIndex*> > vStack;
3034
    vStack.push_back(make_pair(0, chainActive.Genesis()));
s_nakamoto's avatar
s_nakamoto committed
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046

    int nPrevCol = 0;
    while (!vStack.empty())
    {
        int nCol = vStack.back().first;
        CBlockIndex* pindex = vStack.back().second;
        vStack.pop_back();

        // print split or gap
        if (nCol > nPrevCol)
        {
            for (int i = 0; i < nCol-1; i++)
3047
3048
                LogPrintf("| ");
            LogPrintf("|\\\n");
s_nakamoto's avatar
s_nakamoto committed
3049
3050
3051
3052
        }
        else if (nCol < nPrevCol)
        {
            for (int i = 0; i < nCol; i++)
3053
3054
                LogPrintf("| ");
            LogPrintf("|\n");
Pieter Wuille's avatar
Pieter Wuille committed
3055
       }
s_nakamoto's avatar
s_nakamoto committed
3056
3057
3058
3059
        nPrevCol = nCol;

        // print columns
        for (int i = 0; i < nCol; i++)
3060
            LogPrintf("| ");
s_nakamoto's avatar
s_nakamoto committed
3061
3062
3063

        // print item
        CBlock block;
3064
        ReadBlockFromDisk(block, pindex);
3065
        LogPrintf("%d (blk%05u.dat:0x%x)  %s  tx %u\n",
s_nakamoto's avatar
s_nakamoto committed
3066
            pindex->nHeight,
Pieter Wuille's avatar
Pieter Wuille committed
3067
            pindex->GetBlockPos().nFile, pindex->GetBlockPos().nPos,
3068
            DateTimeStrFormat("%Y-%m-%d %H:%M:%S", block.GetBlockTime()),
s_nakamoto's avatar
s_nakamoto committed
3069
3070
            block.vtx.size());

3071
        // put the main time-chain first
s_nakamoto's avatar
s_nakamoto committed
3072
        vector<CBlockIndex*>& vNext = mapNext[pindex];
3073
        for (unsigned int i = 0; i < vNext.size(); i++)
s_nakamoto's avatar
s_nakamoto committed
3074
        {
3075
            if (chainActive.Next(vNext[i]))
s_nakamoto's avatar
s_nakamoto committed
3076
3077
3078
3079
3080
3081
3082
            {
                swap(vNext[0], vNext[i]);
                break;
            }
        }

        // iterate children
3083
        for (unsigned int i = 0; i < vNext.size(); i++)
s_nakamoto's avatar
s_nakamoto committed
3084
3085
3086
3087
            vStack.push_back(make_pair(nCol+i, vNext[i]));
    }
}

3088
bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
3089
{
3090
3091
    // Map of disk positions for blocks with unknown parent (only used for reindex)
    static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent;
3092
    int64_t nStart = GetTimeMillis();
3093

3094
    int nLoaded = 0;
Pieter Wuille's avatar
Pieter Wuille committed
3095
    try {
3096
        // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor
3097
        CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
3098
        uint64_t nRewind = blkdat.GetPos();
3099
        while (!blkdat.eof()) {
3100
3101
            boost::this_thread::interruption_point();

3102
3103
3104
            blkdat.SetPos(nRewind);
            nRewind++; // start one byte further next time, in case of failure
            blkdat.SetLimit(); // remove former limit
3105
            unsigned int nSize = 0;
3106
3107
            try {
                // locate a header
3108
                unsigned char buf[MESSAGE_START_SIZE];
3109
                blkdat.FindByte(Params().MessageStart()[0]);
3110
3111
                nRewind = blkdat.GetPos()+1;
                blkdat >> FLATDATA(buf);
3112
                if (memcmp(buf, Params().MessageStart(), MESSAGE_START_SIZE))
3113
3114
                    continue;
                // read size
3115
                blkdat >> nSize;
3116
3117
                if (nSize < 80 || nSize > MAX_BLOCK_SIZE)
                    continue;
ENikS's avatar
ENikS committed
3118
            } catch (const std::exception &) {
3119
3120
3121
3122
                // no valid block header found; don't complain
                break;
            }
            try {
3123
                // read block
3124
                uint64_t nBlockPos = blkdat.GetPos();
3125
3126
                if (dbp)
                    dbp->nPos = nBlockPos;
3127
                blkdat.SetLimit(nBlockPos + nSize);
3128
3129
3130
                blkdat.SetPos(nBlockPos);
                CBlock block;
                blkdat >> block;
3131
3132
                nRewind = blkdat.GetPos();

3133
3134
3135
                // detect out of order blocks, and store them for later
                uint256 hash = block.GetHash();
                if (hash != Params().HashGenesisBlock() && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) {
3136
                    LogPrint("reindex", "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
3137
                            block.hashPrevBlock.ToString());
3138
                    if (dbp)
3139
                        mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
3140
3141
3142
                    continue;
                }

3143
3144
3145
3146
3147
3148
3149
3150
                // process in case the block isn't known yet
                if (mapBlockIndex.count(hash) == 0) {
                    CValidationState state;
                    if (ProcessBlock(state, NULL, &block, dbp))
                        nLoaded++;
                    if (state.IsError())
                        break;
                }
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174

                // 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;
                            if (ProcessBlock(dummy, NULL, &block, &it->second))
                            {
                                nLoaded++;
                                queue.push_back(block.GetHash());
                            }
                        }
                        range.first++;
                        mapBlocksUnknownParent.erase(it);
                    }
3175
                }
3176
            } catch (std::exception &e) {
3177
                LogPrintf("%s : Deserialize or I/O error - %s", __func__, e.what());
3178
3179
            }
        }
Pieter Wuille's avatar
Pieter Wuille committed
3180
    } catch(std::runtime_error &e) {
3181
        AbortNode(std::string("System error: ") + e.what());
3182
    }
3183
    if (nLoaded > 0)
3184
        LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart);
3185
3186
    return nLoaded > 0;
}
s_nakamoto's avatar
s_nakamoto committed
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197

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

string GetWarnings(string strFor)
{
    int nPriority = 0;
    string strStatusBar;
    string strRPC;
3198

3199
    if (GetBoolArg("-testsafemode", false))
s_nakamoto's avatar
s_nakamoto committed
3200
3201
        strRPC = "test";

3202
3203
3204
    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");

s_nakamoto's avatar
s_nakamoto committed
3205
3206
3207
3208
3209
3210
3211
    // Misc warnings like out of disk space and clock is wrong
    if (strMiscWarning != "")
    {
        nPriority = 1000;
        strStatusBar = strMiscWarning;
    }

3212
    if (fLargeWorkForkFound)
s_nakamoto's avatar
s_nakamoto committed
3213
3214
    {
        nPriority = 2000;
3215
3216
3217
        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
3218
3219
    {
        nPriority = 2000;
3220
        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
3221
3222
3223
3224
    }

    // Alerts
    {
3225
        LOCK(cs_mapAlerts);
3226
        BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
s_nakamoto's avatar
s_nakamoto committed
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
        {
            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;
3241
    assert(!"GetWarnings() : invalid parameter");
s_nakamoto's avatar
s_nakamoto committed
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
    return "error";
}








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


3258
bool static AlreadyHave(const CInv& inv)
s_nakamoto's avatar
s_nakamoto committed
3259
3260
3261
{
    switch (inv.type)
    {
Jeff Garzik's avatar
Jeff Garzik committed
3262
3263
    case MSG_TX:
        {
Pieter Wuille's avatar
Pieter Wuille committed
3264
            bool txInMap = false;
3265
            txInMap = mempool.exists(inv.hash);
Pieter Wuille's avatar
Pieter Wuille committed
3266
            return txInMap || mapOrphanTransactions.count(inv.hash) ||
3267
                pcoinsTip->HaveCoins(inv.hash);
Jeff Garzik's avatar
Jeff Garzik committed
3268
3269
        }
    case MSG_BLOCK:
Pieter Wuille's avatar
Pieter Wuille committed
3270
        return mapBlockIndex.count(inv.hash);
s_nakamoto's avatar
s_nakamoto committed
3271
3272
3273
3274
3275
3276
    }
    // Don't know what it is, just say we already got one
    return true;
}


3277
3278
3279
3280
3281
3282
void static ProcessGetData(CNode* pfrom)
{
    std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();

    vector<CInv> vNotFound;

3283
3284
    LOCK(cs_main);

3285
3286
3287
3288
3289
3290
3291
    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
3292
            boost::this_thread::interruption_point();
3293
3294
3295
3296
            it++;

            if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
            {
3297
                bool send = false;
3298
                BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
3299
3300
                if (mi != mapBlockIndex.end())
                {
3301
3302
3303
                    // If the requested block is at a height below our last
                    // checkpoint, only serve it if it's in the checkpointed chain
                    int nHeight = mi->second->nHeight;
3304
                    CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint();
3305
                    if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
Philip Kaufmann's avatar
Philip Kaufmann committed
3306
3307
3308
3309
3310
3311
                        if (!chainActive.Contains(mi->second))
                        {
                            LogPrintf("ProcessGetData(): ignoring request for old block that isn't in the main chain\n");
                        } else {
                            send = true;
                        }
3312
                    } else {
Philip Kaufmann's avatar
Philip Kaufmann committed
3313
                        send = true;
3314
3315
3316
3317
3318
                    }
                }
                if (send)
                {
                    // Send block from disk
3319
                    CBlock block;
3320
3321
                    if (!ReadBlockFromDisk(block, (*mi).second))
                        assert(!"cannot load block from disk");
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
                    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;
3353
                        vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash()));
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
                        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) {
3372
3373
                    CTransaction tx;
                    if (mempool.lookup(inv.hash, tx)) {
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
                        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.
3387
            g_signals.Inventory(inv.hash);
3388

3389
3390
            if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
                break;
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
        }
    }

    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);
    }
}

3408
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
s_nakamoto's avatar
s_nakamoto committed
3409
3410
{
    RandAddSeedPerfmon();
3411
    LogPrint("net", "received: %s (%u bytes) peer=%d\n", strCommand, vRecv.size(), pfrom->id);
s_nakamoto's avatar
s_nakamoto committed
3412
3413
    if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
    {
3414
        LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
s_nakamoto's avatar
s_nakamoto committed
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
        return true;
    }




    if (strCommand == "version")
    {
        // Each connection can only send one version message
        if (pfrom->nVersion != 0)
3425
        {
Gavin Andresen's avatar
Gavin Andresen committed
3426
            pfrom->PushMessage("reject", strCommand, REJECT_DUPLICATE, string("Duplicate version message"));
Pieter Wuille's avatar
Pieter Wuille committed
3427
            Misbehaving(pfrom->GetId(), 1);
s_nakamoto's avatar
s_nakamoto committed
3428
            return false;
3429
        }
s_nakamoto's avatar
s_nakamoto committed
3430

3431
        int64_t nTime;
s_nakamoto's avatar
s_nakamoto committed
3432
3433
        CAddress addrMe;
        CAddress addrFrom;
3434
        uint64_t nNonce = 1;
s_nakamoto's avatar
s_nakamoto committed
3435
        vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
3436
        if (pfrom->nVersion < MIN_PEER_PROTO_VERSION)
Pieter Wuille's avatar
Pieter Wuille committed
3437
        {
3438
            // disconnect from peers older than this proto version
3439
            LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
Gavin Andresen's avatar
Gavin Andresen committed
3440
3441
            pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
                               strprintf("Version must be %d or greater", MIN_PEER_PROTO_VERSION));
Pieter Wuille's avatar
Pieter Wuille committed
3442
3443
3444
3445
            pfrom->fDisconnect = true;
            return false;
        }

s_nakamoto's avatar
s_nakamoto committed
3446
3447
        if (pfrom->nVersion == 10300)
            pfrom->nVersion = 300;
Pieter Wuille's avatar
Pieter Wuille committed
3448
        if (!vRecv.empty())
s_nakamoto's avatar
s_nakamoto committed
3449
            vRecv >> addrFrom >> nNonce;
Mike Hearn's avatar
Mike Hearn committed
3450
        if (!vRecv.empty()) {
3451
            vRecv >> LIMITED_STRING(pfrom->strSubVer, 256);
Mike Hearn's avatar
Mike Hearn committed
3452
3453
            pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
        }
Pieter Wuille's avatar
Pieter Wuille committed
3454
        if (!vRecv.empty())
s_nakamoto's avatar
s_nakamoto committed
3455
            vRecv >> pfrom->nStartingHeight;
3456
3457
3458
3459
        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
3460

3461
3462
3463
3464
3465
3466
        if (pfrom->fInbound && addrMe.IsRoutable())
        {
            pfrom->addrLocal = addrMe;
            SeenLocal(addrMe);
        }

s_nakamoto's avatar
s_nakamoto committed
3467
3468
3469
        // Disconnect if we connected to ourself
        if (nNonce == nLocalHostNonce && nNonce > 1)
        {
3470
            LogPrintf("connected to self at %s, disconnecting\n", pfrom->addr.ToString());
s_nakamoto's avatar
s_nakamoto committed
3471
3472
3473
3474
            pfrom->fDisconnect = true;
            return true;
        }

Gavin Andresen's avatar
Gavin Andresen committed
3475
3476
3477
3478
        // Be shy and don't send version until we hear
        if (pfrom->fInbound)
            pfrom->PushVersion();

s_nakamoto's avatar
s_nakamoto committed
3479
3480
3481
3482
        pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);


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

s_nakamoto's avatar
s_nakamoto committed
3486
3487
3488
        if (!pfrom->fInbound)
        {
            // Advertise our address
3489
            if (fListen && !IsInitialBlockDownload())
s_nakamoto's avatar
s_nakamoto committed
3490
            {
3491
3492
3493
                CAddress addr = GetLocalAddress(&pfrom->addr);
                if (addr.IsRoutable())
                    pfrom->PushAddress(addr);
s_nakamoto's avatar
s_nakamoto committed
3494
3495
3496
            }

            // Get recent addresses
3497
            if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000)
s_nakamoto's avatar
s_nakamoto committed
3498
3499
3500
3501
            {
                pfrom->PushMessage("getaddr");
                pfrom->fGetAddr = true;
            }
3502
3503
3504
3505
3506
3507
3508
            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
3509
3510
        }

s_nakamoto's avatar
s_nakamoto committed
3511
        // Relay alerts
3512
3513
        {
            LOCK(cs_mapAlerts);
3514
            BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
s_nakamoto's avatar
s_nakamoto committed
3515
                item.second.RelayTo(pfrom);
3516
        }
s_nakamoto's avatar
s_nakamoto committed
3517
3518
3519

        pfrom->fSuccessfullyConnected = true;

3520
3521
3522
3523
3524
3525
3526
3527
        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);
3528

3529
        AddTimeData(pfrom->addr, nTime);
s_nakamoto's avatar
s_nakamoto committed
3530
3531
3532
3533
3534
3535
    }


    else if (pfrom->nVersion == 0)
    {
        // Must have a version message before anything else
Pieter Wuille's avatar
Pieter Wuille committed
3536
        Misbehaving(pfrom->GetId(), 1);
s_nakamoto's avatar
s_nakamoto committed
3537
3538
3539
3540
3541
3542
        return false;
    }


    else if (strCommand == "verack")
    {
3543
        pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
s_nakamoto's avatar
s_nakamoto committed
3544
3545
3546
3547
3548
3549
3550
    }


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

        // Don't want addr from older versions unless seeding
3553
        if (pfrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000)
s_nakamoto's avatar
s_nakamoto committed
3554
3555
            return true;
        if (vAddr.size() > 1000)
3556
        {
Pieter Wuille's avatar
Pieter Wuille committed
3557
            Misbehaving(pfrom->GetId(), 20);
3558
            return error("message addr size() = %u", vAddr.size());
3559
        }
s_nakamoto's avatar
s_nakamoto committed
3560
3561

        // Store the new addresses
3562
        vector<CAddress> vAddrOk;
3563
3564
        int64_t nNow = GetAdjustedTime();
        int64_t nSince = nNow - 10 * 60;
3565
        BOOST_FOREACH(CAddress& addr, vAddr)
s_nakamoto's avatar
s_nakamoto committed
3566
        {
Gavin Andresen's avatar
Gavin Andresen committed
3567
3568
            boost::this_thread::interruption_point();

s_nakamoto's avatar
s_nakamoto committed
3569
3570
            if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
                addr.nTime = nNow - 5 * 24 * 60 * 60;
s_nakamoto's avatar
s_nakamoto committed
3571
            pfrom->AddAddressKnown(addr);
3572
            bool fReachable = IsReachable(addr);
s_nakamoto's avatar
s_nakamoto committed
3573
            if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
s_nakamoto's avatar
s_nakamoto committed
3574
3575
3576
            {
                // Relay to a limited number of other nodes
                {
3577
                    LOCK(cs_vNodes);
3578
3579
                    // 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
3580
3581
                    static uint256 hashSalt;
                    if (hashSalt == 0)
3582
                        hashSalt = GetRandHash();
3583
                    uint64_t hashAddr = addr.GetHash();
Pieter Wuille's avatar
Pieter Wuille committed
3584
                    uint256 hashRand = hashSalt ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60));
3585
                    hashRand = Hash(BEGIN(hashRand), END(hashRand));
s_nakamoto's avatar
s_nakamoto committed
3586
                    multimap<uint256, CNode*> mapMix;
3587
                    BOOST_FOREACH(CNode* pnode, vNodes)
3588
                    {
3589
                        if (pnode->nVersion < CADDR_TIME_VERSION)
s_nakamoto's avatar
s_nakamoto committed
3590
                            continue;
3591
3592
3593
3594
3595
3596
                        unsigned int nPointer;
                        memcpy(&nPointer, &pnode, sizeof(nPointer));
                        uint256 hashKey = hashRand ^ nPointer;
                        hashKey = Hash(BEGIN(hashKey), END(hashKey));
                        mapMix.insert(make_pair(hashKey, pnode));
                    }
3597
                    int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s)
s_nakamoto's avatar
s_nakamoto committed
3598
3599
3600
3601
                    for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
                        ((*mi).second)->PushAddress(addr);
                }
            }
3602
3603
3604
            // Do not store addresses outside our network
            if (fReachable)
                vAddrOk.push_back(addr);
s_nakamoto's avatar
s_nakamoto committed
3605
        }
3606
        addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60);
s_nakamoto's avatar
s_nakamoto committed
3607
3608
        if (vAddr.size() < 1000)
            pfrom->fGetAddr = false;
3609
3610
        if (pfrom->fOneShot)
            pfrom->fDisconnect = true;
s_nakamoto's avatar
s_nakamoto committed
3611
3612
3613
3614
3615
3616
3617
    }


    else if (strCommand == "inv")
    {
        vector<CInv> vInv;
        vRecv >> vInv;
3618
        if (vInv.size() > MAX_INV_SZ)
3619
        {
Pieter Wuille's avatar
Pieter Wuille committed
3620
            Misbehaving(pfrom->GetId(), 20);
3621
            return error("message inv size() = %u", vInv.size());
3622
        }
s_nakamoto's avatar
s_nakamoto committed
3623

3624
3625
        LOCK(cs_main);

Pieter Wuille's avatar
Pieter Wuille committed
3626
3627
        std::vector<CInv> vToFetch;

3628
        for (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
s_nakamoto's avatar
s_nakamoto committed
3629
        {
3630
3631
            const CInv &inv = vInv[nInv];

Gavin Andresen's avatar
Gavin Andresen committed
3632
            boost::this_thread::interruption_point();
s_nakamoto's avatar
s_nakamoto committed
3633
3634
            pfrom->AddInventoryKnown(inv);

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

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

Pieter Wuille's avatar
Pieter Wuille committed
3641
            if (inv.type == MSG_BLOCK) {
Pieter Wuille's avatar
Pieter Wuille committed
3642
                UpdateBlockAvailability(pfrom->GetId(), inv.hash);
Pieter Wuille's avatar
Pieter Wuille committed
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
                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);
                    if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - Params().TargetSpacing() * 20) {
                        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);
                    }
3659
                    LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->nHeight, inv.hash.ToString(), pfrom->id);
Pieter Wuille's avatar
Pieter Wuille committed
3660
3661
                }
            }
Pieter Wuille's avatar
Pieter Wuille committed
3662

s_nakamoto's avatar
s_nakamoto committed
3663
            // Track requests for our stuff
3664
            g_signals.Inventory(inv.hash);
3665
3666
3667
3668
3669

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

        if (!vToFetch.empty())
            pfrom->PushMessage("getdata", vToFetch);
s_nakamoto's avatar
s_nakamoto committed
3674
3675
3676
3677
3678
3679
3680
    }


    else if (strCommand == "getdata")
    {
        vector<CInv> vInv;
        vRecv >> vInv;
3681
        if (vInv.size() > MAX_INV_SZ)
3682
        {
Pieter Wuille's avatar
Pieter Wuille committed
3683
            Misbehaving(pfrom->GetId(), 20);
3684
            return error("message getdata size() = %u", vInv.size());
3685
        }
s_nakamoto's avatar
s_nakamoto committed
3686

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

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

3693
3694
        pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end());
        ProcessGetData(pfrom);
s_nakamoto's avatar
s_nakamoto committed
3695
3696
3697
3698
3699
3700
3701
3702
3703
    }


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

3704
3705
        LOCK(cs_main);

3706
        // Find the last block the caller has in the main chain
jtimon's avatar
jtimon committed
3707
        CBlockIndex* pindex = FindForkInGlobalIndex(chainActive, locator);
s_nakamoto's avatar
s_nakamoto committed
3708
3709
3710

        // Send the rest of the chain
        if (pindex)
3711
            pindex = chainActive.Next(pindex);
3712
        int nLimit = 500;
3713
        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);
3714
        for (; pindex; pindex = chainActive.Next(pindex))
s_nakamoto's avatar
s_nakamoto committed
3715
3716
3717
        {
            if (pindex->GetBlockHash() == hashStop)
            {
3718
                LogPrint("net", "  getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
s_nakamoto's avatar
s_nakamoto committed
3719
3720
3721
                break;
            }
            pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
3722
            if (--nLimit <= 0)
s_nakamoto's avatar
s_nakamoto committed
3723
3724
3725
            {
                // When this block is requested, we'll send an inv that'll make them
                // getblocks the next batch of inventory.
3726
                LogPrint("net", "  getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
s_nakamoto's avatar
s_nakamoto committed
3727
3728
3729
3730
3731
3732
3733
                pfrom->hashContinue = pindex->GetBlockHash();
                break;
            }
        }
    }


3734
3735
3736
3737
3738
3739
    else if (strCommand == "getheaders")
    {
        CBlockLocator locator;
        uint256 hashStop;
        vRecv >> locator >> hashStop;

3740
3741
        LOCK(cs_main);

3742
3743
3744
3745
        CBlockIndex* pindex = NULL;
        if (locator.IsNull())
        {
            // If locator is null, return the hashStop block
3746
            BlockMap::iterator mi = mapBlockIndex.find(hashStop);
3747
3748
3749
3750
3751
3752
3753
            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
3754
            pindex = FindForkInGlobalIndex(chainActive, locator);
3755
            if (pindex)
3756
                pindex = chainActive.Next(pindex);
3757
3758
        }

3759
        // we must use CBlocks, as CBlockHeaders won't include the 0x00 nTx count at the end
3760
        vector<CBlock> vHeaders;
Pieter Wuille's avatar
Pieter Wuille committed
3761
        int nLimit = MAX_HEADERS_RESULTS;
3762
        LogPrint("net", "getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString(), pfrom->id);
3763
        for (; pindex; pindex = chainActive.Next(pindex))
3764
3765
3766
3767
3768
3769
3770
3771
3772
        {
            vHeaders.push_back(pindex->GetBlockHeader());
            if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
                break;
        }
        pfrom->PushMessage("headers", vHeaders);
    }


s_nakamoto's avatar
s_nakamoto committed
3773
3774
3775
    else if (strCommand == "tx")
    {
        vector<uint256> vWorkQueue;
3776
        vector<uint256> vEraseQueue;
s_nakamoto's avatar
s_nakamoto committed
3777
3778
3779
3780
3781
3782
        CTransaction tx;
        vRecv >> tx;

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

3783
3784
        LOCK(cs_main);

s_nakamoto's avatar
s_nakamoto committed
3785
        bool fMissingInputs = false;
Pieter Wuille's avatar
Pieter Wuille committed
3786
        CValidationState state;
3787
3788
3789

        mapAlreadyAskedFor.erase(inv);

3790
        if (AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs))
s_nakamoto's avatar
s_nakamoto committed
3791
        {
3792
            mempool.check(pcoinsTip);
3793
            RelayTransaction(tx);
s_nakamoto's avatar
s_nakamoto committed
3794
            vWorkQueue.push_back(inv.hash);
3795
            vEraseQueue.push_back(inv.hash);
s_nakamoto's avatar
s_nakamoto committed
3796

3797
3798
            LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s : accepted %s (poolsz %u)\n",
                pfrom->id, pfrom->cleanSubVer,
3799
                tx.GetHash().ToString(),
3800
3801
                mempool.mapTx.size());

s_nakamoto's avatar
s_nakamoto committed
3802
            // Recursively process any orphan transactions that depended on this one
3803
            set<NodeId> setMisbehaving;
3804
            for (unsigned int i = 0; i < vWorkQueue.size(); i++)
s_nakamoto's avatar
s_nakamoto committed
3805
            {
3806
3807
3808
3809
3810
                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
3811
3812
                     ++mi)
                {
3813
                    const uint256& orphanHash = *mi;
3814
3815
                    const CTransaction& orphanTx = mapOrphanTransactions[orphanHash].tx;
                    NodeId fromPeer = mapOrphanTransactions[orphanHash].fromPeer;
3816
                    bool fMissingInputs2 = false;
3817
3818
3819
                    // 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)
3820
                    CValidationState stateDummy;
s_nakamoto's avatar
s_nakamoto committed
3821

3822
3823
3824
3825
                    vEraseQueue.push_back(orphanHash);

                    if (setMisbehaving.count(fromPeer))
                        continue;
3826
                    if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2))
s_nakamoto's avatar
s_nakamoto committed
3827
                    {
3828
                        LogPrint("mempool", "   accepted orphan tx %s\n", orphanHash.ToString());
3829
                        RelayTransaction(orphanTx);
3830
                        vWorkQueue.push_back(orphanHash);
3831
3832
3833
                    }
                    else if (!fMissingInputs2)
                    {
3834
3835
3836
3837
3838
3839
3840
3841
3842
                        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
3843
                        LogPrint("mempool", "   removed orphan tx %s\n", orphanHash.ToString());
s_nakamoto's avatar
s_nakamoto committed
3844
                    }
3845
                    mempool.check(pcoinsTip);
s_nakamoto's avatar
s_nakamoto committed
3846
3847
3848
                }
            }

3849
            BOOST_FOREACH(uint256 hash, vEraseQueue)
s_nakamoto's avatar
s_nakamoto committed
3850
3851
3852
3853
                EraseOrphanTx(hash);
        }
        else if (fMissingInputs)
        {
3854
            AddOrphanTx(tx, pfrom->GetId());
3855
3856

            // DoS prevention: do not allow mapOrphanTransactions to grow unbounded
3857
3858
            unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
            unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
3859
            if (nEvicted > 0)
3860
                LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted);
Pieter Wuille's avatar
Pieter Wuille committed
3861
3862
3863
3864
3865
        } 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
3866
        }
3867
        int nDoS = 0;
3868
        if (state.IsInvalid(nDoS))
Philip Kaufmann's avatar
Philip Kaufmann committed
3869
        {
3870
3871
            LogPrint("mempool", "%s from peer=%d %s was not accepted into the memory pool: %s\n", tx.GetHash().ToString(),
                pfrom->id, pfrom->cleanSubVer,
3872
                state.GetRejectReason());
Gavin Andresen's avatar
Gavin Andresen committed
3873
3874
            pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
                               state.GetRejectReason(), inv.hash);
3875
            if (nDoS > 0)
Pieter Wuille's avatar
Pieter Wuille committed
3876
                Misbehaving(pfrom->GetId(), nDoS);
Gavin Andresen's avatar
Gavin Andresen committed
3877
        }
s_nakamoto's avatar
s_nakamoto committed
3878
3879
3880
    }


Pieter Wuille's avatar
Pieter Wuille committed
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
    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.
3928
            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
3929
3930
3931
3932
            pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256(0));
        }
    }

3933
    else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing
s_nakamoto's avatar
s_nakamoto committed
3934
    {
3935
3936
        CBlock block;
        vRecv >> block;
s_nakamoto's avatar
s_nakamoto committed
3937

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

Pieter Wuille's avatar
Pieter Wuille committed
3941
        pfrom->AddInventoryKnown(inv);
3942

Pieter Wuille's avatar
Pieter Wuille committed
3943
        CValidationState state;
3944
        ProcessBlock(state, pfrom, &block);
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
        int nDoS;
        if (state.IsInvalid(nDoS)) {
            pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
                               state.GetRejectReason(), inv.hash);
            if (nDoS > 0) {
                LOCK(cs_main);
                Misbehaving(pfrom->GetId(), nDoS);
            }
        }

s_nakamoto's avatar
s_nakamoto committed
3955
3956
3957
3958
3959
3960
    }


    else if (strCommand == "getaddr")
    {
        pfrom->vAddrToSend.clear();
3961
3962
3963
        vector<CAddress> vAddr = addrman.GetAddr();
        BOOST_FOREACH(const CAddress &addr, vAddr)
            pfrom->PushAddress(addr);
s_nakamoto's avatar
s_nakamoto committed
3964
3965
3966
    }


3967
3968
    else if (strCommand == "mempool")
    {
3969
        LOCK2(cs_main, pfrom->cs_filter);
3970

3971
3972
3973
        std::vector<uint256> vtxid;
        mempool.queryHashes(vtxid);
        vector<CInv> vInv;
Matt Corallo's avatar
Matt Corallo committed
3974
3975
        BOOST_FOREACH(uint256& hash, vtxid) {
            CInv inv(MSG_TX, hash);
3976
3977
3978
            CTransaction tx;
            bool fInMemPool = mempool.lookup(hash, tx);
            if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
3979
            if ((pfrom->pfilter && pfrom->pfilter->IsRelevantAndUpdate(tx)) ||
Matt Corallo's avatar
Matt Corallo committed
3980
3981
               (!pfrom->pfilter))
                vInv.push_back(inv);
3982
3983
3984
3985
            if (vInv.size() == MAX_INV_SZ) {
                pfrom->PushMessage("inv", vInv);
                vInv.clear();
            }
3986
3987
3988
3989
3990
3991
        }
        if (vInv.size() > 0)
            pfrom->PushMessage("inv", vInv);
    }


s_nakamoto's avatar
s_nakamoto committed
3992
3993
    else if (strCommand == "ping")
    {
Jeff Garzik's avatar
Jeff Garzik committed
3994
3995
        if (pfrom->nVersion > BIP0031_VERSION)
        {
3996
            uint64_t nonce = 0;
Jeff Garzik's avatar
Jeff Garzik committed
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
            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
4011
4012
4013
    }


Josh Lehan's avatar
Josh Lehan committed
4014
4015
    else if (strCommand == "pong")
    {
4016
        int64_t pingUsecEnd = nTimeReceived;
4017
        uint64_t nonce = 0;
Josh Lehan's avatar
Josh Lehan committed
4018
4019
4020
        size_t nAvail = vRecv.in_avail();
        bool bPingFinished = false;
        std::string sProblem;
4021

Josh Lehan's avatar
Josh Lehan committed
4022
4023
        if (nAvail >= sizeof(nonce)) {
            vRecv >> nonce;
4024

Josh Lehan's avatar
Josh Lehan committed
4025
4026
4027
4028
4029
            // 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;
4030
                    int64_t pingUsecTime = pingUsecEnd - pfrom->nPingUsecStart;
Josh Lehan's avatar
Josh Lehan committed
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
                    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";
        }
4055

Josh Lehan's avatar
Josh Lehan committed
4056
        if (!(sProblem.empty())) {
4057
4058
            LogPrint("net", "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n",
                pfrom->id,
4059
4060
                pfrom->cleanSubVer,
                sProblem,
4061
4062
4063
                pfrom->nPingNonceSent,
                nonce,
                nAvail);
Josh Lehan's avatar
Josh Lehan committed
4064
4065
4066
4067
4068
        }
        if (bPingFinished) {
            pfrom->nPingNonceSent = 0;
        }
    }
4069
4070


s_nakamoto's avatar
s_nakamoto committed
4071
4072
4073
4074
4075
    else if (strCommand == "alert")
    {
        CAlert alert;
        vRecv >> alert;

Gavin Andresen's avatar
Gavin Andresen committed
4076
4077
        uint256 alertHash = alert.GetHash();
        if (pfrom->setKnown.count(alertHash) == 0)
s_nakamoto's avatar
s_nakamoto committed
4078
        {
Gavin Andresen's avatar
Gavin Andresen committed
4079
            if (alert.ProcessAlert())
4080
            {
Gavin Andresen's avatar
Gavin Andresen committed
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
                // 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
4096
                Misbehaving(pfrom->GetId(), 10);
4097
            }
s_nakamoto's avatar
s_nakamoto committed
4098
4099
4100
4101
        }
    }


4102
4103
4104
4105
4106
4107
4108
    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
4109
            Misbehaving(pfrom->GetId(), 100);
4110
4111
4112
4113
4114
        else
        {
            LOCK(pfrom->cs_filter);
            delete pfrom->pfilter;
            pfrom->pfilter = new CBloomFilter(filter);
4115
            pfrom->pfilter->UpdateEmptyFull();
4116
        }
4117
        pfrom->fRelayTxes = true;
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
    }


    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
4128
        if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE)
4129
        {
Pieter Wuille's avatar
Pieter Wuille committed
4130
            Misbehaving(pfrom->GetId(), 100);
4131
4132
4133
4134
4135
        } else {
            LOCK(pfrom->cs_filter);
            if (pfrom->pfilter)
                pfrom->pfilter->insert(vData);
            else
Pieter Wuille's avatar
Pieter Wuille committed
4136
                Misbehaving(pfrom->GetId(), 100);
4137
4138
4139
4140
4141
4142
4143
4144
        }
    }


    else if (strCommand == "filterclear")
    {
        LOCK(pfrom->cs_filter);
        delete pfrom->pfilter;
4145
        pfrom->pfilter = new CBloomFilter();
4146
        pfrom->fRelayTxes = true;
4147
4148
4149
    }


Gavin Andresen's avatar
Gavin Andresen committed
4150
4151
    else if (strCommand == "reject")
    {
4152
4153
4154
4155
        if (fDebug) {
            try {
                string strMsg; unsigned char ccode; string strReason;
                vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, 111);
Gavin Andresen's avatar
Gavin Andresen committed
4156

4157
4158
                ostringstream ss;
                ss << strMsg << " code " << itostr(ccode) << ": " << strReason;
Gavin Andresen's avatar
Gavin Andresen committed
4159

4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
                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
4170
4171
4172
4173
            }
        }
    }

s_nakamoto's avatar
s_nakamoto committed
4174
4175
4176
    else
    {
        // Ignore unknown commands for extensibility
4177
        LogPrint("net", "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->id);
s_nakamoto's avatar
s_nakamoto committed
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
    }


    // Update the last seen time for this node's address
    if (pfrom->fNetworkNode)
        if (strCommand == "version" || strCommand == "addr" || strCommand == "inv" || strCommand == "getdata" || strCommand == "ping")
            AddressCurrentlyConnected(pfrom->addr);


    return true;
}

4190
// requires LOCK(cs_vRecvMsg)
4191
4192
4193
bool ProcessMessages(CNode* pfrom)
{
    //if (fDebug)
4194
    //    LogPrintf("ProcessMessages(%u messages)\n", pfrom->vRecvMsg.size());
s_nakamoto's avatar
s_nakamoto committed
4195

4196
4197
4198
4199
4200
4201
4202
4203
    //
    // Message format
    //  (4) message start
    //  (12) command
    //  (4) size
    //  (4) checksum
    //  (x) data
    //
4204
    bool fOk = true;
s_nakamoto's avatar
s_nakamoto committed
4205

4206
4207
    if (!pfrom->vRecvGetData.empty())
        ProcessGetData(pfrom);
4208

4209
4210
    // this maintains the order of responses
    if (!pfrom->vRecvGetData.empty()) return fOk;
4211

4212
    std::deque<CNetMessage>::iterator it = pfrom->vRecvMsg.begin();
4213
    while (!pfrom->fDisconnect && it != pfrom->vRecvMsg.end()) {
4214
        // Don't bother if send buffer is too full to respond anyway
4215
        if (pfrom->nSendSize >= SendBufferSize())
4216
4217
            break;

4218
4219
        // get next message
        CNetMessage& msg = *it;
4220
4221

        //if (fDebug)
4222
        //    LogPrintf("ProcessMessages(message %u msgsz, %u bytes, complete:%s)\n",
4223
4224
4225
        //            msg.hdr.nMessageSize, msg.vRecv.size(),
        //            msg.complete() ? "Y" : "N");

4226
        // end, if an incomplete message is found
4227
        if (!msg.complete())
4228
            break;
4229

4230
4231
4232
        // at this point, any failure means we can delete the current message
        it++;

4233
        // Scan for message start
4234
        if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
R E Broadley's avatar
R E Broadley committed
4235
            LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", msg.hdr.GetCommand(), pfrom->id);
4236
4237
            fOk = false;
            break;
4238
        }
s_nakamoto's avatar
s_nakamoto committed
4239

4240
        // Read header
4241
        CMessageHeader& hdr = msg.hdr;
4242
4243
        if (!hdr.IsValid())
        {
R E Broadley's avatar
R E Broadley committed
4244
            LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", hdr.GetCommand(), pfrom->id);
4245
4246
4247
4248
4249
4250
4251
4252
            continue;
        }
        string strCommand = hdr.GetCommand();

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

        // Checksum
4253
        CDataStream& vRecv = msg.vRecv;
Pieter Wuille's avatar
Pieter Wuille committed
4254
4255
4256
4257
        uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
        unsigned int nChecksum = 0;
        memcpy(&nChecksum, &hash, sizeof(nChecksum));
        if (nChecksum != hdr.nChecksum)
4258
        {
4259
            LogPrintf("ProcessMessages(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
4260
               strCommand, nMessageSize, nChecksum, hdr.nChecksum);
Pieter Wuille's avatar
Pieter Wuille committed
4261
            continue;
4262
4263
4264
4265
4266
4267
        }

        // Process message
        bool fRet = false;
        try
        {
4268
            fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime);
Gavin Andresen's avatar
Gavin Andresen committed
4269
            boost::this_thread::interruption_point();
4270
4271
4272
        }
        catch (std::ios_base::failure& e)
        {
Gavin Andresen's avatar
Gavin Andresen committed
4273
            pfrom->PushMessage("reject", strCommand, REJECT_MALFORMED, string("error parsing message"));
4274
4275
            if (strstr(e.what(), "end of data"))
            {
4276
                // Allow exceptions from under-length message on vRecv
4277
                LogPrintf("ProcessMessages(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand, nMessageSize, e.what());
4278
4279
4280
            }
            else if (strstr(e.what(), "size too large"))
            {
4281
                // Allow exceptions from over-long size
4282
                LogPrintf("ProcessMessages(%s, %u bytes) : Exception '%s' caught\n", strCommand, nMessageSize, e.what());
4283
4284
4285
            }
            else
            {
4286
                PrintExceptionContinue(&e, "ProcessMessages()");
4287
4288
            }
        }
Gavin Andresen's avatar
Gavin Andresen committed
4289
4290
4291
        catch (boost::thread_interrupted) {
            throw;
        }
4292
        catch (std::exception& e) {
4293
            PrintExceptionContinue(&e, "ProcessMessages()");
4294
        } catch (...) {
4295
            PrintExceptionContinue(NULL, "ProcessMessages()");
4296
4297
4298
        }

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

4301
        break;
4302
4303
    }

4304
4305
4306
4307
    // In case the connection got shut down, its receive buffer was wiped
    if (!pfrom->fDisconnect)
        pfrom->vRecvMsg.erase(pfrom->vRecvMsg.begin(), it);

4308
    return fOk;
4309
}
s_nakamoto's avatar
s_nakamoto committed
4310
4311
4312
4313


bool SendMessages(CNode* pto, bool fSendTrickle)
{
4314
    {
s_nakamoto's avatar
s_nakamoto committed
4315
4316
4317
4318
        // Don't send anything until we get their version message
        if (pto->nVersion == 0)
            return true;

Josh Lehan's avatar
Josh Lehan committed
4319
4320
4321
4322
4323
4324
4325
4326
        //
        // Message: ping
        //
        bool pingSend = false;
        if (pto->fPingQueued) {
            // RPC ping request by user
            pingSend = true;
        }
4327
4328
        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
4329
4330
4331
            pingSend = true;
        }
        if (pingSend) {
4332
            uint64_t nonce = 0;
Josh Lehan's avatar
Josh Lehan committed
4333
            while (nonce == 0) {
4334
                GetRandBytes((unsigned char*)&nonce, sizeof(nonce));
Josh Lehan's avatar
Josh Lehan committed
4335
4336
            }
            pto->fPingQueued = false;
4337
            pto->nPingUsecStart = GetTimeMicros();
Josh Lehan's avatar
Josh Lehan committed
4338
            if (pto->nVersion > BIP0031_VERSION) {
4339
                pto->nPingNonceSent = nonce;
Pieter Wuille's avatar
Pieter Wuille committed
4340
                pto->PushMessage("ping", nonce);
Josh Lehan's avatar
Josh Lehan committed
4341
            } else {
4342
4343
                // Peer is too old to support ping command with nonce, pong will never arrive.
                pto->nPingNonceSent = 0;
Jeff Garzik's avatar
Jeff Garzik committed
4344
                pto->PushMessage("ping");
Josh Lehan's avatar
Josh Lehan committed
4345
            }
Jeff Garzik's avatar
Jeff Garzik committed
4346
        }
s_nakamoto's avatar
s_nakamoto committed
4347

4348
4349
4350
4351
        TRY_LOCK(cs_main, lockMain); // Acquire cs_main for IsInitialBlockDownload() and CNodeState()
        if (!lockMain)
            return true;

s_nakamoto's avatar
s_nakamoto committed
4352
        // Address refresh broadcast
4353
        static int64_t nLastRebroadcast;
4354
        if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
s_nakamoto's avatar
s_nakamoto committed
4355
4356
        {
            {
4357
                LOCK(cs_vNodes);
4358
                BOOST_FOREACH(CNode* pnode, vNodes)
s_nakamoto's avatar
s_nakamoto committed
4359
4360
                {
                    // Periodically clear setAddrKnown to allow refresh broadcasts
4361
4362
                    if (nLastRebroadcast)
                        pnode->setAddrKnown.clear();
s_nakamoto's avatar
s_nakamoto committed
4363
4364

                    // Rebroadcast our address
4365
                    if (fListen)
s_nakamoto's avatar
s_nakamoto committed
4366
                    {
4367
4368
4369
                        CAddress addr = GetLocalAddress(&pnode->addr);
                        if (addr.IsRoutable())
                            pnode->PushAddress(addr);
s_nakamoto's avatar
s_nakamoto committed
4370
                    }
s_nakamoto's avatar
s_nakamoto committed
4371
4372
                }
            }
4373
            nLastRebroadcast = GetTime();
s_nakamoto's avatar
s_nakamoto committed
4374
4375
4376
4377
4378
4379
4380
4381
4382
        }

        //
        // Message: addr
        //
        if (fSendTrickle)
        {
            vector<CAddress> vAddr;
            vAddr.reserve(pto->vAddrToSend.size());
4383
            BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend)
s_nakamoto's avatar
s_nakamoto committed
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
            {
                // 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);
        }

4402
4403
        CNodeState &state = *State(pto->GetId());
        if (state.fShouldBan) {
Pieter Wuille's avatar
Pieter Wuille committed
4404
4405
            if (pto->fWhitelisted)
                LogPrintf("Warning: not punishing whitelisted peer %s!\n", pto->addr.ToString());
Pieter Wuille's avatar
Pieter Wuille committed
4406
4407
            else {
                pto->fDisconnect = true;
Pieter Wuille's avatar
Pieter Wuille committed
4408
4409
4410
                if (pto->addr.IsLocal())
                    LogPrintf("Warning: not banning local peer %s!\n", pto->addr.ToString());
                else
4411
                {
Pieter Wuille's avatar
Pieter Wuille committed
4412
                    CNode::Ban(pto->addr);
4413
                }
Pieter Wuille's avatar
Pieter Wuille committed
4414
            }
4415
            state.fShouldBan = false;
Pieter Wuille's avatar
Pieter Wuille committed
4416
4417
        }

4418
4419
4420
4421
        BOOST_FOREACH(const CBlockReject& reject, state.rejects)
            pto->PushMessage("reject", (string)"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock);
        state.rejects.clear();

4422
        // Start block sync
Pieter Wuille's avatar
Pieter Wuille committed
4423
4424
4425
4426
4427
4428
4429
4430
4431
        if (pindexBestHeader == NULL)
            pindexBestHeader = chainActive.Tip();
        bool fFetch = !pto->fInbound || (pindexBestHeader && (state.pindexLastCommonBlock ? state.pindexLastCommonBlock->nHeight : 0) + 144 > pindexBestHeader->nHeight);
        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;
4432
                LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight);
Pieter Wuille's avatar
Pieter Wuille committed
4433
4434
                pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256(0));
            }
4435
4436
4437
4438
4439
4440
4441
        }

        // 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())
        {
4442
            g_signals.Broadcast();
4443
        }
s_nakamoto's avatar
s_nakamoto committed
4444
4445
4446
4447
4448
4449
4450

        //
        // Message: inventory
        //
        vector<CInv> vInv;
        vector<CInv> vInvWait;
        {
4451
            LOCK(pto->cs_inventory);
s_nakamoto's avatar
s_nakamoto committed
4452
4453
            vInv.reserve(pto->vInventoryToSend.size());
            vInvWait.reserve(pto->vInventoryToSend.size());
4454
            BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
s_nakamoto's avatar
s_nakamoto committed
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
            {
                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)
4465
                        hashSalt = GetRandHash();
s_nakamoto's avatar
s_nakamoto committed
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
                    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
4493
        // Detect whether we're stalling
4494
        int64_t nNow = GetTimeMicros();
Pieter Wuille's avatar
Pieter Wuille committed
4495
4496
4497
4498
4499
        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);
4500
4501
4502
            pto->fDisconnect = true;
        }

s_nakamoto's avatar
s_nakamoto committed
4503
        //
4504
        // Message: getdata (blocks)
s_nakamoto's avatar
s_nakamoto committed
4505
4506
        //
        vector<CInv> vGetData;
Pieter Wuille's avatar
Pieter Wuille committed
4507
4508
4509
4510
4511
4512
4513
        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);
4514
4515
                LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(),
                    pindex->nHeight, pto->id);
Pieter Wuille's avatar
Pieter Wuille committed
4516
4517
            }
            if (state.nBlocksInFlight == 0 && staller != -1) {
R E Broadley's avatar
R E Broadley committed
4518
                if (State(staller)->nStallingSince == 0) {
Pieter Wuille's avatar
Pieter Wuille committed
4519
                    State(staller)->nStallingSince = nNow;
R E Broadley's avatar
R E Broadley committed
4520
4521
                    LogPrint("net", "Stall started peer=%d\n", staller);
                }
4522
4523
4524
4525
4526
4527
4528
            }
        }

        //
        // Message: getdata (non-blocks)
        //
        while (!pto->fDisconnect && !pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
s_nakamoto's avatar
s_nakamoto committed
4529
4530
        {
            const CInv& inv = (*pto->mapAskFor.begin()).second;
4531
            if (!AlreadyHave(inv))
s_nakamoto's avatar
s_nakamoto committed
4532
            {
4533
                if (fDebug)
4534
                    LogPrint("net", "Requesting %s peer=%d\n", inv.ToString(), pto->id);
s_nakamoto's avatar
s_nakamoto committed
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
                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;
}


4552
4553
4554
bool CBlockUndo::WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock)
{
    // Open history file to append
4555
    CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
4556
    if (fileout.IsNull())
4557
4558
4559
4560
4561
4562
4563
        return error("CBlockUndo::WriteToDisk : OpenUndoFile failed");

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

    // Write undo data
4564
    long fileOutPos = ftell(fileout.Get());
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
    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();

    // Flush stdio buffers and commit to disk before returning
4577
    fflush(fileout.Get());
4578
    if (!IsInitialBlockDownload())
4579
        FileCommit(fileout.Get());
4580
4581
4582
4583
4584
4585
4586

    return true;
}

bool CBlockUndo::ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock)
{
    // Open history file to read
4587
    CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
4588
    if (filein.IsNull())
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
        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
4610

4611
 std::string CBlockFileInfo::ToString() const {
4612
     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));
4613
 }
s_nakamoto's avatar
s_nakamoto committed
4614
4615
4616



4617
4618
4619
4620
4621
4622
class CMainCleanup
{
public:
    CMainCleanup() {}
    ~CMainCleanup() {
        // block headers
4623
        BlockMap::iterator it1 = mapBlockIndex.begin();
4624
4625
4626
4627
4628
4629
        for (; it1 != mapBlockIndex.end(); it1++)
            delete (*it1).second;
        mapBlockIndex.clear();

        // orphan transactions
        mapOrphanTransactions.clear();
4630
        mapOrphanTransactionsByPrev.clear();
4631
4632
    }
} instance_of_cmaincleanup;