main.cpp 217 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
Infernoman's avatar
Infernoman committed
3
// Copyright (c) 2014-2015 The Crown developers
4
// Distributed under the MIT software license, see the accompanying
Fordy's avatar
Fordy committed
5
6
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

7
#include "main.h"
8

9
#include "addrman.h"
10
#include "alert.h"
11
#include "auxpow.h"
12
#include "chainparams.h"
13
#include "checkpoints.h"
14
#include "checkqueue.h"
15
#include "init.h"
16
17
#include "instantx.h"
#include "darksend.h"
18
#include "masternodeman.h"
19
#include "masternode-payments.h"
20
#include "masternode-budget.h"
21
#include "merkleblock.h"
22
#include "net.h"
23
#include "pow.h"
24
25
#include "txdb.h"
#include "txmempool.h"
Pieter Wuille's avatar
Pieter Wuille committed
26
#include "ui_interface.h"
27
#include "util.h"
Evan Duffield's avatar
Evan Duffield committed
28
#include "spork.h"
29
#include "utilmoneystr.h"
30

Gavin Andresen's avatar
Gavin Andresen committed
31
#include <sstream>
32
33
34
35

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

39
using namespace boost;
40
using namespace std;
s_nakamoto's avatar
s_nakamoto committed
41

42
#if defined(NDEBUG)
Infernoman's avatar
Infernoman committed
43
# error "Crown cannot be compiled without assertions."
44
45
#endif

46
47
48
/**
 * Global state
 */
s_nakamoto's avatar
s_nakamoto committed
49
50
51

CCriticalSection cs_main;

52
BlockMap mapBlockIndex;
53
CChain chainActive;
54
CBlockIndex *pindexBestHeader = NULL;
55
int64_t nTimeBestReceived = 0;
56
57
CWaitableCriticalSection csBestBlock;
CConditionVariable cvBlockChange;
58
int nScriptCheckThreads = 0;
59
bool fImporting = false;
60
bool fReindex = false;
Evan Duffield's avatar
Evan Duffield committed
61
bool fTxIndex = true;
62
bool fIsBareMultisigStd = true;
63
bool fCheckBlockIndex = false;
Pieter Wuille's avatar
Pieter Wuille committed
64
unsigned int nCoinCacheSize = 5000;
65
bool fAlerts = DEFAULT_ALERTS;
66

infernoman's avatar
infernoman committed
67
/** Fees smaller than this (in crowns) are considered zero fee (for relaying and mining)
UdjinM6's avatar
UdjinM6 committed
68
69
70
71
 * We are ~100 times smaller then bitcoin now (2015-06-23), set minRelayTxFee only 10 times higher
 * so it's still 10 times lower comparing to bitcoin.
 */
CFeeRate minRelayTxFee = CFeeRate(10000);
Gavin Andresen's avatar
Gavin Andresen committed
72

Gavin Andresen's avatar
Gavin Andresen committed
73
CTxMemPool mempool(::minRelayTxFee);
s_nakamoto's avatar
s_nakamoto committed
74

75
76
77
78
79
struct COrphanTx {
    CTransaction tx;
    NodeId fromPeer;
};
map<uint256, COrphanTx> mapOrphanTransactions;
80
map<uint256, set<uint256> > mapOrphanTransactionsByPrev;
81
82
83
map<uint256, int64_t> mapRejectedBlocks;


84
void EraseOrphansFor(NodeId peer);
s_nakamoto's avatar
s_nakamoto committed
85

86
87
static void CheckBlockIndex();

88
/** Constant stuff for coinbase transactions we create: */
89
CScript COINBASE_FLAGS;
s_nakamoto's avatar
s_nakamoto committed
90

91
const string strMessageMagic = "DarkCoin Signed Message:\n";
92

93
94
// Internal stuff
namespace {
95

R E Broadley's avatar
R E Broadley committed
96
97
    struct CBlockIndexWorkComparator
    {
98
        bool operator()(CBlockIndex *pa, CBlockIndex *pb) const {
R E Broadley's avatar
R E Broadley committed
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
            // 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;
118

119
    /**
120
121
     * The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for itself and all ancestors) and
     * as good as our current tip or better. Entries may be failed, though.
122
     */
123
    set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
124
    /** Number of nodes with fSyncStarted. */
Pieter Wuille's avatar
Pieter Wuille committed
125
    int nSyncStarted = 0;
126
    /** All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions. */
Pieter Wuille's avatar
Pieter Wuille committed
127
    multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked;
R E Broadley's avatar
R E Broadley committed
128
129

    CCriticalSection cs_LastBlockFile;
130
    std::vector<CBlockFileInfo> vinfoBlockFile;
R E Broadley's avatar
R E Broadley committed
131
132
    int nLastBlockFile = 0;

133
134
135
136
    /**
     * Every received block is assigned a unique and increasing identifier, so we
     * know which one to give priority in case of a fork.
     */
R E Broadley's avatar
R E Broadley committed
137
    CCriticalSection cs_nBlockSequenceId;
138
    /** Blocks loaded from disk are assigned id 0, so start the counter at 1. */
R E Broadley's avatar
R E Broadley committed
139
140
    uint32_t nBlockSequenceId = 1;

141
142
143
144
    /**
     * Sources of received blocks, to be able to send them reject messages or ban
     * them, if processing happens afterwards. Protected by cs_main.
     */
R E Broadley's avatar
R E Broadley committed
145
146
    map<uint256, NodeId> mapBlockSource;

147
    /** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */
R E Broadley's avatar
R E Broadley committed
148
149
    struct QueuedBlock {
        uint256 hash;
150
151
        CBlockIndex *pindex;  //! Optional.
        int64_t nTime;  //! Time of "getdata" request in microseconds.
152
153
        int nValidatedQueuedBefore;  //! Number of blocks queued with validated headers (globally) at the time this one is requested.
        bool fValidatedHeaders;  //! Whether this block has validated headers at the time of request.
R E Broadley's avatar
R E Broadley committed
154
155
    };
    map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;
156

157
158
159
    /** Number of blocks in flight with validated headers. */
    int nQueuedValidatedHeaders = 0;

160
    /** Number of preferable block download peers. */
161
    int nPreferredDownload = 0;
162

163
    /** Dirty block index entries. */
164
165
    set<CBlockIndex*> setDirtyBlockIndex;

166
    /** Dirty block file entries. */
167
    set<int> setDirtyFileInfo;
168
} // anon namespace
s_nakamoto's avatar
s_nakamoto committed
169

Pieter Wuille's avatar
Pieter Wuille committed
170
171
172
173
174
//////////////////////////////////////////////////////////////////////////////
//
// dispatching functions
//

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

177
namespace {
178

179
struct CMainSignals {
180
    /** Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. */
181
    boost::signals2::signal<void (const CTransaction &, const CBlock *)> SyncTransaction;
182
    /** Notifies listeners of an erased transaction (currently disabled, requires transaction replacement). */
183
    boost::signals2::signal<void (const uint256 &)> EraseTransaction;
184
    /** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */
185
    boost::signals2::signal<void (const uint256 &)> UpdatedTransaction;
186
    /** Notifies listeners of a new active block chain. */
187
    boost::signals2::signal<void (const CBlockLocator &)> SetBestChain;
188
    /** Notifies listeners about an inventory item being seen on the network. */
189
    boost::signals2::signal<void (const uint256 &)> Inventory;
190
    /** Tells listeners to broadcast their data. */
191
    boost::signals2::signal<void ()> Broadcast;
192
    /** Notifies listeners of a block validation result */
193
    boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked;
194
} g_signals;
Pieter Wuille's avatar
Pieter Wuille committed
195

196
} // anon namespace
Pieter Wuille's avatar
Pieter Wuille committed
197

198
199
200
201
202
203
204
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));
205
    g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
Pieter Wuille's avatar
Pieter Wuille committed
206
207
}

208
void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
209
    g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
210
211
212
213
214
215
    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
216
217
}

218
void UnregisterAllValidationInterfaces() {
219
    g_signals.BlockChecked.disconnect_all_slots();
220
221
222
223
224
225
    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
226
227
}

228
229
void SyncWithWallets(const CTransaction &tx, const CBlock *pblock) {
    g_signals.SyncTransaction(tx, pblock);
Pieter Wuille's avatar
Pieter Wuille committed
230
231
}

232
233
234
235
236
//////////////////////////////////////////////////////////////////////////////
//
// Registration of network node signals.
//

Pieter Wuille's avatar
Pieter Wuille committed
237
namespace {
238
239
240
241
242
243
244

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

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

    CNodeState() {
280
        fCurrentlyConnected = false;
Pieter Wuille's avatar
Pieter Wuille committed
281
282
        nMisbehavior = 0;
        fShouldBan = false;
Pieter Wuille's avatar
Pieter Wuille committed
283
284
        pindexBestKnownBlock = NULL;
        hashLastUnknownBlock = uint256(0);
Pieter Wuille's avatar
Pieter Wuille committed
285
286
287
        pindexLastCommonBlock = NULL;
        fSyncStarted = false;
        nStallingSince = 0;
288
        nBlocksInFlight = 0;
289
        fPreferredDownload = false;
Pieter Wuille's avatar
Pieter Wuille committed
290
291
292
    }
};

293
/** Map maintaining per-node state. Requires cs_main. */
Pieter Wuille's avatar
Pieter Wuille committed
294
295
296
297
298
299
300
301
302
303
304
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()
305
{
UdjinM6's avatar
UdjinM6 committed
306
307
    while(true){
        TRY_LOCK(cs_main, lockMain);
UdjinM6's avatar
UdjinM6 committed
308
        if(!lockMain) { MilliSleep(50); continue; }
UdjinM6's avatar
UdjinM6 committed
309
310
        return chainActive.Height();
    }
311
312
}

313
314
315
316
317
318
319
320
321
322
void UpdatePreferredDownload(CNode* node, CNodeState* state)
{
    nPreferredDownload -= state->fPreferredDownload;

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

    nPreferredDownload += state->fPreferredDownload;
}

Pieter Wuille's avatar
Pieter Wuille committed
323
324
325
326
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;
327
    state.address = pnode->addr;
Pieter Wuille's avatar
Pieter Wuille committed
328
329
330
331
}

void FinalizeNode(NodeId nodeid) {
    LOCK(cs_main);
332
333
    CNodeState *state = State(nodeid);

Pieter Wuille's avatar
Pieter Wuille committed
334
335
336
    if (state->fSyncStarted)
        nSyncStarted--;

337
338
339
340
    if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
        AddressCurrentlyConnected(state->address);
    }

341
342
    BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight)
        mapBlocksInFlight.erase(entry.hash);
343
    EraseOrphansFor(nodeid);
344
    nPreferredDownload -= state->fPreferredDownload;
345

Pieter Wuille's avatar
Pieter Wuille committed
346
347
    mapNodeState.erase(nodeid);
}
348
349

// Requires cs_main.
Pieter Wuille's avatar
Pieter Wuille committed
350
void MarkBlockAsReceived(const uint256& hash) {
351
352
353
    map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
    if (itInFlight != mapBlocksInFlight.end()) {
        CNodeState *state = State(itInFlight->second.first);
354
        nQueuedValidatedHeaders -= itInFlight->second.second->fValidatedHeaders;
355
356
        state->vBlocksInFlight.erase(itInFlight->second.second);
        state->nBlocksInFlight--;
Pieter Wuille's avatar
Pieter Wuille committed
357
        state->nStallingSince = 0;
358
359
360
361
362
        mapBlocksInFlight.erase(itInFlight);
    }
}

// Requires cs_main.
Pieter Wuille's avatar
Pieter Wuille committed
363
void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, CBlockIndex *pindex = NULL) {
364
365
366
367
368
369
    CNodeState *state = State(nodeid);
    assert(state != NULL);

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

370
371
    QueuedBlock newentry = {hash, pindex, GetTimeMicros(), nQueuedValidatedHeaders, pindex != NULL};
    nQueuedValidatedHeaders += newentry.fValidatedHeaders;
372
373
374
375
376
    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
377
378
379
380
381
382
/** 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) {
383
        BlockMap::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock);
Pieter Wuille's avatar
Pieter Wuille committed
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
        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);

399
    BlockMap::iterator it = mapBlockIndex.find(hash);
Pieter Wuille's avatar
Pieter Wuille committed
400
401
402
403
404
405
406
407
408
409
    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
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
/** 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
461
462
463
464
465
    // 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
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
    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) {
483
484
485
486
            if (!pindex->IsValid(BLOCK_VALID_TREE)) {
                // We consider the chain that this peer is on invalid.
                return;
            }
Pieter Wuille's avatar
Pieter Wuille committed
487
488
489
490
491
            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
492
                if (pindex->nHeight > nWindowEnd) {
Pieter Wuille's avatar
Pieter Wuille committed
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
                    // 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;
            }
        }
    }
Pieter Wuille's avatar
Pieter Wuille committed
510
511
}

512
} // anon namespace
Pieter Wuille's avatar
Pieter Wuille committed
513
514
515
516
517
518
519

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
520
    stats.nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
521
522
523
524
525
    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
526
527
528
    return true;
}

529
530
void RegisterNodeSignals(CNodeSignals& nodeSignals)
{
531
    nodeSignals.GetHeight.connect(&GetHeight);
532
533
    nodeSignals.ProcessMessages.connect(&ProcessMessages);
    nodeSignals.SendMessages.connect(&SendMessages);
Pieter Wuille's avatar
Pieter Wuille committed
534
535
    nodeSignals.InitializeNode.connect(&InitializeNode);
    nodeSignals.FinalizeNode.connect(&FinalizeNode);
536
}
Pieter Wuille's avatar
Pieter Wuille committed
537

538
539
void UnregisterNodeSignals(CNodeSignals& nodeSignals)
{
540
    nodeSignals.GetHeight.disconnect(&GetHeight);
541
542
    nodeSignals.ProcessMessages.disconnect(&ProcessMessages);
    nodeSignals.SendMessages.disconnect(&SendMessages);
Pieter Wuille's avatar
Pieter Wuille committed
543
544
    nodeSignals.InitializeNode.disconnect(&InitializeNode);
    nodeSignals.FinalizeNode.disconnect(&FinalizeNode);
545
}
Pieter Wuille's avatar
Pieter Wuille committed
546

jtimon's avatar
jtimon committed
547
548
CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator)
{
549
    // Find the first block the caller has in the main chain
550
    BOOST_FOREACH(const uint256& hash, locator.vHave) {
551
        BlockMap::iterator mi = mapBlockIndex.find(hash);
552
553
554
        if (mi != mapBlockIndex.end())
        {
            CBlockIndex* pindex = (*mi).second;
jtimon's avatar
jtimon committed
555
            if (chain.Contains(pindex))
556
557
558
                return pindex;
        }
    }
jtimon's avatar
jtimon committed
559
    return chain.Genesis();
560
561
}

562
CCoinsViewCache *pcoinsTip = NULL;
563
CBlockTreeDB *pblocktree = NULL;
Pieter Wuille's avatar
Pieter Wuille committed
564

s_nakamoto's avatar
s_nakamoto committed
565
566
567
568
569
//////////////////////////////////////////////////////////////////////////////
//
// mapOrphanTransactions
//

570
bool AddOrphanTx(const CTransaction& tx, NodeId peer)
s_nakamoto's avatar
s_nakamoto committed
571
572
573
{
    uint256 hash = tx.GetHash();
    if (mapOrphanTransactions.count(hash))
574
575
576
577
578
579
580
581
582
        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:
583
584
    unsigned int sz = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION);
    if (sz > 5000)
585
    {
586
        LogPrint("mempool", "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString());
587
588
        return false;
    }
589

590
591
    mapOrphanTransactions[hash].tx = tx;
    mapOrphanTransactions[hash].fromPeer = peer;
592
    BOOST_FOREACH(const CTxIn& txin, tx.vin)
593
        mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash);
594

595
596
    LogPrint("mempool", "stored orphan tx %s (mapsz %u prevsz %u)\n", hash.ToString(),
             mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
597
    return true;
s_nakamoto's avatar
s_nakamoto committed
598
599
}

Pieter Wuille's avatar
Pieter Wuille committed
600
void static EraseOrphanTx(uint256 hash)
s_nakamoto's avatar
s_nakamoto committed
601
{
602
    map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
603
    if (it == mapOrphanTransactions.end())
s_nakamoto's avatar
s_nakamoto committed
604
        return;
605
    BOOST_FOREACH(const CTxIn& txin, it->second.tx.vin)
s_nakamoto's avatar
s_nakamoto committed
606
    {
607
        map<uint256, set<uint256> >::iterator itPrev = mapOrphanTransactionsByPrev.find(txin.prevout.hash);
608
609
        if (itPrev == mapOrphanTransactionsByPrev.end())
            continue;
610
611
612
        itPrev->second.erase(hash);
        if (itPrev->second.empty())
            mapOrphanTransactionsByPrev.erase(itPrev);
s_nakamoto's avatar
s_nakamoto committed
613
    }
614
    mapOrphanTransactions.erase(it);
s_nakamoto's avatar
s_nakamoto committed
615
616
}

617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
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);
}


634
unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
635
{
636
    unsigned int nEvicted = 0;
637
638
639
    while (mapOrphanTransactions.size() > nMaxOrphans)
    {
        // Evict a random orphan:
640
        uint256 randomhash = GetRandHash();
641
        map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
642
643
644
645
646
647
648
        if (it == mapOrphanTransactions.end())
            it = mapOrphanTransactions.begin();
        EraseOrphanTx(it->first);
        ++nEvicted;
    }
    return nEvicted;
}
s_nakamoto's avatar
s_nakamoto committed
649
650
651
652
653
654
655







656
bool IsStandardTx(const CTransaction& tx, string& reason)
Gavin Andresen's avatar
Gavin Andresen committed
657
{
658
    AssertLockHeld(cs_main);
659
    if (tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) {
660
        reason = "version";
661
        return false;
662
    }
663

664
665
666
    // 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)
667
    // Basically we don't want to propagate transactions that can't be included in
668
669
670
671
672
673
674
675
676
677
678
679
680
681
    // 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)) {
682
        reason = "non-final";
683
        return false;
684
    }
685

686
687
688
689
    // 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.
690
    unsigned int sz = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION);
691
692
    if (sz >= MAX_STANDARD_TX_SIZE) {
        reason = "tx-size";
693
        return false;
694
    }
695

696
    BOOST_FOREACH(const CTxIn& txin, tx.vin)
Gavin Andresen's avatar
Gavin Andresen committed
697
    {
698
699
        // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
        // keys. (remember the 520 byte limit on redeemScript size) That works
700
        // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)+3=1627
701
702
703
704
705
        // 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) {
706
            reason = "scriptsig-size";
707
            return false;
708
709
710
        }
        if (!txin.scriptSig.IsPushOnly()) {
            reason = "scriptsig-not-pushonly";
711
            return false;
712
        }
Gavin Andresen's avatar
Gavin Andresen committed
713
    }
714
715
716

    unsigned int nDataOut = 0;
    txnouttype whichType;
717
    BOOST_FOREACH(const CTxOut& txout, tx.vout) {
718
        if (!::IsStandard(txout.scriptPubKey, whichType)) {
719
            reason = "scriptpubkey";
720
            return false;
721
        }
722

723
724
        if (whichType == TX_NULL_DATA)
            nDataOut++;
725
726
727
728
        else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) {
            reason = "bare-multisig";
            return false;
        } else if (txout.IsDust(::minRelayTxFee)) {
729
            reason = "dust";
730
            return false;
731
        }
732
    }
733

734
735
    // only one OP_RETURN txout is permitted
    if (nDataOut > 1) {
736
        reason = "multi-op-return";
737
738
739
        return false;
    }

Gavin Andresen's avatar
Gavin Andresen committed
740
741
742
    return true;
}

743
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
744
{
745
    AssertLockHeld(cs_main);
746
747
748
749
    // Time based nLockTime implemented in 0.1.6
    if (tx.nLockTime == 0)
        return true;
    if (nBlockHeight == 0)
750
        nBlockHeight = chainActive.Height();
751
752
    if (nBlockTime == 0)
        nBlockTime = GetAdjustedTime();
753
    if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
754
755
756
757
758
759
760
        return true;
    BOOST_FOREACH(const CTxIn& txin, tx.vin)
        if (!txin.IsFinal())
            return false;
    return true;
}

761
762
763
/**
 * Check transaction inputs to mitigate two
 * potential denial-of-service attacks:
764
 *
765
766
767
768
769
 * 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
 */
770
bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
Gavin Andresen's avatar
Gavin Andresen committed
771
{
772
    if (tx.IsCoinBase())
773
        return true; // Coinbases don't use vin normally
774

775
    for (unsigned int i = 0; i < tx.vin.size(); i++)
Gavin Andresen's avatar
Gavin Andresen committed
776
    {
777
        const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]);
Gavin Andresen's avatar
Gavin Andresen committed
778
779

        vector<vector<unsigned char> > vSolutions;
780
781
        txnouttype whichType;
        // get the scriptPubKey corresponding to this input:
782
        const CScript& prevScript = prev.scriptPubKey;
783
        if (!Solver(prevScript, whichType, vSolutions))
784
            return false;
785
        int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions);
786
787
        if (nArgsExpected < 0)
            return false;
788
789
790
791

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

Gavin Andresen's avatar
Gavin Andresen committed
799
800
        if (whichType == TX_SCRIPTHASH)
        {
801
            if (stack.empty())
Gavin Andresen's avatar
Gavin Andresen committed
802
                return false;
803
            CScript subscript(stack.back().begin(), stack.back().end());
804
805
            vector<vector<unsigned char> > vSolutions2;
            txnouttype whichType2;
806
807
808
809
810
811
812
813
814
815
816
817
818
819
            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
820
        }
821

822
        if (stack.size() != (unsigned int)nArgsExpected)
823
            return false;
Gavin Andresen's avatar
Gavin Andresen committed
824
825
826
827
828
    }

    return true;
}

829
unsigned int GetLegacySigOpCount(const CTransaction& tx)
830
{
831
    unsigned int nSigOps = 0;
832
    BOOST_FOREACH(const CTxIn& txin, tx.vin)
833
834
835
    {
        nSigOps += txin.scriptSig.GetSigOpCount(false);
    }
836
    BOOST_FOREACH(const CTxOut& txout, tx.vout)
837
838
839
840
841
    {
        nSigOps += txout.scriptPubKey.GetSigOpCount(false);
    }
    return nSigOps;
}
s_nakamoto's avatar
s_nakamoto committed
842

843
unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
844
845
846
847
848
849
850
851
852
853
854
855
856
{
    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
857

858
859
860
861
862
863
864
865
int GetInputAge(CTxIn& vin)
{
    CCoinsView viewDummy;
    CCoinsViewCache view(&viewDummy);
    {
        LOCK(mempool.cs);
        CCoinsViewMemPool viewMempool(pcoinsTip, mempool);
        view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
s_nakamoto's avatar
s_nakamoto committed
866

867
        const CCoins* coins = view.AccessCoins(vin.prevout.hash);
868
869
870

        if (coins){
            if(coins->nHeight < 0) return 0;
871
            return (chainActive.Tip()->nHeight+1) - coins->nHeight;
872
        }
873
874
875
        else
            return -1;
    }
876
}
s_nakamoto's avatar
s_nakamoto committed
877

878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
int GetInputAgeIX(uint256 nTXHash, CTxIn& vin)
{    
    int sigs = 0;
    int nResult = GetInputAge(vin);
    if(nResult < 0) nResult = 0;

    if (nResult < 6){
        std::map<uint256, CTransactionLock>::iterator i = mapTxLocks.find(nTXHash);
        if (i != mapTxLocks.end()){
            sigs = (*i).second.CountSignatures();
        }
        if(sigs >= INSTANTX_SIGNATURES_REQUIRED){
            return nInstantXDepth+nResult;
        }
    }

    return -1;
}
s_nakamoto's avatar
s_nakamoto committed
896

897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
int GetIXConfirmations(uint256 nTXHash)
{    
    int sigs = 0;

    std::map<uint256, CTransactionLock>::iterator i = mapTxLocks.find(nTXHash);
    if (i != mapTxLocks.end()){
        sigs = (*i).second.CountSignatures();
    }
    if(sigs >= INSTANTX_SIGNATURES_REQUIRED){
        return nInstantXDepth;
    }

    return 0;
}


913
bool CheckTransaction(const CTransaction& tx, CValidationState &state)
914
915
{
    // Basic checks that don't depend on any context
916
    if (tx.vin.empty())
Gavin Andresen's avatar
Gavin Andresen committed
917
        return state.DoS(10, error("CheckTransaction() : vin empty"),
918
                         REJECT_INVALID, "bad-txns-vin-empty");
919
    if (tx.vout.empty())
Gavin Andresen's avatar
Gavin Andresen committed
920
        return state.DoS(10, error("CheckTransaction() : vout empty"),
921
                         REJECT_INVALID, "bad-txns-vout-empty");
922
    // Size limits
923
    if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
924
        return state.DoS(100, error("CheckTransaction() : size limits failed"),
925
                         REJECT_INVALID, "bad-txns-oversize");
926
927

    // Check for negative or overflow output values
928
    CAmount nValueOut = 0;
929
    BOOST_FOREACH(const CTxOut& txout, tx.vout)
930
931
    {
        if (txout.nValue < 0)
Gavin Andresen's avatar
Gavin Andresen committed
932
            return state.DoS(100, error("CheckTransaction() : txout.nValue negative"),
933
                             REJECT_INVALID, "bad-txns-vout-negative");
934
        if (txout.nValue > MAX_MONEY)
Gavin Andresen's avatar
Gavin Andresen committed
935
            return state.DoS(100, error("CheckTransaction() : txout.nValue too high"),
936
                             REJECT_INVALID, "bad-txns-vout-toolarge");
937
938
        nValueOut += txout.nValue;
        if (!MoneyRange(nValueOut))
939
            return state.DoS(100, error("CheckTransaction() : txout total out of range"),
940
                             REJECT_INVALID, "bad-txns-txouttotal-toolarge");
941
942
    }

943
944
    // Check for duplicate inputs
    set<COutPoint> vInOutPoints;
945
    BOOST_FOREACH(const CTxIn& txin, tx.vin)
946
947
    {
        if (vInOutPoints.count(txin.prevout))
948
            return state.DoS(100, error("CheckTransaction() : duplicate inputs"),
949
                             REJECT_INVALID, "bad-txns-inputs-duplicate");
950
951
952
        vInOutPoints.insert(txin.prevout);
    }

953
    if (tx.IsCoinBase())
954
    {
955
        if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
Gavin Andresen's avatar
Gavin Andresen committed
956
            return state.DoS(100, error("CheckTransaction() : coinbase script size"),
957
                             REJECT_INVALID, "bad-cb-length");
958
959
960
    }
    else
    {
961
        BOOST_FOREACH(const CTxIn& txin, tx.vin)
962
            if (txin.prevout.IsNull())
Gavin Andresen's avatar
Gavin Andresen committed
963
                return state.DoS(10, error("CheckTransaction() : prevout is null"),
964
                                 REJECT_INVALID, "bad-txns-prevout-null");
965
966
967
968
969
    }

    return true;
}

970
CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree)
971
{
972
973
974
975
    {
        LOCK(mempool.cs);
        uint256 hash = tx.GetHash();
        double dPriorityDelta = 0;
976
        CAmount nFeeDelta = 0;
977
978
979
980
        mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
        if (dPriorityDelta > 0 || nFeeDelta > 0)
            return 0;
    }
981

982
    CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes);
983
984
985

    if (fAllowFree)
    {
986
987
        // 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
988
989
        //   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.
990
        if (nBytes < (DEFAULT_BLOCK_PRIORITY_SIZE - 1000))
991
            nMinFee = 0;
992
993
994
995
996
997
998
    }

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

Pieter Wuille's avatar
Pieter Wuille committed
999

1000
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
1001
                        bool* pfMissingInputs, bool fRejectInsaneFee, bool ignoreFees)
s_nakamoto's avatar
s_nakamoto committed
1002
{
1003
    AssertLockHeld(cs_main);
s_nakamoto's avatar
s_nakamoto committed
1004
1005
1006
    if (pfMissingInputs)
        *pfMissingInputs = false;

1007
    if (!CheckTransaction(tx, state))
1008
        return error("AcceptToMemoryPool: : CheckTransaction failed");
1009

s_nakamoto's avatar
s_nakamoto committed
1010
    // Coinbase is only valid in a block, not as a loose transaction
1011
    if (tx.IsCoinBase())
Gavin Andresen's avatar
Gavin Andresen committed
1012
1013
        return state.DoS(100, error("AcceptToMemoryPool: : coinbase as individual tx"),
                         REJECT_INVALID, "coinbase");
s_nakamoto's avatar
s_nakamoto committed
1014

1015
    // Rather not work on nonstandard transactions (unless -testnet/-regtest)
1016
    string reason;
jtimon's avatar
jtimon committed
1017
    if (Params().RequireStandard() && !IsStandardTx(tx, reason))
Gavin Andresen's avatar
Gavin Andresen committed
1018
        return state.DoS(0,
1019
                         error("AcceptToMemoryPool : nonstandard transaction: %s", reason),
Gavin Andresen's avatar
Gavin Andresen committed
1020
                         REJECT_NONSTANDARD, reason);
1021

Pieter Wuille's avatar
Pieter Wuille committed
1022
    // is it already in the memory pool?
1023
    uint256 hash = tx.GetHash();
1024
1025
    if (pool.exists(hash))
        return false;
s_nakamoto's avatar
s_nakamoto committed
1026

1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
    // ----------- instantX transaction scanning -----------

    BOOST_FOREACH(const CTxIn& in, tx.vin){
        if(mapLockedInputs.count(in.prevout)){
            if(mapLockedInputs[in.prevout] != tx.GetHash()){
                return state.DoS(0,
                                 error("AcceptToMemoryPool : conflicts with existing transaction lock: %s", reason),
                                 REJECT_INVALID, "tx-lock-conflict");
            }
        }
    }

s_nakamoto's avatar
s_nakamoto committed
1039
    // Check for conflicts with in-memory transactions
1040
1041
    {
    LOCK(pool.cs); // protect pool.mapNextTx
1042
    for (unsigned int i = 0; i < tx.vin.size(); i++)
s_nakamoto's avatar
s_nakamoto committed
1043
    {
1044
        COutPoint outpoint = tx.vin[i].prevout;
1045
        if (pool.mapNextTx.count(outpoint))
s_nakamoto's avatar
s_nakamoto committed
1046
1047
1048
1049
1050
        {
            // Disable replacement feature for now
            return false;
        }
    }
1051
    }
s_nakamoto's avatar
s_nakamoto committed
1052

1053

s_nakamoto's avatar
s_nakamoto committed
1054
    {
1055
        CCoinsView dummy;
1056
        CCoinsViewCache view(&dummy);
1057

1058
        CAmount nValueIn = 0;
1059
        {
1060
        LOCK(pool.cs);
1061
        CCoinsViewMemPool viewMemPool(pcoinsTip, pool);
1062
        view.SetBackend(viewMemPool);
Pieter Wuille's avatar
Pieter Wuille committed
1063
1064
1065

        // do we already have it?
        if (view.HaveCoins(hash))
1066
            return false;
Pieter Wuille's avatar
Pieter Wuille committed
1067
1068

        // do all inputs exist?
Pieter Wuille's avatar
Pieter Wuille committed
1069
1070
        // 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
1071
1072
1073
1074
1075
1076
        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
1077
1078
        }

Pieter Wuille's avatar
Pieter Wuille committed
1079
        // are the actual inputs available?
1080
        if (!view.HaveInputs(tx))
Gavin Andresen's avatar
Gavin Andresen committed
1081
            return state.Invalid(error("AcceptToMemoryPool : inputs already spent"),
1082
                                 REJECT_DUPLICATE, "bad-txns-inputs-spent");
1083

1084
1085
1086
        // Bring the best block into scope
        view.GetBestBlock();

1087
1088
        nValueIn = view.GetValueIn(tx);

1089
1090
1091
        // 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
1092

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

1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
        // 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");
1109

1110
1111
        CAmount nValueOut = tx.GetValueOut();
        CAmount nFees = nValueIn-nValueOut;
1112
1113
1114
1115
        double dPriority = view.GetPriority(tx, chainActive.Height());

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

        // Don't accept it if it can't get into a block
1118
1119
1120
1121
        // but prioritise dstx and don't check fees for it
        if(mapDarksendBroadcastTxes.count(hash)) {
            mempool.PrioritiseTransaction(hash, hash.ToString(), 1000, 0.1*COIN);
        } else if(!ignoreFees){
1122
            CAmount txMinFee = GetMinRelayFee(tx, nSize, true);
1123
1124
1125
1126
1127
            if (fLimitFree && nFees < txMinFee)
                return state.DoS(0, error("AcceptToMemoryPool : not enough fees %s, %d < %d",
                                          hash.ToString(), nFees, txMinFee),
                                 REJECT_INSUFFICIENTFEE, "insufficient fee");

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

1133
            // Continuously rate-limit free (really, very-low-fee) transactions
1134
1135
            // This mitigates 'penny-flooding' -- sending thousands of free transactions just to
            // be annoying or make others' transactions take longer to confirm.
1136
            if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize))
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
            {
                static CCriticalSection csFreeLimiter;
                static double dFreeCount;
                static int64_t nLastTime;
                int64_t nNow = GetTime();

                LOCK(csFreeLimiter);

                // 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)
                    return state.DoS(0, error("AcceptToMemoryPool : free transaction rejected by rate limiter"),
1152
                                     REJECT_INSUFFICIENTFEE, "rate limited free transaction");
1153
1154
1155
                LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
                dFreeCount += nSize;
            }
1156
        }
1157

Gavin Andresen's avatar
Gavin Andresen committed
1158
        if (fRejectInsaneFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000)
1159
            return error("AcceptToMemoryPool: : insane fees %s, %d > %d",
1160
                         hash.ToString(),
Gavin Andresen's avatar
Gavin Andresen committed
1161
                         nFees, ::minRelayTxFee.GetFee(nSize) * 10000);
1162

1163
1164
        // Check against previous transactions
        // This is done last to help prevent CPU exhaustion denial-of-service attacks.
1165
        if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true))
1166
        {
1167
            return error("AcceptToMemoryPool: : ConnectInputs failed %s", hash.ToString());
1168
        }
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183

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

1184
1185
        // Store transaction in memory
        pool.addUnchecked(hash, entry);
s_nakamoto's avatar
s_nakamoto committed
1186
1187
    }

1188
    SyncWithWallets(tx, NULL);
s_nakamoto's avatar
s_nakamoto committed
1189
1190
1191
1192

    return true;
}

1193
bool AcceptableInputs(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
1194
                        bool* pfMissingInputs, bool fRejectInsaneFee, bool isDSTX)
1195
1196
{
    AssertLockHeld(cs_main);
1197
1198
    if (pfMissingInputs)
        *pfMissingInputs = false;
1199
1200

    if (!CheckTransaction(tx, state))
1201
        return error("AcceptableInputs: : CheckTransaction failed");
1202
1203
1204

    // Coinbase is only valid in a block, not as a loose transaction
    if (tx.IsCoinBase())
1205
        return state.DoS(100, error("AcceptableInputs: : coinbase as individual tx"),
1206
1207
                         REJECT_INVALID, "coinbase");

1208
1209
    // Rather not work on nonstandard transactions (unless -testnet/-regtest)
    string reason;
1210
1211
1212
1213
1214
// for any real tx this will be checked on AcceptToMemoryPool anyway
//    if (Params().RequireStandard() && !IsStandardTx(tx, reason))
//        return state.DoS(0,
//                         error("AcceptableInputs : nonstandard transaction: %s", reason),
//                         REJECT_NONSTANDARD, reason);
1215

1216
1217
1218
1219
1220
    // is it already in the memory pool?
    uint256 hash = tx.GetHash();
    if (pool.exists(hash))
        return false;

1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
    // ----------- instantX transaction scanning -----------

    BOOST_FOREACH(const CTxIn& in, tx.vin){
        if(mapLockedInputs.count(in.prevout)){
            if(mapLockedInputs[in.prevout] != tx.GetHash()){
                return state.DoS(0,
                                 error("AcceptableInputs : conflicts with existing transaction lock: %s", reason),
                                 REJECT_INVALID, "tx-lock-conflict");
            }
        }
    }

1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
    // Check for conflicts with in-memory transactions
    {
        LOCK(pool.cs); // protect pool.mapNextTx
        for (unsigned int i = 0; i < tx.vin.size(); i++)
        {
            COutPoint outpoint = tx.vin[i].prevout;
            if (pool.mapNextTx.count(outpoint))
            {
                // Disable replacement feature for now
                return false;
            }
        }
    }

1247

1248
1249
    {
        CCoinsView dummy;
1250
        CCoinsViewCache view(&dummy);
1251

1252
        CAmount nValueIn = 0;
1253
1254
        {
            LOCK(pool.cs);
1255
            CCoinsViewMemPool viewMemPool(pcoinsTip, pool);
1256
1257
            view.SetBackend(viewMemPool);

1258
1259
1260
1261
            // do we already have it?
            if (view.HaveCoins(hash))
                return false;

1262
1263
1264
1265
1266
            // do all inputs exist?
            // 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).
            BOOST_FOREACH(const CTxIn txin, tx.vin) {
                if (!view.HaveCoins(txin.prevout.hash)) {
1267
1268
                    if (pfMissingInputs)
                        *pfMissingInputs = true;
1269
1270
1271
1272
1273
1274
                    return false;
                }
            }

            // are the actual inputs available?
            if (!view.HaveInputs(tx))
1275
                return state.Invalid(error("AcceptableInputs : inputs already spent"),
1276
1277
1278
1279
1280
                                     REJECT_DUPLICATE, "bad-txns-inputs-spent");

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

1281
1282
            nValueIn = view.GetValueIn(tx);

1283
1284
1285
1286
            // we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool
            view.SetBackend(dummy);
        }

1287
        // Check for non-standard pay-to-script-hash in inputs
1288
1289
1290
// for any real tx this will be checked on AcceptToMemoryPool anyway
//        if (Params().RequireStandard() && !AreInputsStandard(tx, view))
//            return error("AcceptableInputs: : nonstandard transaction input");
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307

        // 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("AcceptableInputs : too many sigops %s, %d > %d",
                                   hash.ToString(), nSigOps, MAX_TX_SIGOPS),
                             REJECT_NONSTANDARD, "bad-txns-too-many-sigops");

        CAmount nValueOut = tx.GetValueOut();
        CAmount nFees = nValueIn-nValueOut;
        double dPriority = view.GetPriority(tx, chainActive.Height());
1308

1309
1310
        CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height());
        unsigned int nSize = entry.GetTxSize();
1311

1312
        // Don't accept it if it can't get into a block
1313
1314
1315
1316
        // but prioritise dstx and don't check fees for it
        if(isDSTX) {
            mempool.PrioritiseTransaction(hash, hash.ToString(), 1000, 0.1*COIN);
        } else { // same as !ignoreFees for AcceptToMemoryPool
1317
1318
1319
            CAmount txMinFee = GetMinRelayFee(tx, nSize, true);
            if (fLimitFree && nFees < txMinFee)
                return state.DoS(0, error("AcceptableInputs : not enough fees %s, %d < %d",
1320
1321
1322
                                          hash.ToString(), nFees, txMinFee),
                                 REJECT_INSUFFICIENTFEE, "insufficient fee");

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

            // Continuously rate-limit free (really, very-low-fee) transactions
1329
1330
            // This mitigates 'penny-flooding' -- sending thousands of free transactions just to
            // be annoying or make others' transactions take longer to confirm.
1331
            if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize))
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
            {
                static CCriticalSection csFreeLimiter;
                static double dFreeCount;
                static int64_t nLastTime;
                int64_t nNow = GetTime();

                LOCK(csFreeLimiter);

                // 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)
1346
1347
                    return state.DoS(0, error("AcceptableInputs : free transaction rejected by rate limiter"),
                                     REJECT_INSUFFICIENTFEE, "rate limited free transaction");
1348
1349
1350
1351
1352
                LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
                dFreeCount += nSize;
            }
        }

1353
1354
1355
1356
1357
        if (fRejectInsaneFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000)
            return error("AcceptableInputs: : insane fees %s, %d > %d",
                         hash.ToString(),
                         nFees, ::minRelayTxFee.GetFee(nSize) * 10000);

1358
1359
        // Check against previous transactions
        // This is done last to help prevent CPU exhaustion denial-of-service attacks.
1360
        if (!CheckInputs(tx, state, view, false, STANDARD_SCRIPT_VERIFY_FLAGS, true))
1361
        {
1362
            return error("AcceptableInputs: : ConnectInputs failed %s", hash.ToString());
1363
        }
Evan Duffield's avatar
Evan Duffield committed
1364

1365
1366
1367
1368
1369
1370
1371
1372
1373
        // Check again against just the consensus-critical mandatory script
        // verification flags, in case of bugs in the standard flags that cause
        // transactions to pass as valid when they're actually invalid. For
        // instance the STRICTENC flag was incorrectly allowing certain
        // CHECKSIG NOT scripts to pass, even though they were invalid.
        //
        // There is a similar check in CreateNewBlock() to prevent creating
        // invalid blocks, however allowing such transactions into the mempool
        // can be exploited as a DoS attack.
1374
// for any real tx this will be checked on AcceptToMemoryPool anyway
1375
1376
1377
1378
//        if (!CheckInputs(tx, state, view, false, MANDATORY_SCRIPT_VERIFY_FLAGS, true))
//        {
//            return error("AcceptableInputs: : BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString());
//        }
Evan Duffield's avatar
Evan Duffield committed
1379

1380
1381
        // Store transaction in memory
        // pool.addUnchecked(hash, entry);
Evan Duffield's avatar
Evan Duffield committed
1382
1383
    }

1384
    // SyncWithWallets(tx, NULL);
s_nakamoto's avatar
s_nakamoto committed
1385

1386
    return true;
s_nakamoto's avatar
s_nakamoto committed
1387
1388
}

1389
/** 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
1390
bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
1391
{
Pieter Wuille's avatar
Pieter Wuille committed
1392
    CBlockIndex *pindexSlow = NULL;
1393
1394
1395
    {
        LOCK(cs_main);
        {
1396
            if (mempool.lookup(hash, txOut))
1397
1398
1399
1400
            {
                return true;
            }
        }
Pieter Wuille's avatar
Pieter Wuille committed
1401

1402
1403
1404
1405
        if (fTxIndex) {
            CDiskTxPos postx;
            if (pblocktree->ReadTxIndex(hash, postx)) {
                CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
1406
1407
                if (file.IsNull())
                    return error("%s: OpenBlockFile failed", __func__);
1408
1409
1410
                CBlockHeader header;
                try {
                    file >> header;
1411
                    fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
1412
1413
                    file >> txOut;
                } catch (std::exception &e) {
1414
                    return error("%s : Deserialize or I/O error - %s", __func__, e.what());
1415
1416
1417
                }
                hashBlock = header.GetHash();
                if (txOut.GetHash() != hash)
1418
                    return error("%s : txid mismatch", __func__);
1419
1420
1421
1422
                return true;
            }
        }

Pieter Wuille's avatar
Pieter Wuille committed
1423
1424
1425
        if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
            int nHeight = -1;
            {
1426
                CCoinsViewCache &view = *pcoinsTip;
1427
1428
1429
                const CCoins* coins = view.AccessCoins(hash);
                if (coins)
                    nHeight = coins->nHeight;
Pieter Wuille's avatar
Pieter Wuille committed
1430
1431
            }
            if (nHeight > 0)
1432
                pindexSlow = chainActive[nHeight];
1433
1434
        }
    }
s_nakamoto's avatar
s_nakamoto committed
1435

Pieter Wuille's avatar
Pieter Wuille committed
1436
1437
    if (pindexSlow) {
        CBlock block;
1438
        if (ReadBlockFromDisk(block, pindexSlow)) {
Pieter Wuille's avatar
Pieter Wuille committed
1439
1440
1441
1442
1443
1444
1445
1446
1447
            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
1448

Pieter Wuille's avatar
Pieter Wuille committed
1449
1450
    return false;
}
s_nakamoto's avatar
s_nakamoto committed
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461






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

1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
/**
 * Check proof-of-work of a block header, taking auxpow into account.
 * @param block The block header.
 * @return True iff the PoW is correct.
 */
bool CheckProofOfWork(const CBlockHeader& block)
{
    /* Except for legacy blocks with full version 1, ensure that
       the chain ID is correct.  Legacy blocks are not allowed since
       the merge-mining start, which is checked in AcceptBlockHeader
       where the height is known.  */
    if (!block.nVersion.IsLegacy()
        && block.nVersion.GetChainId() != Params().AuxpowChainId())
        return error("%s : block does not have our chain ID"
                     " (got %d, expected %d, full nVersion %d)",
                     __func__, block.nVersion.GetChainId(),
                     Params().AuxpowChainId(), block.nVersion.GetFullVersion());

    /* If there is no auxpow, just check the block hash.  */
    if (!block.auxpow)
    {
        if (block.nVersion.IsAuxpow())
            return error("%s : no auxpow on block with auxpow version",
                         __func__);

        if (!CheckProofOfWork(block.GetHash(), block.nBits))
            return error("%s : non-AUX proof of work failed", __func__);

        return true;
    }

    /* We have auxpow.  Check it.  */
    if (!block.nVersion.IsAuxpow())
        return error("%s : auxpow on block with non-auxpow version", __func__);

    /* Temporary check:  Disallow parent blocks with auxpow version.  This is
       for compatibility with the old client.  */
    /* FIXME: Remove this check with a hardfork later on.  */
    if (block.auxpow->getParentBlock().nVersion.IsAuxpow())
        return error("%s : auxpow parent block has auxpow version", __func__);

    if (!block.auxpow->check(block.GetHash(), block.nVersion.GetChainId()))
        return error("%s : AUX POW is not valid", __func__);
    if (!CheckProofOfWork(block.auxpow->getParentBlockHash(), block.nBits))
        return error("%s : AUX proof of work failed", __func__);

    return true;
}

1511
1512
1513
bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos)
{
    // Open history file to append
1514
    CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
1515
    if (fileout.IsNull())
1516
        return error("WriteBlockToDisk : OpenBlockFile failed");
1517
1518
1519
1520
1521
1522

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

    // Write block
1523
    long fileOutPos = ftell(fileout.Get());
1524
    if (fileOutPos < 0)
1525
        return error("WriteBlockToDisk : ftell failed");
1526
1527
1528
1529
1530
1531
    pos.nPos = (unsigned int)fileOutPos;
    fileout << block;

    return true;
}

1532
1533
1534
1535
1536
/* Generic implementation of block reading that can handle
   both a block and its header.  */

template<typename T>
static bool ReadBlockOrHeader(T& block, const CDiskBlockPos& pos)
1537
1538
1539
1540
{
    block.SetNull();

    // Open history file to read
1541
    CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
1542
    if (filein.IsNull())
1543
        return error("ReadBlockFromDisk : OpenBlockFile failed");
1544
1545
1546
1547
1548
1549

    // Read block
    try {
        filein >> block;
    }
    catch (std::exception &e) {
1550
        return error("%s : Deserialize or I/O error - %s", __func__, e.what());
1551
1552
1553
    }

    // Check the header
1554
    if (!CheckProofOfWork(block))
1555
        return error("ReadBlockFromDisk : Errors in block header");
1556
1557
1558
1559

    return true;
}

1560
1561
template<typename T>
static bool ReadBlockOrHeader(T& block, const CBlockIndex* pindex)
s_nakamoto's avatar
s_nakamoto committed
1562
{
1563
    if (!ReadBlockOrHeader(block, pindex->GetBlockPos()))
s_nakamoto's avatar
s_nakamoto committed
1564
        return false;
1565
1566
    if (block.GetHash() != pindex->GetBlockHash())
        return error("ReadBlockFromDisk(CBlock&, CBlockIndex*) : GetHash() doesn't match index");
s_nakamoto's avatar
s_nakamoto committed
1567
1568
1569
    return true;
}

1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos)
{
    return ReadBlockOrHeader(block, pos);
}

bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex)
{
    return ReadBlockOrHeader(block, pindex);
}

bool ReadBlockHeaderFromDisk(CBlockHeader& block, const CBlockIndex* pindex)
{
    return ReadBlockOrHeader(block, pindex);
}
1584

vertoe's avatar
vertoe committed
1585
double ConvertBitsToDouble(unsigned int nBits)
s_nakamoto's avatar
s_nakamoto committed
1586
{
vertoe's avatar
vertoe committed
1587
    int nShift = (nBits >> 24) & 0xff;
1588

vertoe's avatar
vertoe committed
1589
1590
    double dDiff =
        (double)0x0000ffff / (double)(nBits & 0x00ffffff);
s_nakamoto's avatar
s_nakamoto committed
1591

vertoe's avatar
vertoe committed
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
    while (nShift < 29)
    {
        dDiff *= 256.0;
        nShift++;
    }
    while (nShift > 29)
    {
        dDiff /= 256.0;
        nShift--;
    }

    return dDiff;
}

1606
int64_t GetBlockValue(int nBits, int nHeight, const CAmount& nFees)
vertoe's avatar
vertoe committed
1607
{
1608
1609
    int64_t nSubsidy = 10 * COIN;
    int halvings = nHeight / Params().SubsidyHalvingInterval();
vertoe's avatar
vertoe committed
1610

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

1615
1616
    // Subsidy is cut in half every 210,000 blocks which will occur approximately every 4 years.
    nSubsidy >>= halvings;
Evan Duffield's avatar
Evan Duffield committed
1617

s_nakamoto's avatar
s_nakamoto committed
1618
1619
1620
    return nSubsidy + nFees;
}

infernoman's avatar
infernoman committed
1621
int64_t GetThronePayment(int nHeight, int64_t blockValue)
vertoe's avatar
vertoe committed
1622
{
1623
    int64_t ret = blockValue*0.4; // start at 40%
vertoe's avatar
vertoe committed
1624
1625
1626
1627

    return ret;
}

s_nakamoto's avatar
s_nakamoto committed
1628
1629
bool IsInitialBlockDownload()
{
1630
    LOCK(cs_main);
1631
    if (fImporting || fReindex || chainActive.Height() < Checkpoints::GetTotalBlocksEstimate())
s_nakamoto's avatar
s_nakamoto committed
1632
        return true;
1633
1634
1635
1636
    static bool lockIBDState = false;
    if (lockIBDState)
        return false;
    bool state = (chainActive.Height() < pindexBestHeader->nHeight - 24 * 6 ||
1637
            pindexBestHeader->GetBlockTime() < GetTime() - 6 * 60 * 60); // ~144 blocks behind -> 2 x fork detection time
1638
1639
1640
    if (!state)
        lockIBDState = true;
    return state;
s_nakamoto's avatar
s_nakamoto committed
1641
1642
}

1643
bool fLargeWorkForkFound = false;
1644
bool fLargeWorkInvalidChainFound = false;
1645
1646
1647
1648
CBlockIndex *pindexBestForkTip = NULL, *pindexBestForkBase = NULL;

void CheckForkWarningConditions()
{
1649
    AssertLockHeld(cs_main);
1650
1651
1652
1653
1654
    // 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;

1655
    // If our best fork is no longer within 72 blocks (+/- 3 hours if no one mines it)
1656
    // of our head, drop it
1657
    if (pindexBestForkTip && chainActive.Height() - pindexBestForkTip->nHeight >= 72)
1658
1659
        pindexBestForkTip = NULL;

1660
    if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > chainActive.Tip()->nChainWork + (GetBlockProof(*chainActive.Tip()) * 6)))
1661
    {
1662
        if (!fLargeWorkForkFound && pindexBestForkBase)
1663
        {
1664
            if(pindexBestForkBase->phashBlock){
1665
1666
1667
1668
                std::string warning = std::string("'Warning: Large-work fork detected, forking after block ") +
                    pindexBestForkBase->phashBlock->ToString() + std::string("'");
                CAlert::Notify(warning, true);
            }
1669
        }
1670
        if (pindexBestForkTip && pindexBestForkBase)
1671
        {
1672
1673
1674
1675
1676
1677
            if(pindexBestForkBase->phashBlock){
                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",
                       pindexBestForkBase->nHeight, pindexBestForkBase->phashBlock->ToString(),
                       pindexBestForkTip->nHeight, pindexBestForkTip->phashBlock->ToString());
                fLargeWorkForkFound = true;
            }
1678
1679
1680
        }
        else
        {
1681
            LogPrintf("CheckForkWarningConditions: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n");
1682
1683
1684
1685
1686
            fLargeWorkInvalidChainFound = true;
        }
    }
    else
    {
1687
        fLargeWorkForkFound = false;
1688
1689
        fLargeWorkInvalidChainFound = false;
    }
1690
1691
1692
1693
}

void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip)
{
1694
    AssertLockHeld(cs_main);
1695
1696
    // If we are on a fork that is sufficiently large, set a warning flag
    CBlockIndex* pfork = pindexNewForkTip;
1697
    CBlockIndex* plonger = chainActive.Tip();
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
    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
1708
    // who's tip is within 72 blocks (+/- 3 hours if no one mines it) of ours
UdjinM6's avatar
UdjinM6 committed
1709
    // or a chain that is entirely longer than ours and invalid (note that this should be detected by both)
1710
1711
1712
1713
1714
    // We use 7 blocks rather arbitrarily as it represents just under 10% of sustained network
    // hash rate operating on the fork.
    // 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)) &&
1715
            pindexNewForkTip->nChainWork - pfork->nChainWork > (GetBlockProof(*pfork) * 7) &&
1716
            chainActive.Height() - pindexNewForkTip->nHeight < 72)
1717
1718
1719
1720
1721
1722
1723
1724
    {
        pindexBestForkTip = pindexNewForkTip;
        pindexBestForkBase = pfork;
    }

    CheckForkWarningConditions();
}

1725
// Requires cs_main.
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
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
1736
1737
    int banscore = GetArg("-banscore", 100);
    if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore)
1738
1739
1740
1741
1742
1743
1744
    {
        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
1745
void static InvalidChainFound(CBlockIndex* pindexNew)
s_nakamoto's avatar
s_nakamoto committed
1746
{
1747
1748
    if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
        pindexBestInvalid = pindexNew;
1749

1750
    LogPrintf("InvalidChainFound: invalid block=%s  height=%d  log2_work=%.8g  date=%s\n",
1751
      pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
Pieter Wuille's avatar
Pieter Wuille committed
1752
      log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S",
1753
      pindexNew->GetBlockTime()));
1754
    LogPrintf("InvalidChainFound:  current best=%s  height=%d  log2_work=%.8g  date=%s\n",
1755
1756
      chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0),
      DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()));
1757
    CheckForkWarningConditions();
s_nakamoto's avatar
s_nakamoto committed
1758
1759
}

1760
1761
1762
1763
1764
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)) {
1765
            CBlockReject reject = {state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), pindex->GetBlockHash()};
1766
1767
1768
            State(it->second)->rejects.push_back(reject);
            if (nDoS > 0)
                Misbehaving(it->second, nDoS);
1769
        }
1770
1771
1772
    }
    if (!state.CorruptionPossible()) {
        pindex->nStatus |= BLOCK_FAILED_VALID;
1773
        setDirtyBlockIndex.insert(pindex);
1774
        setBlockIndexCandidates.erase(pindex);
1775
1776
        InvalidChainFound(pindex);
    }
1777
1778
}

1779
void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight)
1780
{
Pieter Wuille's avatar
Pieter Wuille committed
1781
    // mark inputs spent
1782
    if (!tx.IsCoinBase()) {
Pieter Wuille's avatar
Pieter Wuille committed
1783
        txundo.vprevout.reserve(tx.vin.size());
1784
        BOOST_FOREACH(const CTxIn &txin, tx.vin) {
Pieter Wuille's avatar
Pieter Wuille committed
1785
            txundo.vprevout.push_back(CTxInUndo());
1786
            bool ret = inputs.ModifyCoins(txin.prevout.hash)->Spend(txin.prevout, txundo.vprevout.back());
1787
            assert(ret);
Pieter Wuille's avatar
Pieter Wuille committed
1788
1789
1790
1791
        }
    }

    // add outputs
1792
    inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight);
Pieter Wuille's avatar
Pieter Wuille committed
1793
1794
}

1795
bool CScriptCheck::operator()() {
1796
    const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
1797
    if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, cacheStore), &error)) {
1798
        return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error));
1799
    }
1800
1801
1802
    return true;
}

1803
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
1804
{
1805
    if (!tx.IsCoinBase())
s_nakamoto's avatar
s_nakamoto committed
1806
    {
1807
        if (pvChecks)
1808
            pvChecks->reserve(tx.vin.size());
1809

Pieter Wuille's avatar
Pieter Wuille committed
1810
1811
        // 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.
1812
        if (!inputs.HaveInputs(tx))
1813
            return state.Invalid(error("CheckInputs() : %s inputs unavailable", tx.GetHash().ToString()));
Pieter Wuille's avatar
Pieter Wuille committed
1814

1815
1816
        // While checking, GetBestBlock() refers to the parent block.
        // This is also true for mempool checks.
1817
1818
        CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
        int nSpendHeight = pindexPrev->nHeight + 1;
1819
1820
        CAmount nValueIn = 0;
        CAmount nFees = 0;
1821
        for (unsigned int i = 0; i < tx.vin.size(); i++)
s_nakamoto's avatar
s_nakamoto committed
1822
        {
1823
            const COutPoint &prevout = tx.vin[i].prevout;
1824
1825
            const CCoins *coins = inputs.AccessCoins(prevout.hash);
            assert(coins);
s_nakamoto's avatar
s_nakamoto committed
1826
1827

            // If prev is coinbase, check that it's matured
1828
1829
            if (coins->IsCoinBase()) {
                if (nSpendHeight - coins->nHeight < COINBASE_MATURITY)
Gavin Andresen's avatar
Gavin Andresen committed
1830
                    return state.Invalid(
1831
                        error("CheckInputs() : tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
1832
                        REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
Pieter Wuille's avatar
Pieter Wuille committed
1833
            }
s_nakamoto's avatar
s_nakamoto committed
1834

1835
            // Check for negative or overflow input values
1836
1837
            nValueIn += coins->vout[prevout.n].nValue;
            if (!MoneyRange(coins->vout[prevout.n].nValue) || !MoneyRange(nValueIn))
Gavin Andresen's avatar
Gavin Andresen committed
1838
                return state.DoS(100, error("CheckInputs() : txin values out of range"),
1839
                                 REJECT_INVALID, "bad-txns-inputvalues-outofrange");
1840
1841

        }
Pieter Wuille's avatar
Pieter Wuille committed
1842

1843
        if (nValueIn < tx.GetValueOut())
1844
1845
            return state.DoS(100, error("CheckInputs() : %s value in (%s) < value out (%s)",
                                        tx.GetHash().ToString(), FormatMoney(nValueIn), FormatMoney(tx.GetValueOut())),
1846
                             REJECT_INVALID, "bad-txns-in-belowout");
Pieter Wuille's avatar
Pieter Wuille committed
1847
1848

        // Tally transaction fees
1849
        CAmount nTxFee = nValueIn - tx.GetValueOut();
Pieter Wuille's avatar
Pieter Wuille committed
1850
        if (nTxFee < 0)
1851
            return state.DoS(100, error("CheckInputs() : %s nTxFee < 0", tx.GetHash().ToString()),
1852
                             REJECT_INVALID, "bad-txns-fee-negative");
Pieter Wuille's avatar
Pieter Wuille committed
1853
1854
        nFees += nTxFee;
        if (!MoneyRange(nFees))
Gavin Andresen's avatar
Gavin Andresen committed
1855
            return state.DoS(100, error("CheckInputs() : nFees out of range"),
1856
                             REJECT_INVALID, "bad-txns-fee-outofrange");
Pieter Wuille's avatar
Pieter Wuille committed
1857

1858
1859
1860
1861
        // 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
1862
        // Skip ECDSA signature verification when connecting blocks
1863
        // before the last block chain checkpoint. This is safe because block merkle hashes are
Pieter Wuille's avatar
Pieter Wuille committed
1864
        // still computed and checked, and any change will be caught at the next checkpoint.
1865
        if (fScriptChecks) {
1866
1867
            for (unsigned int i = 0; i < tx.vin.size(); i++) {
                const COutPoint &prevout = tx.vin[i].prevout;
1868
1869
                const CCoins* coins = inputs.AccessCoins(prevout.hash);
                assert(coins);
1870

1871
                // Verify signature
1872
                CScriptCheck check(*coins, tx, i, flags, cacheStore);
1873
1874
1875
                if (pvChecks) {
                    pvChecks->push_back(CScriptCheck());
                    check.swap(pvChecks->back());
1876
                } else if (!check()) {
1877
1878
1879
1880
1881
1882
1883
                    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.
1884
                        CScriptCheck check(*coins, tx, i,
1885
                                flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore);
1886
                        if (check())
1887
                            return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError())));
1888
                    }
1889
1890
1891
1892
1893
1894
1895
                    // 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.
1896
                    return state.DoS(100,false, REJECT_INVALID, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError())));
1897
                }
1898
            }
s_nakamoto's avatar
s_nakamoto committed
1899
1900
1901
1902
1903
1904
        }
    }

    return true;
}

1905
bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
s_nakamoto's avatar
s_nakamoto committed
1906
{
1907
    assert(pindex->GetBlockHash() == view.GetBestBlock());
s_nakamoto's avatar
s_nakamoto committed
1908

1909
1910
1911
1912
1913
    if (pfClean)
        *pfClean = false;

    bool fClean = true;

Pieter Wuille's avatar
Pieter Wuille committed
1914
    CBlockUndo blockUndo;
Pieter Wuille's avatar
Pieter Wuille committed
1915
1916
1917
1918
1919
    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
1920

1921
    if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
1922
        return error("DisconnectBlock() : block and undo data inconsistent");
Pieter Wuille's avatar
Pieter Wuille committed
1923
1924

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

1929
1930
1931
1932
        // 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.
1933
        {
1934
        CCoins outsEmpty;
1935
1936
        CCoinsModifier outs = view.ModifyCoins(hash);
        outs->ClearUnspendable();
Pieter Wuille's avatar
Pieter Wuille committed
1937

1938
        CCoins outsBlock(tx, pindex->nHeight);
1939
1940
1941
1942
        // 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)
1943
1944
            outs->nVersion = outsBlock.nVersion;
        if (*outs != outsBlock)
1945
            fClean = fClean && error("DisconnectBlock() : added transaction mismatch? database corrupted");
Pieter Wuille's avatar
Pieter Wuille committed
1946
1947

        // remove outputs
1948
1949
        outs->Clear();
        }
Pieter Wuille's avatar
Pieter Wuille committed
1950
1951
1952
1953

        // restore inputs
        if (i > 0) { // not coinbases
            const CTxUndo &txundo = blockUndo.vtxundo[i-1];
1954
1955
            if (txundo.vprevout.size() != tx.vin.size())
                return error("DisconnectBlock() : transaction and undo data inconsistent");
Pieter Wuille's avatar
Pieter Wuille committed
1956
1957
1958
            for (unsigned int j = tx.vin.size(); j-- > 0;) {
                const COutPoint &out = tx.vin[j].prevout;
                const CTxInUndo &undo = txundo.vprevout[j];
1959
                CCoinsModifier coins = view.ModifyCoins(out.hash);
1960
1961
                if (undo.nHeight != 0) {
                    // undo data contains height: this is the last output of the prevout tx being spent
1962
                    if (!coins->IsPruned())
1963
                        fClean = fClean && error("DisconnectBlock() : undo data overwriting existing transaction");
1964
1965
1966
1967
                    coins->Clear();
                    coins->fCoinBase = undo.fCoinBase;
                    coins->nHeight = undo.nHeight;
                    coins->nVersion = undo.nVersion;
Pieter Wuille's avatar
Pieter Wuille committed
1968
                } else {
1969
                    if (coins->IsPruned())
1970
                        fClean = fClean && error("DisconnectBlock() : undo data adding output to missing transaction");
Pieter Wuille's avatar
Pieter Wuille committed
1971
                }
1972
                if (coins->IsAvailable(out.n))
1973
                    fClean = fClean && error("DisconnectBlock() : undo data overwriting existing output");
1974
1975
1976
                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
1977
1978
1979
1980
1981
            }
        }
    }

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

1984
1985
1986
1987
1988
1989
    if (pfClean) {
        *pfClean = fClean;
        return true;
    } else {
        return fClean;
    }
s_nakamoto's avatar
s_nakamoto committed
1990
1991
}

1992
void static FlushBlockFile(bool fFinalize = false)
Pieter Wuille's avatar
Pieter Wuille committed
1993
1994
1995
{
    LOCK(cs_LastBlockFile);

1996
    CDiskBlockPos posOld(nLastBlockFile, 0);
Pieter Wuille's avatar
Pieter Wuille committed
1997
1998

    FILE *fileOld = OpenBlockFile(posOld);
1999
    if (fileOld) {
2000
        if (fFinalize)
2001
            TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nSize);
2002
2003
2004
        FileCommit(fileOld);
        fclose(fileOld);
    }
Pieter Wuille's avatar
Pieter Wuille committed
2005
2006

    fileOld = OpenUndoFile(posOld);
2007
    if (fileOld) {
2008
        if (fFinalize)
2009
            TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nUndoSize);
2010
2011
2012
        FileCommit(fileOld);
        fclose(fileOld);
    }
Pieter Wuille's avatar
Pieter Wuille committed
2013
2014
}

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

2017
2018
static CCheckQueue<CScriptCheck> scriptcheckqueue(128);

2019
void ThreadScriptCheck() {
2020
    RenameThread("dash-scriptch");
2021
2022
2023
    scriptcheckqueue.Thread();
}

2024
2025
2026
2027
2028
2029
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;

2030
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck)
s_nakamoto's avatar
s_nakamoto committed
2031
{
2032
    AssertLockHeld(cs_main);
s_nakamoto's avatar
s_nakamoto committed
2033
    // Check it again in case a previous version let a bad block in
2034
    if (!CheckBlock(block, state, !fJustCheck, !fJustCheck))
s_nakamoto's avatar
s_nakamoto committed
2035
2036
        return false;

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

2041
2042
    // Special case for the genesis block, skipping connection of its transactions
    // (its coinbase is unspendable)
2043
    if (block.GetHash() == Params().HashGenesisBlock()) {
2044
        view.SetBestBlock(pindex->GetBlockHash());
2045
2046
2047
        return true;
    }

2048
2049
    bool fScriptChecks = pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate();

2050
    // BIP16 didn't become active until Apr 1 2012
2051
    int64_t nBIP16SwitchTime = 1333238400;
jtimon's avatar
jtimon committed
2052
    bool fStrictPayToScriptHash = (pindex->GetBlockTime() >= nBIP16SwitchTime);
2053

2054
    unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE;
2055

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

Pieter Wuille's avatar
Pieter Wuille committed
2061
2062
    CBlockUndo blockundo;

2063
2064
    CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL);

2065
    int64_t nTimeStart = GetTimeMicros();
2066
    CAmount nFees = 0;
2067
    int nInputs = 0;
2068
    unsigned int nSigOps = 0;
2069
    CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
2070
    std::vector<std::pair<uint256, CDiskTxPos> > vPos;
2071
    vPos.reserve(block.vtx.size());
Pieter Wuille's avatar
Pieter Wuille committed
2072
    blockundo.vtxundo.reserve(block.vtx.size() - 1);
2073
    for (unsigned int i = 0; i < block.vtx.size(); i++)
s_nakamoto's avatar
s_nakamoto committed
2074
    {
2075
        const CTransaction &tx = block.vtx[i];
Pieter Wuille's avatar
Pieter Wuille committed
2076

2077
        nInputs += tx.vin.size();
2078
        nSigOps += GetLegacySigOpCount(tx);
2079
        if (nSigOps > MAX_BLOCK_SIGOPS)
Gavin Andresen's avatar
Gavin Andresen committed
2080
            return state.DoS(100, error("ConnectBlock() : too many sigops"),
2081
                             REJECT_INVALID, "bad-blk-sigops");
2082

2083
2084
        if (!tx.IsCoinBase())
        {
2085
            if (!view.HaveInputs(tx))
Gavin Andresen's avatar
Gavin Andresen committed
2086
                return state.DoS(100, error("ConnectBlock() : inputs missing/spent"),
2087
                                 REJECT_INVALID, "bad-txns-inputs-missingorspent");
2088

2089
2090
2091
2092
2093
            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.
2094
                nSigOps += GetP2SHSigOpCount(tx, view);
2095
                if (nSigOps > MAX_BLOCK_SIGOPS)
Gavin Andresen's avatar
Gavin Andresen committed
2096
                    return state.DoS(100, error("ConnectBlock() : too many sigops"),
2097
                                     REJECT_INVALID, "bad-blk-sigops");
2098
            }
2099

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

2102
            std::vector<CScriptCheck> vChecks;
2103
            if (!CheckInputs(tx, state, view, fScriptChecks, flags, false, nScriptCheckThreads ? &vChecks : NULL))
2104
                return false;
2105
            control.Add(vChecks);
2106
2107
        }

Pieter Wuille's avatar
Pieter Wuille committed
2108
2109
2110
2111
2112
        CTxUndo undoDummy;
        if (i > 0) {
            blockundo.vtxundo.push_back(CTxUndo());
        }
        UpdateCoins(tx, state, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight);
2113

2114
        vPos.push_back(std::make_pair(tx.GetHash(), pos));
2115
        pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
s_nakamoto's avatar
s_nakamoto committed
2116
    }
2117
2118
    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
2119

2120
    if(!IsBlockValueValid(block, GetBlockValue(pindex->pprev->nBits, pindex->pprev->nHeight, nFees))){
Gavin Andresen's avatar
Gavin Andresen committed
2121
        return state.DoS(100,
2122
                         error("ConnectBlock() : coinbase pays too much (actual=%d vs limit=%d)",
2123
                               block.vtx[0].GetValueOut(), GetBlockValue(pindex->pprev->nBits, pindex->pprev->nHeight, nFees)),
Philip Kaufmann's avatar
Philip Kaufmann committed
2124
                               REJECT_INVALID, "bad-cb-amount");
2125
    }
Pieter Wuille's avatar
Pieter Wuille committed
2126

2127
    if (!control.Wait())
Pieter Wuille's avatar
Pieter Wuille committed
2128
        return state.DoS(100, false);
2129
2130
    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);
2131

2132
2133
2134
    if (fJustCheck)
        return true;

Pieter Wuille's avatar
Pieter Wuille committed
2135
    // Write undo information to disk
2136
    if (pindex->GetUndoPos().IsNull() || !pindex->IsValid(BLOCK_VALID_SCRIPTS))
Pieter Wuille's avatar
Pieter Wuille committed
2137
    {
2138
2139
        if (pindex->GetUndoPos().IsNull()) {
            CDiskBlockPos pos;
Pieter Wuille's avatar
Pieter Wuille committed
2140
            if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
2141
                return error("ConnectBlock() : FindUndoPos failed");
Pieter Wuille's avatar
Pieter Wuille committed
2142
            if (!blockundo.WriteToDisk(pos, pindex->pprev->GetBlockHash()))
2143
                return state.Abort("Failed to write undo data");
2144
2145
2146
2147
2148
2149

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

2150
        pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
2151
        setDirtyBlockIndex.insert(pindex);
s_nakamoto's avatar
s_nakamoto committed
2152
2153
    }

2154
    if (fTxIndex)
Pieter Wuille's avatar
Pieter Wuille committed
2155
        if (!pblocktree->WriteTxIndex(vPos))
2156
            return state.Abort("Failed to write transaction index");
2157

2158
    // add this block to the view's block chain
2159
    view.SetBestBlock(pindex->GetBlockHash());
Pieter Wuille's avatar
Pieter Wuille committed
2160

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

2164
2165
2166
    // Watch for changes to the previous coinbase transaction.
    static uint256 hashPrevBestCoinBase;
    g_signals.UpdatedTransaction(hashPrevBestCoinBase);
2167
    hashPrevBestCoinBase = block.vtx[0].GetHash();
2168

2169
2170
    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
2171
2172
2173
2174

    return true;
}

2175
2176
2177
2178
2179
2180
enum FlushStateMode {
    FLUSH_STATE_IF_NEEDED,
    FLUSH_STATE_PERIODIC,
    FLUSH_STATE_ALWAYS
};

2181
2182
2183
2184
2185
/**
 * Update the on-disk chain state.
 * The caches and indexes are flushed if either they're too large, forceWrite is set, or
 * fast is not set and it's been a while since the last write.
 */
2186
bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
2187
    LOCK(cs_main);
2188
    static int64_t nLastWrite = 0;
2189
    try {
2190
2191
2192
    if ((mode == FLUSH_STATE_ALWAYS) ||
        ((mode == FLUSH_STATE_PERIODIC || mode == FLUSH_STATE_IF_NEEDED) && pcoinsTip->GetCacheSize() > nCoinCacheSize) ||
        (mode == FLUSH_STATE_PERIODIC && GetTimeMicros() > nLastWrite + DATABASE_WRITE_INTERVAL * 1000000)) {
2193
2194
2195
2196
2197
2198
        // 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()))
2199
            return state.Error("out of disk space");
2200
        // First make sure all block and undo data is flushed to disk.
Pieter Wuille's avatar
Pieter Wuille committed
2201
        FlushBlockFile();
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
        // Then update all block file information (which may refer to block and undo files).
        bool fileschanged = false;
        for (set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) {
            if (!pblocktree->WriteBlockFileInfo(*it, vinfoBlockFile[*it])) {
                return state.Abort("Failed to write to block index");
            }
            fileschanged = true;
            setDirtyFileInfo.erase(it++);
        }
        if (fileschanged && !pblocktree->WriteLastBlockFile(nLastBlockFile)) {
            return state.Abort("Failed to write to block index");
        }
        for (set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) {
             if (!pblocktree->WriteBlockIndex(CDiskBlockIndex(*it))) {
                 return state.Abort("Failed to write to block index");
             }
             setDirtyBlockIndex.erase(it++);
        }
2220
        pblocktree->Sync();
2221
        // Finally flush the chainstate (which may refer to block index entries).
Pieter Wuille's avatar
Pieter Wuille committed
2222
        if (!pcoinsTip->Flush())
2223
            return state.Abort("Failed to write to coin database");
2224
        // Update best block in wallet (so we can detect restored wallets).
2225
        if (mode != FLUSH_STATE_IF_NEEDED) {
2226
2227
            g_signals.SetBestChain(chainActive.GetLocator());
        }
2228
        nLastWrite = GetTimeMicros();
Pieter Wuille's avatar
Pieter Wuille committed
2229
    }
2230
2231
2232
    } catch (const std::runtime_error& e) {
        return state.Abort(std::string("System error while flushing: ") + e.what());
    }
2233
2234
    return true;
}
Pieter Wuille's avatar
Pieter Wuille committed
2235

2236
2237
void FlushStateToDisk() {
    CValidationState state;
2238
    FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
2239
2240
}

2241
/** Update chainActive and related internal data structures. */
2242
void static UpdateTip(CBlockIndex *pindexNew) {
2243
    chainActive.SetTip(pindexNew);
s_nakamoto's avatar
s_nakamoto committed
2244
2245
2246

    // New best block
    nTimeBestReceived = GetTime();
2247
    mempool.AddTransactionsUpdated(1);
2248

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

2254
    cvBlockChange.notify_all();
s_nakamoto's avatar
s_nakamoto committed
2255

2256
    // Check the version of the last 100 blocks to see if we need to upgrade:
2257
2258
    static bool fWarned = false;
    if (!IsInitialBlockDownload() && !fWarned)
2259
2260
    {
        int nUpgraded = 0;
2261
        const CBlockIndex* pindex = chainActive.Tip();
2262
2263
        for (int i = 0; i < 100 && pindex != NULL; i++)
        {
2264
            if (pindex->nVersion.GetBaseVersion() > CBlock::CURRENT_VERSION)
2265
2266
2267
2268
                ++nUpgraded;
            pindex = pindex->pprev;
        }
        if (nUpgraded > 0)
2269
            LogPrintf("SetBestChain: %d of last 100 blocks above version %d\n", nUpgraded, (int)CBlock::CURRENT_VERSION);
2270
        if (nUpgraded > 100/2)
2271
        {
2272
            // strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user:
2273
            strMiscWarning = _("Warning: This version is obsolete, upgrade required!");
2274
2275
2276
            CAlert::Notify(strMiscWarning, true);
            fWarned = true;
        }
2277
    }
2278
}
2279

2280
/** Disconnect chainActive's tip. */
2281
2282
2283
2284
2285
2286
2287
bool static DisconnectTip(CValidationState &state) {
    CBlockIndex *pindexDelete = chainActive.Tip();
    assert(pindexDelete);
    mempool.check(pcoinsTip);
    // Read block from disk.
    CBlock block;
    if (!ReadBlockFromDisk(block, pindexDelete))
2288
        return state.Abort("Failed to read block");
2289
2290
    // Apply the block atomically to the chain state.
    int64_t nStart = GetTimeMicros();
2291
    {
2292
        CCoinsViewCache view(pcoinsTip);
2293
2294
2295
        if (!DisconnectBlock(block, state, pindexDelete, view))
            return error("DisconnectTip() : DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
        assert(view.Flush());
2296
    }
2297
    LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
2298
    // Write the chain state to disk, if necessary.
2299
    if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
2300
        return false;
Gavin Andresen's avatar
Gavin Andresen committed
2301
    // Resurrect mempool transactions from the disconnected block.
2302
2303
    BOOST_FOREACH(const CTransaction &tx, block.vtx) {
        // ignore validation errors in resurrected transactions
Gavin Andresen's avatar
Gavin Andresen committed
2304
        list<CTransaction> removed;
vertoe's avatar
vertoe committed
2305
        CValidationState stateDummy;
2306
2307
        if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
            mempool.remove(tx, removed, true);
2308
    }
2309
    mempool.removeCoinbaseSpends(pcoinsTip, pindexDelete->nHeight);
2310
2311
2312
    mempool.check(pcoinsTip);
    // Update chainActive and related variables.
    UpdateTip(pindexDelete->pprev);
Gavin Andresen's avatar
Gavin Andresen committed
2313
2314
2315
    // Let wallets know transactions went from 1-confirmed to
    // 0-confirmed or conflicted:
    BOOST_FOREACH(const CTransaction &tx, block.vtx) {
2316
        SyncWithWallets(tx, NULL);
Gavin Andresen's avatar
Gavin Andresen committed
2317
    }
2318
    return true;
2319
}
2320

2321
2322
2323
2324
2325
2326
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;

2327
/**
2328
2329
2330
 * 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.
 */
2331
bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *pblock) {
2332
    assert(pindexNew->pprev == chainActive.Tip());
2333
    mempool.check(pcoinsTip);
2334
    // Read block from disk.
2335
    int64_t nTime1 = GetTimeMicros();
2336
    CBlock block;
2337
2338
    if (!pblock) {
        if (!ReadBlockFromDisk(block, pindexNew))
2339
            return state.Abort("Failed to read block");
2340
2341
        pblock = &block;
    }
2342
    // Apply the block atomically to the chain state.
2343
2344
2345
    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
2346
    {
2347
        CCoinsViewCache view(pcoinsTip);
2348
        CInv inv(MSG_BLOCK, pindexNew->GetBlockHash());
2349
2350
2351
        bool rv = ConnectBlock(*pblock, state, pindexNew, view);
        g_signals.BlockChecked(*pblock, state);
        if (!rv) {
2352
2353
2354
            if (state.IsInvalid())
                InvalidBlockFound(pindexNew, state);
            return error("ConnectTip() : ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
2355
        }
2356
        mapBlockSource.erase(inv.hash);
2357
2358
        nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
        LogPrint("bench", "  - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
2359
        assert(view.Flush());
s_nakamoto's avatar
s_nakamoto committed
2360
    }
2361
2362
    int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
    LogPrint("bench", "  - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001);
2363
    // Write the chain state to disk, if necessary.
2364
    if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
2365
        return false;
2366
2367
    int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
    LogPrint("bench", "  - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001);
2368
    // Remove conflicting transactions from the mempool.
Gavin Andresen's avatar
Gavin Andresen committed
2369
    list<CTransaction> txConflicted;
2370
    mempool.removeForBlock(pblock->vtx, pindexNew->nHeight, txConflicted);
2371
2372
2373
    mempool.check(pcoinsTip);
    // Update chainActive & related variables.
    UpdateTip(pindexNew);
Gavin Andresen's avatar
Gavin Andresen committed
2374
2375
2376
    // Tell wallet about transactions that went from mempool
    // to conflicted:
    BOOST_FOREACH(const CTransaction &tx, txConflicted) {
2377
        SyncWithWallets(tx, NULL);
Gavin Andresen's avatar
Gavin Andresen committed
2378
2379
    }
    // ... and about transactions that got confirmed:
2380
2381
    BOOST_FOREACH(const CTransaction &tx, pblock->vtx) {
        SyncWithWallets(tx, pblock);
Gavin Andresen's avatar
Gavin Andresen committed
2382
    }
2383

2384
2385
2386
    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
2387
2388
2389
    return true;
}

2390
2391
2392
2393
2394
2395
bool DisconnectBlocksAndReprocess(int blocks)
{
    LOCK(cs_main);

    CValidationState state;

2396
    LogPrintf("DisconnectBlocksAndReprocess: Got command to replay %d blocks\n", blocks);
2397
2398
2399
2400
2401
2402
    for(int i = 0; i <= blocks; i++)
        DisconnectTip(state);

    return true;
}

2403
2404
2405
2406
2407
2408
/*
    DisconnectBlockAndInputs

    Remove conflicting blocks for successful InstantX transaction locks
    This should be very rare (Probably will never happen)
*/
2409
// ***TODO*** clean up here
2410
2411
bool DisconnectBlockAndInputs(CValidationState &state, CTransaction txLock)
{
Evan Duffield's avatar
Evan Duffield committed
2412

2413
2414
    // All modifications to the coin state will be done in this cache.
    // Only when all have succeeded, we push it to pcoinsTip.
2415
//    CCoinsViewCache view(*pcoinsTip, true);
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444

    CBlockIndex* BlockReading = chainActive.Tip();
    CBlockIndex* pindexNew = NULL;

    bool foundConflictingTx = false;

    //remove anything conflicting in the memory pool
    list<CTransaction> txConflicted;
    mempool.removeConflicts(txLock, txConflicted);


    // List of what to disconnect (typically nothing)
    vector<CBlockIndex*> vDisconnect;

    for (unsigned int i = 1; BlockReading && BlockReading->nHeight > 0 && !foundConflictingTx && i < 6; i++) {
        vDisconnect.push_back(BlockReading);
        pindexNew = BlockReading->pprev; //new best block

        CBlock block;
        if (!ReadBlockFromDisk(block, BlockReading))
            return state.Abort(_("Failed to read block"));

        // Queue memory transactions to resurrect.
        // We only do this for blocks after the last checkpoint (reorganisation before that
        // point should only happen with -reindex/-loadblock, or a misbehaving peer.
        BOOST_FOREACH(const CTransaction& tx, block.vtx){
            if (!tx.IsCoinBase()){
                BOOST_FOREACH(const CTxIn& in1, txLock.vin){
                    BOOST_FOREACH(const CTxIn& in2, tx.vin){
Evan Duffield's avatar
Evan Duffield committed
2445
                        if(in1.prevout == in2.prevout) foundConflictingTx = true;
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
                    }
                }
            }
        }

        if (BlockReading->pprev == NULL) { assert(BlockReading); break; }
        BlockReading = BlockReading->pprev;
    }

    if(!foundConflictingTx) {
        LogPrintf("DisconnectBlockAndInputs: Can't find a conflicting transaction to inputs\n");
        return false;
    }

    if (vDisconnect.size() > 0) {
2461
        LogPrintf("REORGANIZE: Disconnect Conflicting Blocks %lli blocks; %s..\n", vDisconnect.size(), pindexNew->GetBlockHash().ToString());
2462
        BOOST_FOREACH(CBlockIndex* pindex, vDisconnect) {
2463
            LogPrintf(" -- disconnect %s\n", pindex->GetBlockHash().ToString());
Evan Duffield's avatar
Evan Duffield committed
2464
            DisconnectTip(state);
2465
2466
2467
2468
2469
2470
2471
        }
    }

    return true;
}


2472
2473
2474
2475
/**
 * Return the tip of the chain with the most work in it, that isn't
 * known to be invalid (it's however far from certain to be valid).
 */
2476
static CBlockIndex* FindMostWorkChain() {
2477
    do {
2478
2479
        CBlockIndex *pindexNew = NULL;

2480
2481
        // Find the best candidate header.
        {
2482
2483
            std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexCandidates.rbegin();
            if (it == setBlockIndexCandidates.rend())
2484
                return NULL;
2485
2486
2487
2488
2489
2490
2491
2492
            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
2493
            assert(pindexTest->nChainTx || pindexTest->nHeight == 0);
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503

            // Pruned nodes may have entries in setBlockIndexCandidates for
            // which block files have been deleted.  Remove those as candidates
            // for the most work chain if we come across them; we can't switch
            // to a chain unless we have all the non-active-chain parent blocks.
            bool fFailedChain = pindexTest->nStatus & BLOCK_FAILED_MASK;
            bool fMissingData = !(pindexTest->nStatus & BLOCK_HAVE_DATA);
            if (fFailedChain || fMissingData) {
                // Candidate chain is not usable (either invalid or missing data)
                if (fFailedChain && (pindexBestInvalid == NULL || pindexNew->nChainWork > pindexBestInvalid->nChainWork))
2504
2505
                    pindexBestInvalid = pindexNew;
                CBlockIndex *pindexFailed = pindexNew;
2506
                // Remove the entire chain from the set.
2507
                while (pindexTest != pindexFailed) {
2508
2509
2510
2511
2512
2513
2514
2515
                    if (fFailedChain) {
                        pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
                    } else if (fMissingData) {
                        // If we're missing data, then add back to mapBlocksUnlinked,
                        // so that if the block arrives in the future we can try adding
                        // to setBlockIndexCandidates again.
                        mapBlocksUnlinked.insert(std::make_pair(pindexFailed->pprev, pindexFailed));
                    }
2516
                    setBlockIndexCandidates.erase(pindexFailed);
2517
2518
                    pindexFailed = pindexFailed->pprev;
                }
2519
                setBlockIndexCandidates.erase(pindexTest);
2520
2521
                fInvalidAncestor = true;
                break;
Pieter Wuille's avatar
Pieter Wuille committed
2522
            }
2523
            pindexTest = pindexTest->pprev;
s_nakamoto's avatar
s_nakamoto committed
2524
        }
2525
2526
        if (!fInvalidAncestor)
            return pindexNew;
2527
2528
    } while(true);
}
s_nakamoto's avatar
s_nakamoto committed
2529

2530
/** Delete all entries in setBlockIndexCandidates that are worse than the current tip. */
2531
2532
2533
2534
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();
2535
    while (it != setBlockIndexCandidates.end() && setBlockIndexCandidates.value_comp()(*it, chainActive.Tip())) {
2536
2537
        setBlockIndexCandidates.erase(it++);
    }
2538
2539
    // Either the current tip or a successor of it we're working towards is left in setBlockIndexCandidates.
    assert(!setBlockIndexCandidates.empty());
2540
2541
}

2542
2543
2544
2545
/**
 * Try to make some progress towards making pindexMostWork the active block.
 * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork.
 */
2546
static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, CBlock *pblock) {
2547
    AssertLockHeld(cs_main);
2548
    bool fInvalidFound = false;
2549
2550
    const CBlockIndex *pindexOldTip = chainActive.Tip();
    const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork);
s_nakamoto's avatar
s_nakamoto committed
2551

2552
2553
2554
2555
2556
    // Disconnect active blocks which are no longer in the best chain.
    while (chainActive.Tip() && chainActive.Tip() != pindexFork) {
        if (!DisconnectTip(state))
            return false;
    }
2557

2558
2559
    // Build list of new blocks to connect.
    std::vector<CBlockIndex*> vpindexToConnect;
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
    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) {
2570
2571
        vpindexToConnect.push_back(pindexIter);
        pindexIter = pindexIter->pprev;
2572
    }
2573
    nHeight = nTargetHeight;
2574

2575
2576
    // Connect new blocks.
    BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) {
2577
        if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) {
2578
2579
2580
2581
2582
            if (state.IsInvalid()) {
                // The block violates a consensus rule.
                if (!state.CorruptionPossible())
                    InvalidChainFound(vpindexToConnect.back());
                state = CValidationState();
2583
                fInvalidFound = true;
2584
                fContinue = false;
2585
2586
2587
2588
2589
2590
                break;
            } else {
                // A system error occurred (disk space, database error, ...).
                return false;
            }
        } else {
2591
            PruneBlockIndexCandidates();
2592
2593
            if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) {
                // We're in a better position than we were. Return temporarily to release the lock.
2594
                fContinue = false;
2595
                break;
2596
2597
            }
        }
2598
    }
2599
    }
Pieter Wuille's avatar
Pieter Wuille committed
2600

2601
2602
2603
2604
2605
2606
    // Callbacks/notifications for a new best chain.
    if (fInvalidFound)
        CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
    else
        CheckForkWarningConditions();

s_nakamoto's avatar
s_nakamoto committed
2607
    return true;
2608
}
s_nakamoto's avatar
s_nakamoto committed
2609

2610
2611
2612
2613
2614
/**
 * 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).
 */
2615
bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
2616
2617
    CBlockIndex *pindexNewTip = NULL;
    CBlockIndex *pindexMostWork = NULL;
2618
2619
2620
    do {
        boost::this_thread::interruption_point();

2621
        bool fInitialDownload;
UdjinM6's avatar
UdjinM6 committed
2622
2623
        while(true) {
            TRY_LOCK(cs_main, lockMain);
UdjinM6's avatar
UdjinM6 committed
2624
            if(!lockMain) { MilliSleep(50); continue; }
UdjinM6's avatar
UdjinM6 committed
2625

2626
            pindexMostWork = FindMostWorkChain();
2627

2628
2629
2630
            // Whether we have anything to do at all.
            if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip())
                return true;
2631

2632
            if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL))
2633
                return false;
2634

2635
2636
            pindexNewTip = chainActive.Tip();
            fInitialDownload = IsInitialBlockDownload();
UdjinM6's avatar
UdjinM6 committed
2637
            break;
2638
        }
2639
        // When we reach this point, we switched to a new tip (stored in pindexNewTip).
2640

2641
2642
2643
2644
2645
        // 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();
2646
            {
2647
2648
2649
2650
                LOCK(cs_vNodes);
                BOOST_FOREACH(CNode* pnode, vNodes)
                    if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
                        pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip));
2651
            }
2652
            // Notify external listeners about the new tip.
2653
            uiInterface.NotifyBlockTip(hashNewTip);
2654
        }
2655
    } while(pindexMostWork != chainActive.Tip());
2656
    CheckBlockIndex();
2657

2658
    // Write changes periodically to disk, after relay.
2659
    if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) {
2660
        return false;
2661
    }
s_nakamoto's avatar
s_nakamoto committed
2662

2663
2664
    return true;
}
2665

2666
2667
2668
2669
2670
bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
    AssertLockHeld(cs_main);

    // Mark the block itself as invalid.
    pindex->nStatus |= BLOCK_FAILED_VALID;
2671
    setDirtyBlockIndex.insert(pindex);
2672
2673
2674
2675
2676
    setBlockIndexCandidates.erase(pindex);

    while (chainActive.Contains(pindex)) {
        CBlockIndex *pindexWalk = chainActive.Tip();
        pindexWalk->nStatus |= BLOCK_FAILED_CHILD;
2677
        setDirtyBlockIndex.insert(pindexWalk);
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
        setBlockIndexCandidates.erase(pindexWalk);
        // ActivateBestChain considers blocks already in chainActive
        // unconditionally valid already, so force disconnect away from it.
        if (!DisconnectTip(state)) {
            return false;
        }
    }

    // The resulting new best tip may not be in setBlockIndexCandidates anymore, so
    // add them again.
    BlockMap::iterator it = mapBlockIndex.begin();
    while (it != mapBlockIndex.end()) {
2690
        if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && !setBlockIndexCandidates.value_comp()(it->second, chainActive.Tip())) {
2691
            setBlockIndexCandidates.insert(it->second);
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
        }
        it++;
    }

    InvalidChainFound(pindex);
    return true;
}

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

    int nHeight = pindex->nHeight;

    // Remove the invalidity flag from this block and all its descendants.
    BlockMap::iterator it = mapBlockIndex.begin();
    while (it != mapBlockIndex.end()) {
        if (!it->second->IsValid() && it->second->GetAncestor(nHeight) == pindex) {
            it->second->nStatus &= ~BLOCK_FAILED_MASK;
2710
            setDirtyBlockIndex.insert(it->second);
2711
2712
2713
2714
2715
2716
2717
            if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) {
                setBlockIndexCandidates.insert(it->second);
            }
            if (it->second == pindexBestInvalid) {
                // Reset invalid block marker if it was pointing to one of those.
                pindexBestInvalid = NULL;
            }
2718
        }
2719
        it++;
2720
    }
Pieter Wuille's avatar
Pieter Wuille committed
2721

2722
2723
    // Remove the invalidity flag from all ancestors too.
    while (pindex != NULL) {
2724
2725
2726
        if (pindex->nStatus & BLOCK_FAILED_MASK) {
            pindex->nStatus &= ~BLOCK_FAILED_MASK;
            setDirtyBlockIndex.insert(pindex);
2727
2728
2729
        }
        pindex = pindex->pprev;
    }
s_nakamoto's avatar
s_nakamoto committed
2730
2731
2732
    return true;
}

Pieter Wuille's avatar
Pieter Wuille committed
2733
CBlockIndex* AddToBlockIndex(const CBlockHeader& block)
s_nakamoto's avatar
s_nakamoto committed
2734
2735
{
    // Check for duplicate
2736
    uint256 hash = block.GetHash();
2737
    BlockMap::iterator it = mapBlockIndex.find(hash);
2738
2739
    if (it != mapBlockIndex.end())
        return it->second;
s_nakamoto's avatar
s_nakamoto committed
2740
2741

    // Construct new block index object
2742
    CBlockIndex* pindexNew = new CBlockIndex(block);
2743
    assert(pindexNew);
Pieter Wuille's avatar
Pieter Wuille committed
2744
2745
2746
2747
    // 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;
2748
    BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
s_nakamoto's avatar
s_nakamoto committed
2749
    pindexNew->phashBlock = &((*mi).first);
2750
    BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock);
s_nakamoto's avatar
s_nakamoto committed
2751
2752
2753
2754
    if (miPrev != mapBlockIndex.end())
    {
        pindexNew->pprev = (*miPrev).second;
        pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
2755
        pindexNew->BuildSkip();
s_nakamoto's avatar
s_nakamoto committed
2756
    }
2757
    pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew);
2758
    pindexNew->RaiseValidity(BLOCK_VALID_TREE);
Pieter Wuille's avatar
Pieter Wuille committed
2759
2760
2761
    if (pindexBestHeader == NULL || pindexBestHeader->nChainWork < pindexNew->nChainWork)
        pindexBestHeader = pindexNew;

2762
    setDirtyBlockIndex.insert(pindexNew);
2763
2764
2765
2766

    return pindexNew;
}

2767
/** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */
2768
2769
bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos)
{
2770
    pindexNew->nTx = block.vtx.size();
Pieter Wuille's avatar
Pieter Wuille committed
2771
    pindexNew->nChainTx = 0;
2772
2773
    pindexNew->nFile = pos.nFile;
    pindexNew->nDataPos = pos.nPos;
Pieter Wuille's avatar
Pieter Wuille committed
2774
    pindexNew->nUndoPos = 0;
2775
    pindexNew->nStatus |= BLOCK_HAVE_DATA;
Pieter Wuille's avatar
Pieter Wuille committed
2776
    pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
2777
    setDirtyBlockIndex.insert(pindexNew);
2778

Pieter Wuille's avatar
Pieter Wuille committed
2779
2780
2781
2782
    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
2783

Pieter Wuille's avatar
Pieter Wuille committed
2784
2785
2786
2787
2788
        // 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;
2789
2790
2791
2792
            {
                LOCK(cs_nBlockSequenceId);
                pindex->nSequenceId = nBlockSequenceId++;
            }
2793
2794
2795
            if (chainActive.Tip() == NULL || !setBlockIndexCandidates.value_comp()(pindex, chainActive.Tip())) {
                setBlockIndexCandidates.insert(pindex);
            }
Pieter Wuille's avatar
Pieter Wuille committed
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
            std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex);
            while (range.first != range.second) {
                std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
                queue.push_back(it->second);
                range.first++;
                mapBlocksUnlinked.erase(it);
            }
        }
    } else {
        if (pindexNew->pprev && pindexNew->pprev->IsValid(BLOCK_VALID_TREE)) {
            mapBlocksUnlinked.insert(std::make_pair(pindexNew->pprev, pindexNew));
        }
    }
2809

s_nakamoto's avatar
s_nakamoto committed
2810
2811
2812
    return true;
}

2813
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
2814
2815
2816
{
    LOCK(cs_LastBlockFile);

2817
2818
2819
2820
2821
2822
2823
2824
    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());
2825
            FlushBlockFile(true);
2826
2827
2828
2829
            nFile++;
            if (vinfoBlockFile.size() <= nFile) {
                vinfoBlockFile.resize(nFile + 1);
            }
2830
        }
2831
2832
        pos.nFile = nFile;
        pos.nPos = vinfoBlockFile[nFile].nSize;
Pieter Wuille's avatar
Pieter Wuille committed
2833
2834
    }

2835
2836
    nLastBlockFile = nFile;
    vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
2837
    if (fKnown)
2838
        vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
2839
    else
2840
        vinfoBlockFile[nFile].nSize += nAddSize;
Pieter Wuille's avatar
Pieter Wuille committed
2841

2842
2843
    if (!fKnown) {
        unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
2844
        unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
2845
        if (nNewChunks > nOldChunks) {
2846
2847
2848
            if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) {
                FILE *file = OpenBlockFile(pos);
                if (file) {
2849
                    LogPrintf("Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile);
2850
2851
2852
                    AllocateFileRange(file, pos.nPos, nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos);
                    fclose(file);
                }
2853
            }
2854
            else
2855
                return state.Error("out of disk space");
2856
2857
2858
        }
    }

2859
    setDirtyFileInfo.insert(nFile);
Pieter Wuille's avatar
Pieter Wuille committed
2860
2861
2862
    return true;
}

Pieter Wuille's avatar
Pieter Wuille committed
2863
bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize)
Pieter Wuille's avatar
Pieter Wuille committed
2864
2865
2866
2867
2868
{
    pos.nFile = nFile;

    LOCK(cs_LastBlockFile);

2869
    unsigned int nNewSize;
2870
2871
    pos.nPos = vinfoBlockFile[nFile].nUndoSize;
    nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize;
2872
    setDirtyFileInfo.insert(nFile);
2873
2874
2875
2876

    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) {
2877
2878
2879
        if (CheckDiskSpace(nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos)) {
            FILE *file = OpenUndoFile(pos);
            if (file) {
2880
                LogPrintf("Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile);
2881
2882
2883
                AllocateFileRange(file, pos.nPos, nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos);
                fclose(file);
            }
2884
        }
2885
        else
2886
            return state.Error("out of disk space");
Pieter Wuille's avatar
Pieter Wuille committed
2887
2888
2889
2890
2891
    }

    return true;
}

2892
bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW)
s_nakamoto's avatar
s_nakamoto committed
2893
{
2894
    // Check proof of work matches claimed amount
2895
    if (fCheckPOW && !CheckProofOfWork(block))
2896
        return state.DoS(50, error("CheckBlockHeader() : proof of work failed"),
2897
                         REJECT_INVALID, "high-hash");
2898

s_nakamoto's avatar
s_nakamoto committed
2899
    // Check timestamp
2900
    if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
2901
        return state.Invalid(error("CheckBlockHeader() : block timestamp too far in the future"),
2902
                             REJECT_INVALID, "time-too-new");
s_nakamoto's avatar
s_nakamoto committed
2903

2904
2905
2906
    return true;
}

2907
bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot)
s_nakamoto's avatar
s_nakamoto committed
2908
{
Pieter Wuille's avatar
Pieter Wuille committed
2909
    // These are checks that are independent of context.
s_nakamoto's avatar
s_nakamoto committed
2910

2911
2912
2913
    if (block.fChecked)
        return true;

2914
2915
    // Check that the header is valid (particularly PoW).  This is mostly
    // redundant with the call in AcceptBlockHeader.
2916
2917
2918
    if (!CheckBlockHeader(block, state, fCheckPOW))
        return false;

Pieter Wuille's avatar
Pieter Wuille committed
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
    // 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
2939
    // Size limits
2940
    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
2941
        return state.DoS(100, error("CheckBlock() : size limits failed"),
2942
                         REJECT_INVALID, "bad-blk-length");
s_nakamoto's avatar
s_nakamoto committed
2943
2944

    // First transaction must be coinbase, the rest must not be
2945
    if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
Gavin Andresen's avatar
Gavin Andresen committed
2946
        return state.DoS(100, error("CheckBlock() : first tx is not coinbase"),
2947
                         REJECT_INVALID, "bad-cb-missing");
2948
2949
    for (unsigned int i = 1; i < block.vtx.size(); i++)
        if (block.vtx[i].IsCoinBase())
Gavin Andresen's avatar
Gavin Andresen committed
2950
            return state.DoS(100, error("CheckBlock() : more than one coinbase"),
2951
                             REJECT_INVALID, "bad-cb-multiple");
s_nakamoto's avatar
s_nakamoto committed
2952

Evan Duffield's avatar
Evan Duffield committed
2953
2954
2955

    // ----------- instantX transaction scanning -----------

Evan Duffield's avatar
Evan Duffield committed
2956
    if(IsSporkActive(SPORK_3_INSTANTX_BLOCK_FILTERING)){
2957
2958
2959
2960
2961
2962
        BOOST_FOREACH(const CTransaction& tx, block.vtx){
            if (!tx.IsCoinBase()){
                //only reject blocks when it's based on complete consensus
                BOOST_FOREACH(const CTxIn& in, tx.vin){
                    if(mapLockedInputs.count(in.prevout)){
                        if(mapLockedInputs[in.prevout] != tx.GetHash()){
2963
                            mapRejectedBlocks.insert(make_pair(block.GetHash(), GetTime()));
2964
                            LogPrintf("CheckBlock() : found conflicting transaction with transaction lock %s %s\n", mapLockedInputs[in.prevout].ToString(), tx.GetHash().ToString());
2965
2966
                            return state.DoS(0, error("CheckBlock() : found conflicting transaction with transaction lock"),
                                             REJECT_INVALID, "conflicting-tx-ix");
2967
                        }
Evan Duffield's avatar
Evan Duffield committed
2968
2969
2970
2971
                    }
                }
            }
        }
2972
    } else {
Evan Duffield's avatar
Evan Duffield committed
2973
        LogPrintf("CheckBlock() : skipping transaction locking checks\n");
Evan Duffield's avatar
Evan Duffield committed
2974
    }
Evan Duffield's avatar
Evan Duffield committed
2975
2976


2977
    // ----------- masternode payments / budgets -----------
Evan Duffield's avatar
Evan Duffield committed
2978

2979
    CBlockIndex* pindexPrev = chainActive.Tip();
UdjinM6's avatar
UdjinM6 committed
2980
    if(pindexPrev != NULL)
2981
    {
2982
2983
        int nHeight = 0;
        if(pindexPrev->GetBlockHash() == block.hashPrevBlock)
2984
        {
2985
2986
            nHeight = pindexPrev->nHeight+1;
        } else { //out of order
2987
2988
2989
            BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
            if (mi != mapBlockIndex.end() && (*mi).second)
                nHeight = (*mi).second->nHeight+1;
2990
2991
2992
2993
2994
        }

        if(nHeight != 0){
            if(!IsBlockPayeeValid(block.vtx[0], nHeight))
            {
2995
2996
                mapRejectedBlocks.insert(make_pair(block.GetHash(), GetTime()));
                return state.DoS(100, error("CheckBlock() : Couldn't find masternode/budget payment"));
2997
2998
            }
        } else {
UdjinM6's avatar
UdjinM6 committed
2999
            LogPrintf("CheckBlock() : WARNING: Couldn't find previous block, skipping IsBlockPayeeValid()\n");
3000
3001
3002
        }
    }

3003
    // -------------------------------------------
3004

s_nakamoto's avatar
s_nakamoto committed
3005
    // Check transactions
3006
    BOOST_FOREACH(const CTransaction& tx, block.vtx)
3007
        if (!CheckTransaction(tx, state))
Pieter Wuille's avatar
Pieter Wuille committed
3008
            return error("CheckBlock() : CheckTransaction failed");
s_nakamoto's avatar
s_nakamoto committed
3009

3010
    unsigned int nSigOps = 0;
3011
    BOOST_FOREACH(const CTransaction& tx, block.vtx)
Gavin Andresen's avatar
Gavin Andresen committed
3012
    {
3013
        nSigOps += GetLegacySigOpCount(tx);
Gavin Andresen's avatar
Gavin Andresen committed
3014
3015
    }
    if (nSigOps > MAX_BLOCK_SIGOPS)
Gavin Andresen's avatar
Gavin Andresen committed
3016
        return state.DoS(100, error("CheckBlock() : out-of-bounds SigOpCount"),
3017
                         REJECT_INVALID, "bad-blk-sigops", true);
s_nakamoto's avatar
s_nakamoto committed
3018

3019
3020
3021
    if (fCheckPOW && fCheckMerkleRoot)
        block.fChecked = true;

s_nakamoto's avatar
s_nakamoto committed
3022
3023
3024
    return true;
}

3025
bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev)
s_nakamoto's avatar
s_nakamoto committed
3026
{
3027
    uint256 hash = block.GetHash();
3028
3029
    if (hash == Params().HashGenesisBlock())
        return true;
s_nakamoto's avatar
s_nakamoto committed
3030

3031
    assert(pindexPrev);
3032

3033
    int nHeight = pindexPrev->nHeight+1;
3034

3035
3036
3037
3038
3039
3040
3041
    // Disallow legacy blocks after merge-mining start.
    if (nHeight >= Params().AuxpowStartHeight()
        && block.nVersion.IsLegacy())
        return state.DoS(100, error("%s : legacy block after auxpow start",
                                    __func__),
                         REJECT_INVALID, "late-legacy-block");

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

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

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

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

3063
    // Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
3064
    if (block.nVersion.GetBaseVersion() < 2 &&
3065
3066
3067
3068
        CBlockIndex::IsSuperMajority(2, pindexPrev, Params().RejectBlockOutdatedMajority()))
    {
        return state.Invalid(error("%s : rejected nVersion=1 block", __func__),
                             REJECT_OBSOLETE, "bad-version");
Pieter Wuille's avatar
Pieter Wuille committed
3069
    }
s_nakamoto's avatar
s_nakamoto committed
3070

Pieter Wuille's avatar
Pieter Wuille committed
3071
    // Reject block.nVersion=2 blocks when 95% (75% on testnet) of the network has upgraded:
3072
    if (block.nVersion.GetBaseVersion() < 3 && CBlockIndex::IsSuperMajority(3, pindexPrev, Params().RejectBlockOutdatedMajority()))
3073
    {
Pieter Wuille's avatar
Pieter Wuille committed
3074
3075
        return state.Invalid(error("%s : rejected nVersion=2 block", __func__),
                             REJECT_OBSOLETE, "bad-version");
3076
    }
s_nakamoto's avatar
s_nakamoto committed
3077
3078
3079
3080

    return true;
}

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

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

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

3103
    return true;
3104
3105
}

Pieter Wuille's avatar
Pieter Wuille committed
3106
bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex)
s_nakamoto's avatar
s_nakamoto committed
3107
{
3108
    AssertLockHeld(cs_main);
s_nakamoto's avatar
s_nakamoto committed
3109
    // Check for duplicate
3110
    uint256 hash = block.GetHash();
3111
    BlockMap::iterator miSelf = mapBlockIndex.find(hash);
3112
    CBlockIndex *pindex = NULL;
3113
3114

    // TODO : ENABLE BLOCK CACHE IN SPECIFIC CASES
Evan Duffield's avatar
Evan Duffield committed
3115
3116
3117
3118
3119
3120
3121
3122
3123
    if (miSelf != mapBlockIndex.end()) {
        // Block header is already known.
        pindex = miSelf->second;
        if (ppindex)
            *ppindex = pindex;
        if (pindex->nStatus & BLOCK_FAILED_MASK)
            return state.Invalid(error("%s : block is marked invalid", __func__), 0, "duplicate");
        return true;
    }
3124

3125
    if (!CheckBlockHeader(block, state))
3126
        return false;
3127

s_nakamoto's avatar
s_nakamoto committed
3128
    // Get prev block index
3129
    CBlockIndex* pindexPrev = NULL;
3130
    if (hash != Params().HashGenesisBlock()) {
3131
        BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
3132
        if (mi == mapBlockIndex.end())
3133
            return state.DoS(0, error("%s : prev block not found", __func__), 0, "bad-prevblk");
3134
        pindexPrev = (*mi).second;
3135
3136
        if (pindexPrev->nStatus & BLOCK_FAILED_MASK)
            return state.DoS(100, error("%s : prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
3137
    }
3138

3139
3140
    if (!ContextualCheckBlockHeader(block, state, pindexPrev))
        return false;
s_nakamoto's avatar
s_nakamoto committed
3141

3142
3143
    if (pindex == NULL)
        pindex = AddToBlockIndex(block);
s_nakamoto's avatar
s_nakamoto committed
3144

3145
3146
3147
3148
3149
    if (ppindex)
        *ppindex = pindex;

    return true;
}
3150

3151
3152
3153
bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, CDiskBlockPos* dbp)
{
    AssertLockHeld(cs_main);
s_nakamoto's avatar
s_nakamoto committed
3154

3155
    CBlockIndex *&pindex = *ppindex;
3156

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

Pieter Wuille's avatar
Pieter Wuille committed
3160
3161
3162
    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");
s_nakamoto's avatar
s_nakamoto committed
3163
3164
3165
        return true;
    }

3166
    if ((!CheckBlock(block, state)) || !ContextualCheckBlock(block, state, pindex->pprev)) {
3167
        if (state.IsInvalid() && !state.CorruptionPossible()) {
3168
            pindex->nStatus |= BLOCK_FAILED_VALID;
3169
            setDirtyBlockIndex.insert(pindex);
s_nakamoto's avatar
s_nakamoto committed
3170
        }
3171
        return false;
s_nakamoto's avatar
s_nakamoto committed
3172
3173
    }

3174
3175
    int nHeight = pindex->nHeight;

s_nakamoto's avatar
s_nakamoto committed
3176
    // Write block to history file
Pieter Wuille's avatar
Pieter Wuille committed
3177
    try {
3178
        unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
Pieter Wuille's avatar
Pieter Wuille committed
3179
3180
3181
        CDiskBlockPos blockPos;
        if (dbp != NULL)
            blockPos = *dbp;
jtimon's avatar
jtimon committed
3182
        if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL))
Pieter Wuille's avatar
Pieter Wuille committed
3183
3184
            return error("AcceptBlock() : FindBlockPos failed");
        if (dbp == NULL)
3185
            if (!WriteBlockToDisk(block, blockPos))
3186
                return state.Abort("Failed to write block");
3187
3188
        if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
            return error("AcceptBlock() : ReceivedBlockTransactions failed");
Pieter Wuille's avatar
Pieter Wuille committed
3189
    } catch(std::runtime_error &e) {
3190
        return state.Abort(std::string("System error: ") + e.what());
3191
    }
3192

s_nakamoto's avatar
s_nakamoto committed
3193
3194
3195
    return true;
}

3196
bool CBlockIndex::IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired)
3197
{
3198
    unsigned int nToCheck = Params().ToCheckBlockUpgradeMajority();
3199
3200
3201
    unsigned int nFound = 0;
    for (unsigned int i = 0; i < nToCheck && nFound < nRequired && pstart != NULL; i++)
    {
3202
        if (pstart->nVersion.GetBaseVersion() >= minVersion)
3203
3204
3205
3206
3207
3208
            ++nFound;
        pstart = pstart->pprev;
    }
    return (nFound >= nRequired);
}

3209
3210
/** 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); }
s_nakamoto's avatar
s_nakamoto committed
3211

3212
3213
3214
3215
/** Compute what height to jump back to with the CBlockIndex::pskip pointer. */
int static inline GetSkipHeight(int height) {
    if (height < 2)
        return 0;
s_nakamoto's avatar
s_nakamoto committed
3216

3217
3218
3219
3220
3221
    // 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);
}
s_nakamoto's avatar
s_nakamoto committed
3222

3223
CBlockIndex* CBlockIndex::GetAncestor(int height)
3224
{
3225
3226
    if (height > nHeight || height < 0)
        return NULL;
3227

3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
    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--;
3242
3243
        }
    }
3244
    return pindexWalk;
3245
3246
}

3247
3248
3249
3250
const CBlockIndex* CBlockIndex::GetAncestor(int height) const
{
    return const_cast<CBlockIndex*>(this)->GetAncestor(height);
}
3251

3252
3253
3254
3255
3256
void CBlockIndex::BuildSkip()
{
    if (pprev)
        pskip = pprev->GetAncestor(GetSkipHeight(nHeight));
}
3257

3258
bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp)
s_nakamoto's avatar
s_nakamoto committed
3259
3260
{
    // Preliminary checks
Pieter Wuille's avatar
Pieter Wuille committed
3261
    bool checked = CheckBlock(*pblock, state);
3262

UdjinM6's avatar
UdjinM6 committed
3263
3264
    while(true) {
        TRY_LOCK(cs_main, lockMain);
UdjinM6's avatar
UdjinM6 committed
3265
        if(!lockMain) { MilliSleep(50); continue; }
UdjinM6's avatar
UdjinM6 committed
3266

Pieter Wuille's avatar
Pieter Wuille committed
3267
3268
        MarkBlockAsReceived(pblock->GetHash());
        if (!checked) {
3269
            return error("%s : CheckBlock FAILED", __func__);
3270
        }
3271

Pieter Wuille's avatar
Pieter Wuille committed
3272
3273
3274
3275
3276
        // 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
3277
        }
3278
        CheckBlockIndex();
Pieter Wuille's avatar
Pieter Wuille committed
3279
        if (!ret)
3280
            return error("%s : AcceptBlock FAILED", __func__);
UdjinM6's avatar
UdjinM6 committed
3281
        break;
Pieter Wuille's avatar
Pieter Wuille committed
3282
3283
    }

3284
    if (!ActivateBestChain(state, pblock))
3285
        return error("%s : ActivateBestChain failed", __func__);
Pieter Wuille's avatar
Pieter Wuille committed
3286

3287
    if(!fLiteMode){
infernoman's avatar
infernoman committed
3288
        if (masternodeSync.RequestedThroneAssets > THRONE_SYNC_LIST) {
3289
3290
            darkSendPool.NewBlock();
            masternodePayments.ProcessBlock(GetHeight()+10);
Evan Duffield's avatar
Evan Duffield committed
3291
            budget.NewBlock();
Pieter Wuille's avatar
Pieter Wuille committed
3292
3293
3294
        }
    }

3295
    LogPrintf("%s : ACCEPTED\n", __func__);
s_nakamoto's avatar
s_nakamoto committed
3296
3297
    return true;
}
Pieter Wuille's avatar
Pieter Wuille committed
3298

3299
3300
3301
3302
bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot)
{
    AssertLockHeld(cs_main);
    assert(pindexPrev == chainActive.Tip());
Pieter Wuille's avatar
Pieter Wuille committed
3303

3304
3305
3306
3307
    CCoinsViewCache viewNew(pcoinsTip);
    CBlockIndex indexDummy(block);
    indexDummy.pprev = pindexPrev;
    indexDummy.nHeight = pindexPrev->nHeight + 1;
Pieter Wuille's avatar
Pieter Wuille committed
3308

3309
3310
3311
3312
    // NOTE: CheckBlockHeader is called by CheckBlock
    if (!ContextualCheckBlockHeader(block, state, pindexPrev))
        return false;
    if (!CheckBlock(block, state, fCheckPOW, fCheckMerkleRoot))
3313
        return false;
3314
    if (!ContextualCheckBlock(block, state, pindexPrev))
3315
        return false;
3316
3317
3318
    if (!ConnectBlock(block, state, &indexDummy, viewNew, true))
        return false;
    assert(state.IsValid());
Pieter Wuille's avatar
Pieter Wuille committed
3319

3320
    return true;
Pieter Wuille's avatar
Pieter Wuille committed
3321
3322
3323
3324
3325
3326
3327
3328
}







s_nakamoto's avatar
s_nakamoto committed
3329

3330
bool AbortNode(const std::string &strMessage, const std::string &userMessage) {
3331
    strMiscWarning = strMessage;
3332
    LogPrintf("*** %s\n", strMessage);
3333
3334
3335
    uiInterface.ThreadSafeMessageBox(
        userMessage.empty() ? _("Error: A fatal internal error occured, see debug.log for details") : userMessage,
        "", CClientUIInterface::MSG_ERROR);
3336
3337
3338
    StartShutdown();
    return false;
}
Pieter Wuille's avatar
Pieter Wuille committed
3339

3340
bool CheckDiskSpace(uint64_t nAdditionalBytes)
s_nakamoto's avatar
s_nakamoto committed
3341
{
3342
    uint64_t nFreeBytesAvailable = filesystem::space(GetDataDir()).available;
s_nakamoto's avatar
s_nakamoto committed
3343

3344
3345
    // Check for nMinDiskSpace bytes (currently 50MB)
    if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
3346
        return AbortNode("Disk space is low!", _("Error: Disk space is low!"));
3347

s_nakamoto's avatar
s_nakamoto committed
3348
3349
3350
    return true;
}

Pieter Wuille's avatar
Pieter Wuille committed
3351
FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly)
3352
{
Pieter Wuille's avatar
Pieter Wuille committed
3353
    if (pos.IsNull())
s_nakamoto's avatar
s_nakamoto committed
3354
        return NULL;
3355
    boost::filesystem::path path = GetBlockPosFilename(pos, prefix);
Pieter Wuille's avatar
Pieter Wuille committed
3356
3357
3358
3359
    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
3360
    if (!file) {
3361
        LogPrintf("Unable to open file %s\n", path.string());
s_nakamoto's avatar
s_nakamoto committed
3362
        return NULL;
Pieter Wuille's avatar
Pieter Wuille committed
3363
    }
Pieter Wuille's avatar
Pieter Wuille committed
3364
3365
    if (pos.nPos) {
        if (fseek(file, pos.nPos, SEEK_SET)) {
3366
            LogPrintf("Unable to seek to position %u of %s\n", pos.nPos, path.string());
Pieter Wuille's avatar
Pieter Wuille committed
3367
3368
3369
3370
            fclose(file);
            return NULL;
        }
    }
s_nakamoto's avatar
s_nakamoto committed
3371
3372
3373
    return file;
}

Pieter Wuille's avatar
Pieter Wuille committed
3374
3375
3376
3377
FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly) {
    return OpenDiskFile(pos, "blk", fReadOnly);
}

3378
FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly) {
Pieter Wuille's avatar
Pieter Wuille committed
3379
3380
3381
    return OpenDiskFile(pos, "rev", fReadOnly);
}

3382
3383
boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix)
{
Suhas Daftuar's avatar
Suhas Daftuar committed
3384
    return GetDataDir() / "blocks" / strprintf("%s%05u.dat", prefix, pos.nFile);
3385
3386
}

3387
3388
3389
3390
3391
3392
CBlockIndex * InsertBlockIndex(uint256 hash)
{
    if (hash == 0)
        return NULL;

    // Return existing
3393
    BlockMap::iterator mi = mapBlockIndex.find(hash);
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
    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
3412
    boost::this_thread::interruption_point();
3413

Pieter Wuille's avatar
Pieter Wuille committed
3414
    // Calculate nChainWork
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
    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;
3426
        pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + GetBlockProof(*pindex);
Pieter Wuille's avatar
Pieter Wuille committed
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
        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))
3440
            setBlockIndexCandidates.insert(pindex);
3441
3442
        if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->nChainWork > pindexBestInvalid->nChainWork))
            pindexBestInvalid = pindex;
3443
3444
        if (pindex->pprev)
            pindex->BuildSkip();
Pieter Wuille's avatar
Pieter Wuille committed
3445
3446
        if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == NULL || CBlockIndexWorkComparator()(pindexBestHeader, pindex)))
            pindexBestHeader = pindex;
3447
3448
3449
3450
    }

    // Load block file info
    pblocktree->ReadLastBlockFile(nLastBlockFile);
3451
    vinfoBlockFile.resize(nLastBlockFile + 1);
3452
    LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile);
3453
3454
3455
    for (int nFile = 0; nFile <= nLastBlockFile; nFile++) {
        pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]);
    }
3456
    LogPrintf("%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString());
3457
3458
3459
3460
3461
3462
3463
3464
    for (int nFile = nLastBlockFile + 1; true; nFile++) {
        CBlockFileInfo info;
        if (pblocktree->ReadBlockFileInfo(nFile, info)) {
            vinfoBlockFile.push_back(info);
        } else {
            break;
        }
    }
3465

3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
    // 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);
3479
        if (CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION).IsNull()) {
3480
3481
3482
            return false;
        }
    }
3483

3484
3485
3486
3487
3488
    // Check whether we need to continue reindexing
    bool fReindexing = false;
    pblocktree->ReadReindexing(fReindexing);
    fReindex |= fReindexing;

3489
3490
    // Check whether we have a transaction index
    pblocktree->ReadFlag("txindex", fTxIndex);
3491
    LogPrintf("LoadBlockIndexDB(): transaction index %s\n", fTxIndex ? "enabled" : "disabled");
3492

3493
    // Load pointer to end of best chain
3494
    BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
3495
    if (it == mapBlockIndex.end())
3496
        return true;
3497
    chainActive.SetTip(it->second);
3498
3499
3500

    PruneBlockIndexCandidates();

3501
    LogPrintf("LoadBlockIndexDB(): hashBestChain=%s height=%d date=%s progress=%f\n",
3502
        chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(),
3503
3504
        DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
        Checkpoints::GuessVerificationProgress(chainActive.Tip()));
3505

Pieter Wuille's avatar
Pieter Wuille committed
3506
3507
3508
    return true;
}

Cozz Lovan's avatar
Cozz Lovan committed
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
CVerifyDB::CVerifyDB()
{
    uiInterface.ShowProgress(_("Verifying blocks..."), 0);
}

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

3519
bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth)
3520
{
3521
    LOCK(cs_main);
3522
    if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL)
Pieter Wuille's avatar
Pieter Wuille committed
3523
3524
        return true;

3525
    // Verify blocks in the best chain
3526
    if (nCheckDepth <= 0)
3527
        nCheckDepth = 1000000000; // suffices until the year 19000
3528
3529
    if (nCheckDepth > chainActive.Height())
        nCheckDepth = chainActive.Height();
Pieter Wuille's avatar
Pieter Wuille committed
3530
    nCheckLevel = std::max(0, std::min(4, nCheckLevel));
3531
    LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
3532
    CCoinsViewCache coins(coinsview);
3533
    CBlockIndex* pindexState = chainActive.Tip();
Pieter Wuille's avatar
Pieter Wuille committed
3534
3535
    CBlockIndex* pindexFailure = NULL;
    int nGoodTransactions = 0;
Pieter Wuille's avatar
Pieter Wuille committed
3536
    CValidationState state;
3537
    for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev)
3538
    {
Gavin Andresen's avatar
Gavin Andresen committed
3539
        boost::this_thread::interruption_point();
Cozz Lovan's avatar
Cozz Lovan committed
3540
        uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100)))));
3541
        if (pindex->nHeight < chainActive.Height()-nCheckDepth)
3542
3543
            break;
        CBlock block;
Pieter Wuille's avatar
Pieter Wuille committed
3544
        // check level 0: read from disk
3545
        if (!ReadBlockFromDisk(block, pindex))
3546
            return error("VerifyDB() : *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
3547
        // check level 1: verify block validity
3548
        if (nCheckLevel >= 1 && !CheckBlock(block, state))
3549
            return error("VerifyDB() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
Pieter Wuille's avatar
Pieter Wuille committed
3550
3551
3552
3553
3554
3555
        // 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()))
3556
                    return error("VerifyDB() : *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
Pieter Wuille's avatar
Pieter Wuille committed
3557
3558
3559
            }
        }
        // check level 3: check for inconsistencies during memory-only disconnect of tip blocks
3560
        if (nCheckLevel >= 3 && pindex == pindexState && (coins.GetCacheSize() + pcoinsTip->GetCacheSize()) <= nCoinCacheSize) {
Pieter Wuille's avatar
Pieter Wuille committed
3561
            bool fClean = true;
3562
            if (!DisconnectBlock(block, state, pindex, coins, &fClean))
3563
                return error("VerifyDB() : *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
Pieter Wuille's avatar
Pieter Wuille committed
3564
3565
3566
3567
3568
3569
            pindexState = pindex->pprev;
            if (!fClean) {
                nGoodTransactions = 0;
                pindexFailure = pindex;
            } else
                nGoodTransactions += block.vtx.size();
3570
        }
3571
3572
        if (ShutdownRequested())
            return true;
3573
    }
Pieter Wuille's avatar
Pieter Wuille committed
3574
    if (pindexFailure)
3575
        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
3576
3577
3578
3579

    // check level 4: try reconnecting blocks
    if (nCheckLevel >= 4) {
        CBlockIndex *pindex = pindexState;
3580
        while (pindex != chainActive.Tip()) {
Gavin Andresen's avatar
Gavin Andresen committed
3581
            boost::this_thread::interruption_point();
Cozz Lovan's avatar
Cozz Lovan committed
3582
            uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50))));
3583
            pindex = chainActive.Next(pindex);
3584
            CBlock block;
3585
            if (!ReadBlockFromDisk(block, pindex))
3586
                return error("VerifyDB() : *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
3587
            if (!ConnectBlock(block, state, pindex, coins))
3588
                return error("VerifyDB() : *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
Pieter Wuille's avatar
Pieter Wuille committed
3589
        }
3590
3591
    }

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

3594
3595
3596
    return true;
}

3597
3598
3599
void UnloadBlockIndex()
{
    mapBlockIndex.clear();
3600
    setBlockIndexCandidates.clear();
3601
    chainActive.SetTip(NULL);
3602
    pindexBestInvalid = NULL;
3603
3604
}

3605
bool LoadBlockIndex()
s_nakamoto's avatar
s_nakamoto committed
3606
{
3607
    // Load block index from databases
3608
    if (!fReindex && !LoadBlockIndexDB())
s_nakamoto's avatar
s_nakamoto committed
3609
        return false;
3610
3611
    return true;
}
3612
3613


3614
bool InitBlockIndex() {
3615
    LOCK(cs_main);
3616
    // Check whether we're already initialized
3617
    if (chainActive.Genesis() != NULL)
3618
3619
3620
        return true;

    // Use the provided setting for -txindex in the new database
Evan Duffield's avatar
Evan Duffield committed
3621
    fTxIndex = GetBoolArg("-txindex", true);
3622
    pblocktree->WriteFlag("txindex", fTxIndex);
3623
    LogPrintf("Initializing databases...\n");
3624
3625
3626
3627

    // Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
    if (!fReindex) {
        try {
3628
3629
            CBlock &block = const_cast<CBlock&>(Params().GenesisBlock());
            // Start new block file
3630
3631
3632
            unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
            CDiskBlockPos blockPos;
            CValidationState state;
jtimon's avatar
jtimon committed
3633
            if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.GetBlockTime()))
3634
                return error("LoadBlockIndex() : FindBlockPos failed");
3635
            if (!WriteBlockToDisk(block, blockPos))
3636
                return error("LoadBlockIndex() : writing genesis block to disk failed");
3637
3638
            CBlockIndex *pindex = AddToBlockIndex(block);
            if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
3639
                return error("LoadBlockIndex() : genesis block not accepted");
3640
            if (!ActivateBestChain(state, &block))
3641
                return error("LoadBlockIndex() : genesis block cannot be activated");
3642
            // Force a chainstate write so that when we VerifyDB in a moment, it doesnt check stale data
3643
            return FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
3644
3645
3646
        } catch(std::runtime_error &e) {
            return error("LoadBlockIndex() : failed to initialize block database: %s", e.what());
        }
s_nakamoto's avatar
s_nakamoto committed
3647
3648
3649
3650
3651
3652
3653
    }

    return true;
}



3654
bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
3655
{
3656
3657
    // Map of disk positions for blocks with unknown parent (only used for reindex)
    static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent;
3658
    int64_t nStart = GetTimeMillis();
3659

3660
    int nLoaded = 0;
Pieter Wuille's avatar
Pieter Wuille committed
3661
    try {
3662
        // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor
3663
        CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
3664
        uint64_t nRewind = blkdat.GetPos();
3665
        while (!blkdat.eof()) {
3666
3667
            boost::this_thread::interruption_point();

3668
3669
3670
            blkdat.SetPos(nRewind);
            nRewind++; // start one byte further next time, in case of failure
            blkdat.SetLimit(); // remove former limit
3671
            unsigned int nSize = 0;
3672
3673
            try {
                // locate a header
3674
                unsigned char buf[MESSAGE_START_SIZE];
3675
                blkdat.FindByte(Params().MessageStart()[0]);
3676
3677
                nRewind = blkdat.GetPos()+1;
                blkdat >> FLATDATA(buf);
3678
                if (memcmp(buf, Params().MessageStart(), MESSAGE_START_SIZE))
3679
3680
                    continue;
                // read size
3681
                blkdat >> nSize;
3682
3683
                if (nSize < 80 || nSize > MAX_BLOCK_SIZE)
                    continue;
ENikS's avatar
ENikS committed
3684
            } catch (const std::exception &) {
3685
3686
3687
3688
                // no valid block header found; don't complain
                break;
            }
            try {
3689
                // read block
3690
                uint64_t nBlockPos = blkdat.GetPos();
3691
3692
                if (dbp)
                    dbp->nPos = nBlockPos;
3693
                blkdat.SetLimit(nBlockPos + nSize);
3694
                blkdat.SetPos(nBlockPos);
3695
3696
3697
                CBlock block;
                blkdat >> block;
                nRewind = blkdat.GetPos();
3698

3699
3700
3701
                // detect out of order blocks, and store them for later
                uint256 hash = block.GetHash();
                if (hash != Params().HashGenesisBlock() && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) {
3702
                    LogPrint("reindex", "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
3703
                            block.hashPrevBlock.ToString());
3704
                    if (dbp)
3705
                        mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
3706
3707
3708
                    continue;
                }

3709
                // process in case the block isn't known yet
3710
                if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) {
Pieter Wuille's avatar
Pieter Wuille committed
3711
                    CValidationState state;
3712
                    if (ProcessNewBlock(state, NULL, &block, dbp))
3713
                        nLoaded++;
Pieter Wuille's avatar
Pieter Wuille committed
3714
3715
                    if (state.IsError())
                        break;
3716
3717
                } else if (hash != Params().HashGenesisBlock() && mapBlockIndex[hash]->nHeight % 1000 == 0) {
                    LogPrintf("Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->nHeight);
3718
                }
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733

                // 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;
3734
                            if (ProcessNewBlock(dummy, NULL, &block, &it->second))
3735
3736
3737
3738
3739
3740
3741
3742
                            {
                                nLoaded++;
                                queue.push_back(block.GetHash());
                            }
                        }
                        range.first++;
                        mapBlocksUnknownParent.erase(it);
                    }
3743
                }
3744
            } catch (std::exception &e) {
3745
                LogPrintf("%s : Deserialize or I/O error - %s", __func__, e.what());
3746
3747
            }
        }
Pieter Wuille's avatar
Pieter Wuille committed
3748
    } catch(std::runtime_error &e) {
3749
        AbortNode(std::string("System error: ") + e.what());
3750
    }
3751
    if (nLoaded > 0)
3752
        LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart);
3753
3754
    return nLoaded > 0;
}
s_nakamoto's avatar
s_nakamoto committed
3755

3756
3757
3758
3759
3760
3761
3762
3763
void static CheckBlockIndex()
{
    if (!fCheckBlockIndex) {
        return;
    }

    LOCK(cs_main);

3764
3765
3766
3767
3768
3769
3770
3771
    // During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain,
    // so we have the genesis block in mapBlockIndex but no active chain.  (A few of the tests when
    // iterating the block tree require that chainActive has been initialized.)
    if (chainActive.Height() < 0) {
        assert(mapBlockIndex.size() <= 1);
        return;
    }

3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
    // Build forward-pointing map of the entire block tree.
    std::multimap<CBlockIndex*,CBlockIndex*> forward;
    for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
        forward.insert(std::make_pair(it->second->pprev, it->second));
    }

    assert(forward.size() == mapBlockIndex.size());

    std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(NULL);
    CBlockIndex *pindex = rangeGenesis.first->second;
    rangeGenesis.first++;
    assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent NULL.

    // Iterate over the entire block tree, using depth-first search.
    // Along the way, remember whether there are blocks on the path from genesis
    // block being explored which are the first to have certain properties.
    size_t nNodes = 0;
    int nHeight = 0;
    CBlockIndex* pindexFirstInvalid = NULL; // Oldest ancestor of pindex which is invalid.
    CBlockIndex* pindexFirstMissing = NULL; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA.
    CBlockIndex* pindexFirstNotTreeValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not).
    CBlockIndex* pindexFirstNotChainValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not).
    CBlockIndex* pindexFirstNotScriptsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not).
    while (pindex != NULL) {
        nNodes++;
        if (pindexFirstInvalid == NULL && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex;
        if (pindexFirstMissing == NULL && !(pindex->nStatus & BLOCK_HAVE_DATA)) pindexFirstMissing = pindex;
        if (pindex->pprev != NULL && pindexFirstNotTreeValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindexFirstNotTreeValid = pindex;
        if (pindex->pprev != NULL && pindexFirstNotChainValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) pindexFirstNotChainValid = pindex;
        if (pindex->pprev != NULL && pindexFirstNotScriptsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) pindexFirstNotScriptsValid = pindex;

        // Begin: actual consistency checks.
        if (pindex->pprev == NULL) {
            // Genesis block checks.
            assert(pindex->GetBlockHash() == Params().HashGenesisBlock()); // Genesis block's hash must match.
            assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block.
        }
3809
3810
3811
3812
3813
        // HAVE_DATA is equivalent to VALID_TRANSACTIONS and equivalent to nTx > 0 (we stored the number of transactions in the block)
        assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0));
        assert(((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS) == (pindex->nTx > 0));
        if (pindex->nChainTx == 0) assert(pindex->nSequenceId == 0);  // nSequenceId can't be set for blocks that aren't linked
        // All parents having data is equivalent to all parents being VALID_TRANSACTIONS, which is equivalent to nChainTx being set.
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
        assert((pindexFirstMissing != NULL) == (pindex->nChainTx == 0)); // nChainTx == 0 is used to signal that all parent block's transaction data is available.
        assert(pindex->nHeight == nHeight); // nHeight must be consistent.
        assert(pindex->pprev == NULL || pindex->nChainWork >= pindex->pprev->nChainWork); // For every block except the genesis block, the chainwork must be larger than the parent's.
        assert(nHeight < 2 || (pindex->pskip && (pindex->pskip->nHeight < nHeight))); // The pskip pointer must point back for all but the first 2 blocks.
        assert(pindexFirstNotTreeValid == NULL); // All mapBlockIndex entries must at least be TREE valid
        if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE) assert(pindexFirstNotTreeValid == NULL); // TREE valid implies all parents are TREE valid
        if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_CHAIN) assert(pindexFirstNotChainValid == NULL); // CHAIN valid implies all parents are CHAIN valid
        if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_SCRIPTS) assert(pindexFirstNotScriptsValid == NULL); // SCRIPTS valid implies all parents are SCRIPTS valid
        if (pindexFirstInvalid == NULL) {
            // Checks for not-invalid blocks.
            assert((pindex->nStatus & BLOCK_FAILED_MASK) == 0); // The failed mask cannot be set for blocks without invalid parents.
        }
        if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && pindexFirstMissing == NULL) {
            if (pindexFirstInvalid == NULL) { // If this block sorts at least as good as the current tip and is valid, it must be in setBlockIndexCandidates.
                 assert(setBlockIndexCandidates.count(pindex));
            }
        } else { // If this block sorts worse than the current tip, it cannot be in setBlockIndexCandidates.
            assert(setBlockIndexCandidates.count(pindex) == 0);
        }
        // Check whether this block is in mapBlocksUnlinked.
        std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked = mapBlocksUnlinked.equal_range(pindex->pprev);
        bool foundInUnlinked = false;
        while (rangeUnlinked.first != rangeUnlinked.second) {
            assert(rangeUnlinked.first->first == pindex->pprev);
            if (rangeUnlinked.first->second == pindex) {
                foundInUnlinked = true;
                break;
            }
            rangeUnlinked.first++;
        }
        if (pindex->pprev && pindex->nStatus & BLOCK_HAVE_DATA && pindexFirstMissing != NULL) {
            if (pindexFirstInvalid == NULL) { // If this block has block data available, some parent doesn't, and has no invalid parents, it must be in mapBlocksUnlinked.
                assert(foundInUnlinked);
            }
        } else { // If this block does not have block data available, or all parents do, it cannot be in mapBlocksUnlinked.
            assert(!foundInUnlinked);
        }
        // assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow
        // End: actual consistency checks.

        // Try descending into the first subnode.
        std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
        if (range.first != range.second) {
            // A subnode was found.
            pindex = range.first->second;
            nHeight++;
            continue;
        }
        // This is a leaf node.
        // Move upwards until we reach a node of which we have not yet visited the last child.
        while (pindex) {
            // We are going to either move to a parent or a sibling of pindex.
            // If pindex was the first with a certain property, unset the corresponding variable.
            if (pindex == pindexFirstInvalid) pindexFirstInvalid = NULL;
            if (pindex == pindexFirstMissing) pindexFirstMissing = NULL;
            if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid = NULL;
            if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = NULL;
            if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = NULL;
            // Find our parent.
            CBlockIndex* pindexPar = pindex->pprev;
            // Find which child we just visited.
            std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
            while (rangePar.first->second != pindex) {
                assert(rangePar.first != rangePar.second); // Our parent must have at least the node we're coming from as child.
                rangePar.first++;
            }
            // Proceed to the next one.
            rangePar.first++;
            if (rangePar.first != rangePar.second) {
                // Move to the sibling.
                pindex = rangePar.first->second;
                break;
            } else {
                // Move up further.
                pindex = pindexPar;
                nHeight--;
                continue;
            }
        }
    }

    // Check that we actually traversed the entire map.
    assert(nNodes == forward.size());
}

s_nakamoto's avatar
s_nakamoto committed
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
//////////////////////////////////////////////////////////////////////////////
//
// CAlert
//

string GetWarnings(string strFor)
{
    int nPriority = 0;
    string strStatusBar;
    string strRPC;
3909
3910
3911
3912

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

3913
3914
3915
    if (GetBoolArg("-testsafemode", false))
        strStatusBar = strRPC = "testsafemode enabled";

s_nakamoto's avatar
s_nakamoto committed
3916
3917
3918
3919
3920
3921
3922
    // Misc warnings like out of disk space and clock is wrong
    if (strMiscWarning != "")
    {
        nPriority = 1000;
        strStatusBar = strMiscWarning;
    }

3923
    if (fLargeWorkForkFound)
s_nakamoto's avatar
s_nakamoto committed
3924
3925
    {
        nPriority = 2000;
3926
3927
3928
        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
3929
3930
    {
        nPriority = 2000;
3931
        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
3932
3933
3934
3935
    }

    // Alerts
    {
3936
        LOCK(cs_mapAlerts);
3937
        BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
s_nakamoto's avatar
s_nakamoto committed
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
        {
            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;
3952
    assert(!"GetWarnings() : invalid parameter");
s_nakamoto's avatar
s_nakamoto committed
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
    return "error";
}








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


3969
bool static AlreadyHave(const CInv& inv)
s_nakamoto's avatar
s_nakamoto committed
3970
3971
3972
{
    switch (inv.type)
    {
Jeff Garzik's avatar
Jeff Garzik committed
3973
3974
    case MSG_TX:
        {
Pieter Wuille's avatar
Pieter Wuille committed
3975
            bool txInMap = false;
3976
            txInMap = mempool.exists(inv.hash);
Pieter Wuille's avatar
Pieter Wuille committed
3977
            return txInMap || mapOrphanTransactions.count(inv.hash) ||
3978
                pcoinsTip->HaveCoins(inv.hash);
Jeff Garzik's avatar
Jeff Garzik committed
3979
        }
3980
3981
    case MSG_DSTX:
        return mapDarksendBroadcastTxes.count(inv.hash);
Jeff Garzik's avatar
Jeff Garzik committed
3982
    case MSG_BLOCK:
Pieter Wuille's avatar
Pieter Wuille committed
3983
        return mapBlockIndex.count(inv.hash);
3984
3985
3986
3987
3988
    case MSG_TXLOCK_REQUEST:
        return mapTxLockReq.count(inv.hash) ||
               mapTxLockReqRejected.count(inv.hash);
    case MSG_TXLOCK_VOTE:
        return mapTxLockVote.count(inv.hash);
Evan Duffield's avatar
Evan Duffield committed
3989
3990
    case MSG_SPORK:
        return mapSporks.count(inv.hash);
infernoman's avatar
infernoman committed
3991
    case MSG_THRONE_WINNER:
infernoman's avatar
infernoman committed
3992
3993
        if(masternodePayments.mapThronePayeeVotes.count(inv.hash)) {
            masternodeSync.AddedThroneWinner(inv.hash);
3994
3995
3996
            return true;
        }
        return false;
3997
    case MSG_BUDGET_VOTE:
infernoman's avatar
infernoman committed
3998
        if(budget.mapSeenThroneBudgetVotes.count(inv.hash)) {
3999
            masternodeSync.AddedBudgetItem(inv.hash);
4000
4001
4002
            return true;
        }
        return false;
4003
    case MSG_BUDGET_PROPOSAL:
infernoman's avatar
infernoman committed
4004
        if(budget.mapSeenThroneBudgetProposals.count(inv.hash)) {
4005
            masternodeSync.AddedBudgetItem(inv.hash);
4006
4007
4008
            return true;
        }
        return false;
4009
    case MSG_BUDGET_FINALIZED_VOTE:
4010
        if(budget.mapSeenFinalizedBudgetVotes.count(inv.hash)) {
4011
            masternodeSync.AddedBudgetItem(inv.hash);
4012
4013
4014
            return true;
        }
        return false;
4015
    case MSG_BUDGET_FINALIZED:
4016
        if(budget.mapSeenFinalizedBudgets.count(inv.hash)) {
4017
            masternodeSync.AddedBudgetItem(inv.hash);
4018
4019
4020
            return true;
        }
        return false;
infernoman's avatar
infernoman committed
4021
    case MSG_THRONE_ANNOUNCE:
infernoman's avatar
infernoman committed
4022
4023
        if(mnodeman.mapSeenThroneBroadcast.count(inv.hash)) {
            masternodeSync.AddedThroneList(inv.hash);
4024
4025
4026
            return true;
        }
        return false;
infernoman's avatar
infernoman committed
4027
    case MSG_THRONE_PING:
infernoman's avatar
infernoman committed
4028
        return mnodeman.mapSeenThronePing.count(inv.hash);
s_nakamoto's avatar
s_nakamoto committed
4029
4030
4031
4032
4033
4034
    }
    // Don't know what it is, just say we already got one
    return true;
}


4035
4036
4037
4038
4039
4040
void static ProcessGetData(CNode* pfrom)
{
    std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();

    vector<CInv> vNotFound;

4041
    LOCK(cs_main);
4042

4043
4044
4045
4046
4047
4048
4049
    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
4050
            boost::this_thread::interruption_point();
4051
4052
4053
4054
            it++;

            if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
            {
4055
                bool send = false;
4056
                BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
4057
4058
                if (mi != mapBlockIndex.end())
                {
4059
                    if (chainActive.Contains(mi->second)) {
Philip Kaufmann's avatar
Philip Kaufmann committed
4060
                        send = true;
4061
4062
4063
4064
4065
4066
4067
4068
4069
                    } else {
                        // To prevent fingerprinting attacks, only send blocks outside of the active
                        // chain if they are valid, and no more than a month older than the best header
                        // chain we know about.
                        send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
                            (mi->second->GetBlockTime() > pindexBestHeader->GetBlockTime() - 30 * 24 * 60 * 60);
                        if (!send) {
                            LogPrintf("ProcessGetData(): ignoring request from peer=%i for old block that isn't in the main chain\n", pfrom->GetId());
                        }
4070
4071
4072
4073
4074
                    }
                }
                if (send)
                {
                    // Send block from disk
4075
                    CBlock block;
4076
4077
                    if (!ReadBlockFromDisk(block, (*mi).second))
                        assert(!"cannot load block from disk");
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
                    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;
4109
                        vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash()));
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
                        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;
                    }
                }
4127

4128
                if (!pushed && inv.type == MSG_TX) {
Evan Duffield's avatar
Evan Duffield committed
4129

4130
4131
                    CTransaction tx;
                    if (mempool.lookup(inv.hash, tx)) {
4132
4133
                        CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
                        ss.reserve(1000);
4134
4135
                        ss << tx;
                        pfrom->PushMessage("tx", ss);
4136
4137
4138
                        pushed = true;
                    }
                }
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
                if (!pushed && inv.type == MSG_TXLOCK_VOTE) {
                    if(mapTxLockVote.count(inv.hash)){
                        CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
                        ss.reserve(1000);
                        ss << mapTxLockVote[inv.hash];
                        pfrom->PushMessage("txlvote", ss);
                        pushed = true;
                    }
                }
                if (!pushed && inv.type == MSG_TXLOCK_REQUEST) {
                    if(mapTxLockReq.count(inv.hash)){
                        CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
                        ss.reserve(1000);
                        ss << mapTxLockReq[inv.hash];
Evan Duffield's avatar
Evan Duffield committed
4153
                        pfrom->PushMessage("ix", ss);
4154
4155
4156
                        pushed = true;
                    }
                }
Evan Duffield's avatar
Evan Duffield committed
4157
4158
4159
4160
4161
4162
4163
4164
4165
                if (!pushed && inv.type == MSG_SPORK) {
                    if(mapSporks.count(inv.hash)){
                        CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
                        ss.reserve(1000);
                        ss << mapSporks[inv.hash];
                        pfrom->PushMessage("spork", ss);
                        pushed = true;
                    }
                }
infernoman's avatar
infernoman committed
4166
                if (!pushed && inv.type == MSG_THRONE_WINNER) {
infernoman's avatar
infernoman committed
4167
                    if(masternodePayments.mapThronePayeeVotes.count(inv.hash)){
4168
4169
                        CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
                        ss.reserve(1000);
infernoman's avatar
infernoman committed
4170
                        ss << masternodePayments.mapThronePayeeVotes[inv.hash];
4171
4172
4173
4174
                        pfrom->PushMessage("mnw", ss);
                        pushed = true;
                    }
                }
4175
                if (!pushed && inv.type == MSG_BUDGET_VOTE) {
infernoman's avatar
infernoman committed
4176
                    if(budget.mapSeenThroneBudgetVotes.count(inv.hash)){
4177
4178
                        CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
                        ss.reserve(1000);
infernoman's avatar
infernoman committed
4179
                        ss << budget.mapSeenThroneBudgetVotes[inv.hash];
4180
4181
4182
4183
4184
4185
                        pfrom->PushMessage("mvote", ss);
                        pushed = true;
                    }
                }

                if (!pushed && inv.type == MSG_BUDGET_PROPOSAL) {
infernoman's avatar
infernoman committed
4186
                    if(budget.mapSeenThroneBudgetProposals.count(inv.hash)){
4187
4188
                        CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
                        ss.reserve(1000);
infernoman's avatar
infernoman committed
4189
                        ss << budget.mapSeenThroneBudgetProposals[inv.hash];
4190
4191
4192
4193
                        pfrom->PushMessage("mprop", ss);
                        pushed = true;
                    }
                }
4194

4195
                if (!pushed && inv.type == MSG_BUDGET_FINALIZED_VOTE) {
4196
                    if(budget.mapSeenFinalizedBudgetVotes.count(inv.hash)){
4197
4198
                        CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
                        ss.reserve(1000);
4199
                        ss << budget.mapSeenFinalizedBudgetVotes[inv.hash];
4200
4201
4202
4203
4204
4205
                        pfrom->PushMessage("fbvote", ss);
                        pushed = true;
                    }
                }

                if (!pushed && inv.type == MSG_BUDGET_FINALIZED) {
4206
                    if(budget.mapSeenFinalizedBudgets.count(inv.hash)){
4207
4208
                        CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
                        ss.reserve(1000);
4209
                        ss << budget.mapSeenFinalizedBudgets[inv.hash];
4210
4211
4212
4213
                        pfrom->PushMessage("fbs", ss);
                        pushed = true;
                    }
                }
4214

infernoman's avatar
infernoman committed
4215
                if (!pushed && inv.type == MSG_THRONE_ANNOUNCE) {
infernoman's avatar
infernoman committed
4216
                    if(mnodeman.mapSeenThroneBroadcast.count(inv.hash)){
4217
4218
                        CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
                        ss.reserve(1000);
infernoman's avatar
infernoman committed
4219
                        ss << mnodeman.mapSeenThroneBroadcast[inv.hash];
4220
4221
4222
4223
4224
                        pfrom->PushMessage("mnb", ss);
                        pushed = true;
                    }
                }

infernoman's avatar
infernoman committed
4225
                if (!pushed && inv.type == MSG_THRONE_PING) {
infernoman's avatar
infernoman committed
4226
                    if(mnodeman.mapSeenThronePing.count(inv.hash)){
4227
4228
                        CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
                        ss.reserve(1000);
infernoman's avatar
infernoman committed
4229
                        ss << mnodeman.mapSeenThronePing[inv.hash];
4230
4231
4232
4233
4234
                        pfrom->PushMessage("mnp", ss);
                        pushed = true;
                    }
                }

4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
                if (!pushed && inv.type == MSG_DSTX) {       
                    if(mapDarksendBroadcastTxes.count(inv.hash)){
                        CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
                        ss.reserve(1000);
                        ss <<
                            mapDarksendBroadcastTxes[inv.hash].tx <<
                            mapDarksendBroadcastTxes[inv.hash].vin <<
                            mapDarksendBroadcastTxes[inv.hash].vchSig <<
                            mapDarksendBroadcastTxes[inv.hash].sigTime;

                        pfrom->PushMessage("dstx", ss);
                        pushed = true;
                    }
                }


4251
4252
4253
4254
4255
4256
                if (!pushed) {
                    vNotFound.push_back(inv);
                }
            }

            // Track requests for our stuff.
4257
            g_signals.Inventory(inv.hash);
4258

4259
4260
            if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
                break;
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
        }
    }

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

4278
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
s_nakamoto's avatar
s_nakamoto committed
4279
4280
{
    RandAddSeedPerfmon();
4281
    LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
s_nakamoto's avatar
s_nakamoto committed
4282
4283
    if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
    {
4284
        LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
s_nakamoto's avatar
s_nakamoto committed
4285
4286
4287
4288
4289
4290
4291
        return true;
    }

    if (strCommand == "version")
    {
        // Each connection can only send one version message
        if (pfrom->nVersion != 0)
4292
        {
Gavin Andresen's avatar
Gavin Andresen committed
4293
            pfrom->PushMessage("reject", strCommand, REJECT_DUPLICATE, string("Duplicate version message"));
Pieter Wuille's avatar
Pieter Wuille committed
4294
            Misbehaving(pfrom->GetId(), 1);
s_nakamoto's avatar
s_nakamoto committed
4295
            return false;
4296
        }
s_nakamoto's avatar
s_nakamoto committed
4297

4298
        int64_t nTime;
s_nakamoto's avatar
s_nakamoto committed
4299
4300
        CAddress addrMe;
        CAddress addrFrom;
4301
        uint64_t nNonce = 1;
s_nakamoto's avatar
s_nakamoto committed
4302
        vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
4303
        if (pfrom->nVersion < MIN_PEER_PROTO_VERSION)
Pieter Wuille's avatar
Pieter Wuille committed
4304
        {
4305
            // disconnect from peers older than this proto version
4306
            LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion);
Gavin Andresen's avatar
Gavin Andresen committed
4307
4308
            pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
                               strprintf("Version must be %d or greater", MIN_PEER_PROTO_VERSION));
Pieter Wuille's avatar
Pieter Wuille committed
4309
4310
4311
4312
            pfrom->fDisconnect = true;
            return false;
        }

s_nakamoto's avatar
s_nakamoto committed
4313
4314
        if (pfrom->nVersion == 10300)
            pfrom->nVersion = 300;
Pieter Wuille's avatar
Pieter Wuille committed
4315
        if (!vRecv.empty())
s_nakamoto's avatar
s_nakamoto committed
4316
            vRecv >> addrFrom >> nNonce;
Mike Hearn's avatar
Mike Hearn committed
4317
        if (!vRecv.empty()) {
4318
            vRecv >> LIMITED_STRING(pfrom->strSubVer, 256);
Mike Hearn's avatar
Mike Hearn committed
4319
4320
            pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
        }
Pieter Wuille's avatar
Pieter Wuille committed
4321
        if (!vRecv.empty())
s_nakamoto's avatar
s_nakamoto committed
4322
            vRecv >> pfrom->nStartingHeight;
4323
4324
4325
4326
        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
4327
4328
4329
4330

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

4336
4337
4338
4339
4340
4341
        pfrom->addrLocal = addrMe;
        if (pfrom->fInbound && addrMe.IsRoutable())
        {
            SeenLocal(addrMe);
        }

Gavin Andresen's avatar
Gavin Andresen committed
4342
4343
4344
4345
        // Be shy and don't send version until we hear
        if (pfrom->fInbound)
            pfrom->PushVersion();

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

4348
4349
        // Potentially mark this peer as a preferred download peer.
        UpdatePreferredDownload(pfrom, State(pfrom->GetId()));
s_nakamoto's avatar
s_nakamoto committed
4350
4351

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

s_nakamoto's avatar
s_nakamoto committed
4355
4356
4357
        if (!pfrom->fInbound)
        {
            // Advertise our address
4358
            if (fListen && !IsInitialBlockDownload())
s_nakamoto's avatar
s_nakamoto committed
4359
            {
4360
4361
                CAddress addr = GetLocalAddress(&pfrom->addr);
                if (addr.IsRoutable())
4362
                {
4363
                    pfrom->PushAddress(addr);
4364
4365
                } else if (IsPeerAddrLocalGood(pfrom)) {
                    addr.SetIP(pfrom->addrLocal);
4366
                    pfrom->PushAddress(addr);
4367
                }
s_nakamoto's avatar
s_nakamoto committed
4368
4369
4370
            }

            // Get recent addresses
4371
            if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000)
s_nakamoto's avatar
s_nakamoto committed
4372
4373
4374
4375
            {
                pfrom->PushMessage("getaddr");
                pfrom->fGetAddr = true;
            }
4376
4377
4378
4379
4380
4381
4382
            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
4383
4384
        }

s_nakamoto's avatar
s_nakamoto committed
4385
        // Relay alerts
4386
4387
        {
            LOCK(cs_mapAlerts);
4388
            BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
s_nakamoto's avatar
s_nakamoto committed
4389
                item.second.RelayTo(pfrom);
4390
        }
s_nakamoto's avatar
s_nakamoto committed
4391
4392
4393

        pfrom->fSuccessfullyConnected = true;

4394
4395
4396
4397
4398
4399
4400
4401
        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);
4402

4403
        AddTimeData(pfrom->addr, nTime);
s_nakamoto's avatar
s_nakamoto committed
4404
4405
4406
4407
4408
4409
    }


    else if (pfrom->nVersion == 0)
    {
        // Must have a version message before anything else
Pieter Wuille's avatar
Pieter Wuille committed
4410
        Misbehaving(pfrom->GetId(), 1);
s_nakamoto's avatar
s_nakamoto committed
4411
4412
4413
4414
4415
4416
        return false;
    }


    else if (strCommand == "verack")
    {
4417
        pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
4418
4419
4420
4421
4422
4423

        // Mark this node as currently connected, so we update its timestamp later.
        if (pfrom->fNetworkNode) {
            LOCK(cs_main);
            State(pfrom->GetId())->fCurrentlyConnected = true;
        }
s_nakamoto's avatar
s_nakamoto committed
4424
4425
4426
4427
4428
4429
4430
    }


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

        // Don't want addr from older versions unless seeding
4433
        if (pfrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000)
s_nakamoto's avatar
s_nakamoto committed
4434
4435
            return true;
        if (vAddr.size() > 1000)
4436
        {
Pieter Wuille's avatar
Pieter Wuille committed
4437
            Misbehaving(pfrom->GetId(), 20);
4438
            return error("message addr size() = %u", vAddr.size());
4439
        }
s_nakamoto's avatar
s_nakamoto committed
4440
4441

        // Store the new addresses
4442
        vector<CAddress> vAddrOk;
4443
4444
        int64_t nNow = GetAdjustedTime();
        int64_t nSince = nNow - 10 * 60;
4445
        BOOST_FOREACH(CAddress& addr, vAddr)
s_nakamoto's avatar
s_nakamoto committed
4446
        {
Gavin Andresen's avatar
Gavin Andresen committed
4447
4448
            boost::this_thread::interruption_point();

s_nakamoto's avatar
s_nakamoto committed
4449
4450
            if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
                addr.nTime = nNow - 5 * 24 * 60 * 60;
s_nakamoto's avatar
s_nakamoto committed
4451
            pfrom->AddAddressKnown(addr);
4452
            bool fReachable = IsReachable(addr);
s_nakamoto's avatar
s_nakamoto committed
4453
            if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
s_nakamoto's avatar
s_nakamoto committed
4454
4455
4456
            {
                // Relay to a limited number of other nodes
                {
4457
                    LOCK(cs_vNodes);
4458
4459
                    // 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
4460
4461
                    static uint256 hashSalt;
                    if (hashSalt == 0)
4462
                        hashSalt = GetRandHash();
4463
                    uint64_t hashAddr = addr.GetHash();
Pieter Wuille's avatar
Pieter Wuille committed
4464
                    uint256 hashRand = hashSalt ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60));
4465
                    hashRand = Hash(BEGIN(hashRand), END(hashRand));
s_nakamoto's avatar
s_nakamoto committed
4466
                    multimap<uint256, CNode*> mapMix;
4467
                    BOOST_FOREACH(CNode* pnode, vNodes)
4468
                    {
4469
                        if (pnode->nVersion < CADDR_TIME_VERSION)
s_nakamoto's avatar
s_nakamoto committed
4470
                            continue;
4471
4472
4473
4474
4475
4476
                        unsigned int nPointer;
                        memcpy(&nPointer, &pnode, sizeof(nPointer));
                        uint256 hashKey = hashRand ^ nPointer;
                        hashKey = Hash(BEGIN(hashKey), END(hashKey));
                        mapMix.insert(make_pair(hashKey, pnode));
                    }
4477
                    int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s)
s_nakamoto's avatar
s_nakamoto committed
4478
4479
4480
4481
                    for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
                        ((*mi).second)->PushAddress(addr);
                }
            }
4482
4483
4484
            // Do not store addresses outside our network
            if (fReachable)
                vAddrOk.push_back(addr);
s_nakamoto's avatar
s_nakamoto committed
4485
        }
4486
        addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60);
s_nakamoto's avatar
s_nakamoto committed
4487
4488
        if (vAddr.size() < 1000)
            pfrom->fGetAddr = false;
4489
4490
        if (pfrom->fOneShot)
            pfrom->fDisconnect = true;
s_nakamoto's avatar
s_nakamoto committed
4491
4492
4493
4494
4495
4496
4497
    }


    else if (strCommand == "inv")
    {
        vector<CInv> vInv;
        vRecv >> vInv;
4498
        if (vInv.size() > MAX_INV_SZ)
4499
        {
Pieter Wuille's avatar
Pieter Wuille committed
4500
            Misbehaving(pfrom->GetId(), 20);
4501
            return error("message inv size() = %u", vInv.size());
4502
        }
s_nakamoto's avatar
s_nakamoto committed
4503

4504
4505
        LOCK(cs_main);

Pieter Wuille's avatar
Pieter Wuille committed
4506
4507
        std::vector<CInv> vToFetch;

4508
        for (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
s_nakamoto's avatar
s_nakamoto committed
4509
        {
4510
4511
            const CInv &inv = vInv[nInv];

Gavin Andresen's avatar
Gavin Andresen committed
4512
            boost::this_thread::interruption_point();
s_nakamoto's avatar
s_nakamoto committed
4513
4514
            pfrom->AddInventoryKnown(inv);

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

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

4521

Pieter Wuille's avatar
Pieter Wuille committed
4522
            if (inv.type == MSG_BLOCK) {
Pieter Wuille's avatar
Pieter Wuille committed
4523
                UpdateBlockAvailability(pfrom->GetId(), inv.hash);
Pieter Wuille's avatar
Pieter Wuille committed
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
                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);
4534
4535
4536
                    CNodeState *nodestate = State(pfrom->GetId());
                    if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - Params().TargetSpacing() * 20 &&
                        nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
Pieter Wuille's avatar
Pieter Wuille committed
4537
4538
4539
4540
4541
                        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);
                    }
4542
                    LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->nHeight, inv.hash.ToString(), pfrom->id);
4543
                }
4544
            }
s_nakamoto's avatar
s_nakamoto committed
4545
4546

            // Track requests for our stuff
4547
            g_signals.Inventory(inv.hash);
4548
4549
4550
4551
4552

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

        if (!vToFetch.empty())
            pfrom->PushMessage("getdata", vToFetch);
s_nakamoto's avatar
s_nakamoto committed
4557
4558
4559
4560
4561
4562
4563
    }


    else if (strCommand == "getdata")
    {
        vector<CInv> vInv;
        vRecv >> vInv;
4564
        if (vInv.size() > MAX_INV_SZ)
4565
        {
Pieter Wuille's avatar
Pieter Wuille committed
4566
            Misbehaving(pfrom->GetId(), 20);
4567
            return error("message getdata size() = %u", vInv.size());
4568
        }
s_nakamoto's avatar
s_nakamoto committed
4569

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

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

4576
4577
        pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end());
        ProcessGetData(pfrom);
s_nakamoto's avatar
s_nakamoto committed
4578
4579
4580
4581
4582
4583
4584
4585
4586
    }


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

4587
4588
        LOCK(cs_main);

4589
        // Find the last block the caller has in the main chain
jtimon's avatar
jtimon committed
4590
        CBlockIndex* pindex = FindForkInGlobalIndex(chainActive, locator);
s_nakamoto's avatar
s_nakamoto committed
4591
4592
4593

        // Send the rest of the chain
        if (pindex)
4594
            pindex = chainActive.Next(pindex);
4595
        int nLimit = 500;
4596
        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);
4597
        for (; pindex; pindex = chainActive.Next(pindex))
s_nakamoto's avatar
s_nakamoto committed
4598
4599
4600
        {
            if (pindex->GetBlockHash() == hashStop)
            {
4601
                LogPrint("net", "  getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
s_nakamoto's avatar
s_nakamoto committed
4602
4603
4604
                break;
            }
            pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
4605
            if (--nLimit <= 0)
s_nakamoto's avatar
s_nakamoto committed
4606
4607
4608
            {
                // When this block is requested, we'll send an inv that'll make them
                // getblocks the next batch of inventory.
4609
                LogPrint("net", "  getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
s_nakamoto's avatar
s_nakamoto committed
4610
4611
4612
4613
4614
4615
4616
                pfrom->hashContinue = pindex->GetBlockHash();
                break;
            }
        }
    }


4617
4618
4619
4620
4621
4622
    else if (strCommand == "getheaders")
    {
        CBlockLocator locator;
        uint256 hashStop;
        vRecv >> locator >> hashStop;

4623
4624
        LOCK(cs_main);

4625
4626
4627
        if (IsInitialBlockDownload())
            return true;

4628
4629
4630
4631
        CBlockIndex* pindex = NULL;
        if (locator.IsNull())
        {
            // If locator is null, return the hashStop block
4632
            BlockMap::iterator mi = mapBlockIndex.find(hashStop);
4633
4634
4635
4636
4637
4638
4639
            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
4640
            pindex = FindForkInGlobalIndex(chainActive, locator);
4641
            if (pindex)
4642
                pindex = chainActive.Next(pindex);
4643
4644
        }

4645
        // we must use CBlocks, as CBlockHeaders won't include the 0x00 nTx count at the end
4646
        vector<CBlock> vHeaders;
Pieter Wuille's avatar
Pieter Wuille committed
4647
        int nLimit = MAX_HEADERS_RESULTS;
4648
        LogPrint("net", "getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString(), pfrom->id);
4649
        for (; pindex; pindex = chainActive.Next(pindex))
4650
4651
4652
4653
4654
4655
4656
4657
4658
        {
            vHeaders.push_back(pindex->GetBlockHeader());
            if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
                break;
        }
        pfrom->PushMessage("headers", vHeaders);
    }


4659
    else if (strCommand == "tx"|| strCommand == "dstx")
s_nakamoto's avatar
s_nakamoto committed
4660
4661
    {
        vector<uint256> vWorkQueue;
4662
        vector<uint256> vEraseQueue;
s_nakamoto's avatar
s_nakamoto committed
4663
        CTransaction tx;
4664
4665

        //masternode signed transaction
UdjinM6's avatar
UdjinM6 committed
4666
        bool ignoreFees = false;
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
        CTxIn vin;
        vector<unsigned char> vchSig;
        int64_t sigTime;

        if(strCommand == "tx") {
            vRecv >> tx;
        } else if (strCommand == "dstx") {
            //these allow masternodes to publish a limited amount of free transactions
            vRecv >> tx >> vin >> vchSig >> sigTime;

infernoman's avatar
infernoman committed
4677
            CThrone* pmn = mnodeman.Find(vin);
UdjinM6's avatar
UdjinM6 committed
4678
            if(pmn != NULL)
4679
            {
UdjinM6's avatar
UdjinM6 committed
4680
                if(!pmn->allowFreeTx){
4681
                    //multiple peers can send us a valid masternode transaction
infernoman's avatar
infernoman committed
4682
                    if(fDebug) LogPrintf("dstx: Throne sending too many transactions %s\n", tx.GetHash().ToString());
4683
4684
                    return true;
                }
4685

4686
                std::string strMessage = tx.GetHash().ToString() + boost::lexical_cast<std::string>(sigTime);
4687

4688
                std::string errorMessage = "";
UdjinM6's avatar
UdjinM6 committed
4689
                if(!darkSendSigner.VerifyMessage(pmn->pubkey2, vchSig, strMessage, errorMessage)){
4690
                    LogPrintf("dstx: Got bad masternode address signature %s \n", vin.ToString());
4691
4692
4693
                    //pfrom->Misbehaving(20);
                    return false;
                }
4694

infernoman's avatar
infernoman committed
4695
                LogPrintf("dstx: Got Throne transaction %s\n", tx.GetHash().ToString());
4696

UdjinM6's avatar
UdjinM6 committed
4697
                ignoreFees = true;
UdjinM6's avatar
UdjinM6 committed
4698
                pmn->allowFreeTx = false;
4699

4700
4701
4702
4703
4704
4705
                if(!mapDarksendBroadcastTxes.count(tx.GetHash())){
                    CDarksendBroadcastTx dstx;
                    dstx.tx = tx;
                    dstx.vin = vin;
                    dstx.vchSig = vchSig;
                    dstx.sigTime = sigTime;
4706

4707
                    mapDarksendBroadcastTxes.insert(make_pair(tx.GetHash(), dstx));
4708
4709
4710
                }
            }
        }
s_nakamoto's avatar
s_nakamoto committed
4711
4712
4713
4714

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

4715
4716
        LOCK(cs_main);

s_nakamoto's avatar
s_nakamoto committed
4717
        bool fMissingInputs = false;
Pieter Wuille's avatar
Pieter Wuille committed
4718
        CValidationState state;
4719
4720
4721

        mapAlreadyAskedFor.erase(inv);

UdjinM6's avatar
UdjinM6 committed
4722
        if (AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs, false, ignoreFees))
s_nakamoto's avatar
s_nakamoto committed
4723
        {
4724
            mempool.check(pcoinsTip);
4725
            RelayTransaction(tx);
s_nakamoto's avatar
s_nakamoto committed
4726
4727
            vWorkQueue.push_back(inv.hash);

4728
4729
            LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s : accepted %s (poolsz %u)\n",
                pfrom->id, pfrom->cleanSubVer,
4730
                tx.GetHash().ToString(),
4731
4732
                mempool.mapTx.size());

s_nakamoto's avatar
s_nakamoto committed
4733
            // Recursively process any orphan transactions that depended on this one
4734
            set<NodeId> setMisbehaving;
4735
            for (unsigned int i = 0; i < vWorkQueue.size(); i++)
s_nakamoto's avatar
s_nakamoto committed
4736
            {
4737
4738
4739
4740
4741
                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
4742
4743
                     ++mi)
                {
4744
                    const uint256& orphanHash = *mi;
4745
4746
                    const CTransaction& orphanTx = mapOrphanTransactions[orphanHash].tx;
                    NodeId fromPeer = mapOrphanTransactions[orphanHash].fromPeer;
4747
                    bool fMissingInputs2 = false;
4748
4749
4750
                    // 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)
4751
                    CValidationState stateDummy;
s_nakamoto's avatar
s_nakamoto committed
4752

4753
4754
4755

                    if (setMisbehaving.count(fromPeer))
                        continue;
4756
                    if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2))
s_nakamoto's avatar
s_nakamoto committed
4757
                    {
4758
                        LogPrint("mempool", "   accepted orphan tx %s\n", orphanHash.ToString());
4759
                        RelayTransaction(orphanTx);
4760
                        vWorkQueue.push_back(orphanHash);
4761
                        vEraseQueue.push_back(orphanHash);
4762
4763
4764
                    }
                    else if (!fMissingInputs2)
                    {
4765
4766
4767
4768
4769
4770
4771
4772
                        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());
                        }
4773
4774
                        // Has inputs but not accepted to mempool
                        // Probably non-standard or insufficient fee/priority
4775
                        LogPrint("mempool", "   removed orphan tx %s\n", orphanHash.ToString());
4776
                        vEraseQueue.push_back(orphanHash);
s_nakamoto's avatar
s_nakamoto committed
4777
                    }
4778
                    mempool.check(pcoinsTip);
s_nakamoto's avatar
s_nakamoto committed
4779
4780
4781
                }
            }

4782
            BOOST_FOREACH(uint256 hash, vEraseQueue)
s_nakamoto's avatar
s_nakamoto committed
4783
4784
4785
4786
                EraseOrphanTx(hash);
        }
        else if (fMissingInputs)
        {
4787
            AddOrphanTx(tx, pfrom->GetId());
4788
4789

            // DoS prevention: do not allow mapOrphanTransactions to grow unbounded
4790
4791
            unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
            unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
4792
            if (nEvicted > 0)
4793
                LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted);
Pieter Wuille's avatar
Pieter Wuille committed
4794
4795
4796
4797
        } 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).
4798

Pieter Wuille's avatar
Pieter Wuille committed
4799
            RelayTransaction(tx);
s_nakamoto's avatar
s_nakamoto committed
4800
        }
4801
4802
4803

        if(strCommand == "dstx"){
            CInv inv(MSG_DSTX, tx.GetHash());
UdjinM6's avatar
UdjinM6 committed
4804
            RelayInv(inv);
4805
4806
        }

4807
        int nDoS = 0;
4808
        if (state.IsInvalid(nDoS))
Philip Kaufmann's avatar
Philip Kaufmann committed
4809
        {
4810
4811
            LogPrint("mempool", "%s from peer=%d %s was not accepted into the memory pool: %s\n", tx.GetHash().ToString(),
                pfrom->id, pfrom->cleanSubVer,
4812
                state.GetRejectReason());
Gavin Andresen's avatar
Gavin Andresen committed
4813
            pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
4814
                               state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
4815
            if (nDoS > 0)
Pieter Wuille's avatar
Pieter Wuille committed
4816
                Misbehaving(pfrom->GetId(), nDoS);
Gavin Andresen's avatar
Gavin Andresen committed
4817
        }
s_nakamoto's avatar
s_nakamoto committed
4818
4819
4820
    }


Pieter Wuille's avatar
Pieter Wuille committed
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
    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);
4856
4857
                    std::string strError = "invalid header received " + header.GetHash().ToString();
                    return error(strError.c_str());
Pieter Wuille's avatar
Pieter Wuille committed
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
                }
            }
        }

        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.
4869
            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
4870
4871
            pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256(0));
        }
4872
4873

        CheckBlockIndex();
Pieter Wuille's avatar
Pieter Wuille committed
4874
4875
    }

4876
    else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing
s_nakamoto's avatar
s_nakamoto committed
4877
    {
4878
4879
        CBlock block;
        vRecv >> block;
s_nakamoto's avatar
s_nakamoto committed
4880

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

Pieter Wuille's avatar
Pieter Wuille committed
4884
        pfrom->AddInventoryKnown(inv);
4885

Pieter Wuille's avatar
Pieter Wuille committed
4886
        CValidationState state;
4887
        ProcessNewBlock(state, pfrom, &block);
4888
4889
4890
        int nDoS;
        if (state.IsInvalid(nDoS)) {
            pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
4891
                               state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
4892
            if (nDoS > 0) {
UdjinM6's avatar
UdjinM6 committed
4893
4894
                TRY_LOCK(cs_main, lockMain);
                if(lockMain) Misbehaving(pfrom->GetId(), nDoS);
4895
4896
4897
            }
        }

s_nakamoto's avatar
s_nakamoto committed
4898
4899
4900
    }


4901
4902
    // This asymmetric behavior for inbound and outbound connections was introduced
    // to prevent a fingerprinting attack: an attacker can send specific fake addresses
4903
4904
    // to users' AddrMan and later request them by sending getaddr messages.
    // Making users (which are behind NAT and can only make outgoing connections) ignore
4905
4906
    // getaddr message mitigates the attack.
    else if ((strCommand == "getaddr") && (pfrom->fInbound))
s_nakamoto's avatar
s_nakamoto committed
4907
4908
    {
        pfrom->vAddrToSend.clear();
4909
4910
4911
        vector<CAddress> vAddr = addrman.GetAddr();
        BOOST_FOREACH(const CAddress &addr, vAddr)
            pfrom->PushAddress(addr);
s_nakamoto's avatar
s_nakamoto committed
4912
4913
4914
    }


4915
4916
    else if (strCommand == "mempool")
    {
4917
        LOCK2(cs_main, pfrom->cs_filter);
4918

4919
4920
4921
        std::vector<uint256> vtxid;
        mempool.queryHashes(vtxid);
        vector<CInv> vInv;
Matt Corallo's avatar
Matt Corallo committed
4922
4923
        BOOST_FOREACH(uint256& hash, vtxid) {
            CInv inv(MSG_TX, hash);
4924
4925
4926
            CTransaction tx;
            bool fInMemPool = mempool.lookup(hash, tx);
            if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
4927
            if ((pfrom->pfilter && pfrom->pfilter->IsRelevantAndUpdate(tx)) ||
Matt Corallo's avatar
Matt Corallo committed
4928
4929
               (!pfrom->pfilter))
                vInv.push_back(inv);
4930
4931
4932
4933
            if (vInv.size() == MAX_INV_SZ) {
                pfrom->PushMessage("inv", vInv);
                vInv.clear();
            }
4934
4935
4936
4937
4938
4939
        }
        if (vInv.size() > 0)
            pfrom->PushMessage("inv", vInv);
    }


s_nakamoto's avatar
s_nakamoto committed
4940
4941
    else if (strCommand == "ping")
    {
Jeff Garzik's avatar
Jeff Garzik committed
4942
4943
        if (pfrom->nVersion > BIP0031_VERSION)
        {
4944
            uint64_t nonce = 0;
Jeff Garzik's avatar
Jeff Garzik committed
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
            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
4959
4960
4961
    }


Josh Lehan's avatar
Josh Lehan committed
4962
4963
    else if (strCommand == "pong")
    {
4964
        int64_t pingUsecEnd = nTimeReceived;
4965
        uint64_t nonce = 0;
Josh Lehan's avatar
Josh Lehan committed
4966
4967
4968
        size_t nAvail = vRecv.in_avail();
        bool bPingFinished = false;
        std::string sProblem;
4969

Josh Lehan's avatar
Josh Lehan committed
4970
4971
        if (nAvail >= sizeof(nonce)) {
            vRecv >> nonce;
4972

Josh Lehan's avatar
Josh Lehan committed
4973
4974
4975
4976
4977
            // 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;
4978
                    int64_t pingUsecTime = pingUsecEnd - pfrom->nPingUsecStart;
Josh Lehan's avatar
Josh Lehan committed
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
                    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";
        }
5003

Josh Lehan's avatar
Josh Lehan committed
5004
        if (!(sProblem.empty())) {
5005
5006
            LogPrint("net", "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n",
                pfrom->id,
5007
5008
                pfrom->cleanSubVer,
                sProblem,
5009
5010
5011
                pfrom->nPingNonceSent,
                nonce,
                nAvail);
Josh Lehan's avatar
Josh Lehan committed
5012
5013
5014
5015
5016
        }
        if (bPingFinished) {
            pfrom->nPingNonceSent = 0;
        }
    }
5017
5018


5019
    else if (fAlerts && strCommand == "alert")
s_nakamoto's avatar
s_nakamoto committed
5020
5021
5022
5023
    {
        CAlert alert;
        vRecv >> alert;

Gavin Andresen's avatar
Gavin Andresen committed
5024
5025
        uint256 alertHash = alert.GetHash();
        if (pfrom->setKnown.count(alertHash) == 0)
s_nakamoto's avatar
s_nakamoto committed
5026
        {
Gavin Andresen's avatar
Gavin Andresen committed
5027
            if (alert.ProcessAlert())
5028
            {
Gavin Andresen's avatar
Gavin Andresen committed
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
                // 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
5044
                Misbehaving(pfrom->GetId(), 10);
5045
            }
s_nakamoto's avatar
s_nakamoto committed
5046
5047
5048
5049
        }
    }


5050
5051
5052
5053
5054
5055
5056
    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
5057
            Misbehaving(pfrom->GetId(), 100);
5058
5059
5060
5061
5062
        else
        {
            LOCK(pfrom->cs_filter);
            delete pfrom->pfilter;
            pfrom->pfilter = new CBloomFilter(filter);
5063
            pfrom->pfilter->UpdateEmptyFull();
5064
        }
5065
        pfrom->fRelayTxes = true;
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
    }


    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
5076
        if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE)
5077
        {
Pieter Wuille's avatar
Pieter Wuille committed
5078
            Misbehaving(pfrom->GetId(), 100);
5079
5080
5081
5082
5083
        } else {
            LOCK(pfrom->cs_filter);
            if (pfrom->pfilter)
                pfrom->pfilter->insert(vData);
            else
Pieter Wuille's avatar
Pieter Wuille committed
5084
                Misbehaving(pfrom->GetId(), 100);
5085
5086
5087
5088
5089
5090
5091
5092
        }
    }


    else if (strCommand == "filterclear")
    {
        LOCK(pfrom->cs_filter);
        delete pfrom->pfilter;
5093
        pfrom->pfilter = new CBloomFilter();
5094
        pfrom->fRelayTxes = true;
5095
5096
5097
    }


Gavin Andresen's avatar
Gavin Andresen committed
5098
5099
    else if (strCommand == "reject")
    {
5100
5101
5102
        if (fDebug) {
            try {
                string strMsg; unsigned char ccode; string strReason;
5103
                vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, MAX_REJECT_MESSAGE_LENGTH);
Gavin Andresen's avatar
Gavin Andresen committed
5104

5105
5106
                ostringstream ss;
                ss << strMsg << " code " << itostr(ccode) << ": " << strReason;
Gavin Andresen's avatar
Gavin Andresen committed
5107

5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
                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
5118
5119
5120
            }
        }
    }
s_nakamoto's avatar
s_nakamoto committed
5121
5122
    else
    {
5123
        //probably one the extensions
Evan Duffield's avatar
Evan Duffield committed
5124
        darkSendPool.ProcessMessageDarksend(pfrom, strCommand, vRecv);
5125
        mnodeman.ProcessMessage(pfrom, strCommand, vRecv);
5126
        budget.ProcessMessage(pfrom, strCommand, vRecv);
infernoman's avatar
infernoman committed
5127
        masternodePayments.ProcessMessageThronePayments(pfrom, strCommand, vRecv);
5128
        ProcessMessageInstantX(pfrom, strCommand, vRecv);
Evan Duffield's avatar
Evan Duffield committed
5129
        ProcessSpork(pfrom, strCommand, vRecv);
Evan Duffield's avatar
Evan Duffield committed
5130
        masternodeSync.ProcessMessage(pfrom, strCommand, vRecv);
s_nakamoto's avatar
s_nakamoto committed
5131
5132
5133
5134
5135
5136
5137
    }



    return true;
}

5138
// requires LOCK(cs_vRecvMsg)
5139
5140
5141
bool ProcessMessages(CNode* pfrom)
{
    //if (fDebug)
5142
    //    LogPrintf("ProcessMessages(%u messages)\n", pfrom->vRecvMsg.size());
s_nakamoto's avatar
s_nakamoto committed
5143

5144
5145
5146
5147
5148
5149
5150
5151
    //
    // Message format
    //  (4) message start
    //  (12) command
    //  (4) size
    //  (4) checksum
    //  (x) data
    //
5152
    bool fOk = true;
s_nakamoto's avatar
s_nakamoto committed
5153

5154
5155
    if (!pfrom->vRecvGetData.empty())
        ProcessGetData(pfrom);
5156

5157
5158
    // this maintains the order of responses
    if (!pfrom->vRecvGetData.empty()) return fOk;
5159

5160
    std::deque<CNetMessage>::iterator it = pfrom->vRecvMsg.begin();
5161
    while (!pfrom->fDisconnect && it != pfrom->vRecvMsg.end()) {
5162
        // Don't bother if send buffer is too full to respond anyway
5163
        if (pfrom->nSendSize >= SendBufferSize())
5164
5165
            break;

5166
5167
        // get next message
        CNetMessage& msg = *it;
5168
5169

        //if (fDebug)
5170
        //    LogPrintf("ProcessMessages(message %u msgsz, %u bytes, complete:%s)\n",
5171
5172
5173
        //            msg.hdr.nMessageSize, msg.vRecv.size(),
        //            msg.complete() ? "Y" : "N");

5174
        // end, if an incomplete message is found
5175
        if (!msg.complete())
5176
            break;
5177

5178
5179
5180
        // at this point, any failure means we can delete the current message
        it++;

5181
        // Scan for message start
5182
        if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
5183
            LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id);
5184
5185
            fOk = false;
            break;
5186
        }
s_nakamoto's avatar
s_nakamoto committed
5187

5188
        // Read header
5189
        CMessageHeader& hdr = msg.hdr;
5190
5191
        if (!hdr.IsValid())
        {
5192
            LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id);
5193
5194
5195
5196
5197
5198
5199
5200
            continue;
        }
        string strCommand = hdr.GetCommand();

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

        // Checksum
5201
        CDataStream& vRecv = msg.vRecv;
Pieter Wuille's avatar
Pieter Wuille committed
5202
5203
5204
5205
        uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
        unsigned int nChecksum = 0;
        memcpy(&nChecksum, &hash, sizeof(nChecksum));
        if (nChecksum != hdr.nChecksum)
5206
        {
5207
5208
            LogPrintf("ProcessMessages(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
               SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum);
Pieter Wuille's avatar
Pieter Wuille committed
5209
            continue;
5210
5211
5212
5213
5214
5215
        }

        // Process message
        bool fRet = false;
        try
        {
5216
            fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime);
Gavin Andresen's avatar
Gavin Andresen committed
5217
            boost::this_thread::interruption_point();
5218
5219
5220
        }
        catch (std::ios_base::failure& e)
        {
Gavin Andresen's avatar
Gavin Andresen committed
5221
            pfrom->PushMessage("reject", strCommand, REJECT_MALFORMED, string("error parsing message"));
5222
5223
            if (strstr(e.what(), "end of data"))
            {
5224
                // Allow exceptions from under-length message on vRecv
5225
                LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", SanitizeString(strCommand), nMessageSize, e.what());
5226
5227
5228
            }
            else if (strstr(e.what(), "size too large"))
            {
5229
                // Allow exceptions from over-long size
5230
                LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught\n", SanitizeString(strCommand), nMessageSize, e.what());
5231
5232
5233
            }
            else
            {
5234
                PrintExceptionContinue(&e, "ProcessMessages()");
5235
5236
            }
        }
Gavin Andresen's avatar
Gavin Andresen committed
5237
5238
5239
        catch (boost::thread_interrupted) {
            throw;
        }
5240
        catch (std::exception& e) {
5241
            PrintExceptionContinue(&e, "ProcessMessages()");
5242
        } catch (...) {
5243
            PrintExceptionContinue(NULL, "ProcessMessages()");
5244
5245
5246
        }

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

5249
        break;
5250
5251
    }

5252
5253
5254
5255
    // In case the connection got shut down, its receive buffer was wiped
    if (!pfrom->fDisconnect)
        pfrom->vRecvMsg.erase(pfrom->vRecvMsg.begin(), it);

5256
    return fOk;
5257
}
s_nakamoto's avatar
s_nakamoto committed
5258
5259
5260
5261


bool SendMessages(CNode* pto, bool fSendTrickle)
{
5262
    {
s_nakamoto's avatar
s_nakamoto committed
5263
5264
5265
5266
        // Don't send anything until we get their version message
        if (pto->nVersion == 0)
            return true;

Josh Lehan's avatar
Josh Lehan committed
5267
5268
5269
5270
5271
5272
5273
5274
        //
        // Message: ping
        //
        bool pingSend = false;
        if (pto->fPingQueued) {
            // RPC ping request by user
            pingSend = true;
        }
5275
5276
        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
5277
5278
5279
            pingSend = true;
        }
        if (pingSend) {
5280
            uint64_t nonce = 0;
Josh Lehan's avatar
Josh Lehan committed
5281
            while (nonce == 0) {
5282
                GetRandBytes((unsigned char*)&nonce, sizeof(nonce));
Josh Lehan's avatar
Josh Lehan committed
5283
5284
            }
            pto->fPingQueued = false;
5285
            pto->nPingUsecStart = GetTimeMicros();
Josh Lehan's avatar
Josh Lehan committed
5286
            if (pto->nVersion > BIP0031_VERSION) {
5287
                pto->nPingNonceSent = nonce;
Pieter Wuille's avatar
Pieter Wuille committed
5288
                pto->PushMessage("ping", nonce);
Josh Lehan's avatar
Josh Lehan committed
5289
            } else {
5290
5291
                // Peer is too old to support ping command with nonce, pong will never arrive.
                pto->nPingNonceSent = 0;
Jeff Garzik's avatar
Jeff Garzik committed
5292
                pto->PushMessage("ping");
Josh Lehan's avatar
Josh Lehan committed
5293
            }
Jeff Garzik's avatar
Jeff Garzik committed
5294
        }
s_nakamoto's avatar
s_nakamoto committed
5295

5296
5297
5298
5299
        TRY_LOCK(cs_main, lockMain); // Acquire cs_main for IsInitialBlockDownload() and CNodeState()
        if (!lockMain)
            return true;

s_nakamoto's avatar
s_nakamoto committed
5300
        // Address refresh broadcast
5301
        static int64_t nLastRebroadcast;
5302
        if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
s_nakamoto's avatar
s_nakamoto committed
5303
        {
5304
5305
            LOCK(cs_vNodes);
            BOOST_FOREACH(CNode* pnode, vNodes)
s_nakamoto's avatar
s_nakamoto committed
5306
            {
5307
5308
5309
                // Periodically clear setAddrKnown to allow refresh broadcasts
                if (nLastRebroadcast)
                    pnode->setAddrKnown.clear();
s_nakamoto's avatar
s_nakamoto committed
5310

5311
5312
                // Rebroadcast our address
                AdvertizeLocal(pnode);
s_nakamoto's avatar
s_nakamoto committed
5313
            }
5314
5315
            if (!vNodes.empty())
                nLastRebroadcast = GetTime();
s_nakamoto's avatar
s_nakamoto committed
5316
5317
5318
5319
5320
5321
5322
5323
5324
        }

        //
        // Message: addr
        //
        if (fSendTrickle)
        {
            vector<CAddress> vAddr;
            vAddr.reserve(pto->vAddrToSend.size());
5325
            BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend)
s_nakamoto's avatar
s_nakamoto committed
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
            {
                // 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);
        }

5344
5345
        CNodeState &state = *State(pto->GetId());
        if (state.fShouldBan) {
Pieter Wuille's avatar
Pieter Wuille committed
5346
5347
            if (pto->fWhitelisted)
                LogPrintf("Warning: not punishing whitelisted peer %s!\n", pto->addr.ToString());
Pieter Wuille's avatar
Pieter Wuille committed
5348
5349
            else {
                pto->fDisconnect = true;
Pieter Wuille's avatar
Pieter Wuille committed
5350
5351
5352
                if (pto->addr.IsLocal())
                    LogPrintf("Warning: not banning local peer %s!\n", pto->addr.ToString());
                else
5353
                {
Pieter Wuille's avatar
Pieter Wuille committed
5354
                    CNode::Ban(pto->addr);
5355
                }
Pieter Wuille's avatar
Pieter Wuille committed
5356
            }
5357
            state.fShouldBan = false;
Pieter Wuille's avatar
Pieter Wuille committed
5358
5359
        }

5360
5361
5362
5363
        BOOST_FOREACH(const CBlockReject& reject, state.rejects)
            pto->PushMessage("reject", (string)"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock);
        state.rejects.clear();

5364
        // Start block sync
Pieter Wuille's avatar
Pieter Wuille committed
5365
5366
        if (pindexBestHeader == NULL)
            pindexBestHeader = chainActive.Tip();
5367
        bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->fOneShot); // Download if this is a nice peer, or we have no nice peers and this one might do.
Pieter Wuille's avatar
Pieter Wuille committed
5368
        if (!state.fSyncStarted && !pto->fClient && fFetch && !fImporting && !fReindex) {
5369
5370
            // Only actively request headers from a single peer, unless we're close to end of initial download.
            if (nSyncStarted == 0 || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 6 * 60 * 60) { // NOTE: was "close to today" and 24h in Bitcoin
Pieter Wuille's avatar
Pieter Wuille committed
5371
5372
5373
                state.fSyncStarted = true;
                nSyncStarted++;
                CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader;
5374
                LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight);
Pieter Wuille's avatar
Pieter Wuille committed
5375
5376
                pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256(0));
            }
5377
5378
5379
5380
5381
5382
5383
        }

        // 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())
        {
5384
            g_signals.Broadcast();
5385
        }
s_nakamoto's avatar
s_nakamoto committed
5386
5387
5388
5389
5390
5391
5392

        //
        // Message: inventory
        //
        vector<CInv> vInv;
        vector<CInv> vInvWait;
        {
5393
            LOCK(pto->cs_inventory);
s_nakamoto's avatar
s_nakamoto committed
5394
5395
            vInv.reserve(pto->vInventoryToSend.size());
            vInvWait.reserve(pto->vInventoryToSend.size());
5396
            BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
s_nakamoto's avatar
s_nakamoto committed
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
            {
                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)
5407
                        hashSalt = GetRandHash();
s_nakamoto's avatar
s_nakamoto committed
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
                    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
5435
        // Detect whether we're stalling
5436
        int64_t nNow = GetTimeMicros();
Pieter Wuille's avatar
Pieter Wuille committed
5437
5438
5439
5440
5441
        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);
5442
5443
            pto->fDisconnect = true;
        }
5444
        // In case there is a block that has been in flight from this peer for (2 + 0.5 * N) times the block interval
5445
5446
5447
5448
        // (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to
        // timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link
        // being saturated. We only count validated in-flight blocks so peers can't advertize nonexisting block hashes
        // to unreasonably increase our timeout.
5449
        if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0 && state.vBlocksInFlight.front().nTime < nNow - 500000 * Params().TargetSpacing() * (4 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) {
5450
            LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", state.vBlocksInFlight.front().hash.ToString(), pto->id);
5451
5452
5453
            pto->fDisconnect = true;
        }

s_nakamoto's avatar
s_nakamoto committed
5454
        //
5455
        // Message: getdata (blocks)
s_nakamoto's avatar
s_nakamoto committed
5456
5457
        //
        vector<CInv> vGetData;
Pieter Wuille's avatar
Pieter Wuille committed
5458
5459
5460
5461
5462
5463
5464
        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);
5465
5466
                LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(),
                    pindex->nHeight, pto->id);
Pieter Wuille's avatar
Pieter Wuille committed
5467
5468
            }
            if (state.nBlocksInFlight == 0 && staller != -1) {
R E Broadley's avatar
R E Broadley committed
5469
                if (State(staller)->nStallingSince == 0) {
Pieter Wuille's avatar
Pieter Wuille committed
5470
                    State(staller)->nStallingSince = nNow;
R E Broadley's avatar
R E Broadley committed
5471
5472
                    LogPrint("net", "Stall started peer=%d\n", staller);
                }
5473
5474
5475
5476
5477
5478
5479
            }
        }

        //
        // Message: getdata (non-blocks)
        //
        while (!pto->fDisconnect && !pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
s_nakamoto's avatar
s_nakamoto committed
5480
5481
        {
            const CInv& inv = (*pto->mapAskFor.begin()).second;
5482
            if (!AlreadyHave(inv))
s_nakamoto's avatar
s_nakamoto committed
5483
            {
5484
                if (fDebug)
5485
                    LogPrint("net", "Requesting %s peer=%d\n", inv.ToString(), pto->id);
s_nakamoto's avatar
s_nakamoto committed
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
                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;
}


5503
5504
5505
bool CBlockUndo::WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock)
{
    // Open history file to append
5506
    CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
5507
    if (fileout.IsNull())
5508
5509
5510
5511
5512
5513
5514
        return error("CBlockUndo::WriteToDisk : OpenUndoFile failed");

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

    // Write undo data
5515
    long fileOutPos = ftell(fileout.Get());
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
    if (fileOutPos < 0)
        return error("CBlockUndo::WriteToDisk : ftell failed");
    pos.nPos = (unsigned int)fileOutPos;
    fileout << *this;

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

    return true;
}

bool CBlockUndo::ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock)
{
    // Open history file to read
5533
    CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
5534
    if (filein.IsNull())
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
        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
5556

5557
 std::string CBlockFileInfo::ToString() const {
5558
     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));
5559
 }
s_nakamoto's avatar
s_nakamoto committed
5560
5561
5562



5563
5564
5565
5566
5567
5568
class CMainCleanup
{
public:
    CMainCleanup() {}
    ~CMainCleanup() {
        // block headers
5569
        BlockMap::iterator it1 = mapBlockIndex.begin();
5570
5571
5572
5573
5574
5575
        for (; it1 != mapBlockIndex.end(); it1++)
            delete (*it1).second;
        mapBlockIndex.clear();

        // orphan transactions
        mapOrphanTransactions.clear();
5576
        mapOrphanTransactionsByPrev.clear();
5577
5578
    }
} instance_of_cmaincleanup;