main.cpp 194 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
vertoe's avatar
vertoe committed
3
// Copyright (c) 2014-2015 The Darkcoin developers
s_nakamoto's avatar
s_nakamoto committed
4
// Distributed under the MIT/X11 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 "chainparams.h"
12
#include "checkpoints.h"
13
#include "checkqueue.h"
14
#include "init.h"
15
16
17
#include "instantx.h"
#include "darksend.h"
#include "masternode.h"
18
19
20
#include "net.h"
#include "txdb.h"
#include "txmempool.h"
Pieter Wuille's avatar
Pieter Wuille committed
21
#include "ui_interface.h"
22
23
#include "util.h"

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

#include <boost/algorithm/string/replace.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
29
#include <boost/lexical_cast.hpp>
s_nakamoto's avatar
s_nakamoto committed
30

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

34
#if defined(NDEBUG)
vertoe's avatar
vertoe committed
35
# error "Darkcoin cannot be compiled without assertions."
36
37
#endif

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

CCriticalSection cs_main;

44
CTxMemPool mempool;
s_nakamoto's avatar
s_nakamoto committed
45
46

map<uint256, CBlockIndex*> mapBlockIndex;
47
CChain chainActive;
48
CChain chainMostWork;
49
int64_t nTimeBestReceived = 0;
50
int nScriptCheckThreads = 0;
51
bool fImporting = false;
52
bool fReindex = false;
53
bool fBenchmark = false;
54
bool fTxIndex = false;
Pieter Wuille's avatar
Pieter Wuille committed
55
unsigned int nCoinCacheSize = 5000;
s_nakamoto's avatar
s_nakamoto committed
56

Gavin Andresen's avatar
Gavin Andresen committed
57
/** Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) */
58
int64_t CTransaction::nMinTxFee = 10000;  // Override with -mintxfee
59
/** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
60
int64_t CTransaction::nMinRelayTxFee = 1000;
Gavin Andresen's avatar
Gavin Andresen committed
61

62
63
64
65
66
67
68
struct COrphanBlock {
    uint256 hashBlock;
    uint256 hashPrev;
    vector<unsigned char> vchBlock;
};
map<uint256, COrphanBlock*> mapOrphanBlocks;
multimap<uint256, COrphanBlock*> mapOrphanBlocksByPrev;
s_nakamoto's avatar
s_nakamoto committed
69

70
71
72
73
74
struct COrphanTx {
    CTransaction tx;
    NodeId fromPeer;
};
map<uint256, COrphanTx> mapOrphanTransactions;
75
map<uint256, set<uint256> > mapOrphanTransactionsByPrev;
76
void EraseOrphansFor(NodeId peer);
s_nakamoto's avatar
s_nakamoto committed
77

78
79
// Constant stuff for coinbase transactions we create:
CScript COINBASE_FLAGS;
s_nakamoto's avatar
s_nakamoto committed
80

81
const string strMessageMagic = "DarkCoin Signed Message:\n";
82

83
84
// Internal stuff
namespace {
R E Broadley's avatar
R E Broadley committed
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
    struct CBlockIndexWorkComparator
    {
        bool operator()(CBlockIndex *pa, CBlockIndex *pb) {
            // First sort by most total work, ...
            if (pa->nChainWork > pb->nChainWork) return false;
            if (pa->nChainWork < pb->nChainWork) return true;

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

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

            // Identical blocks.
            return false;
        }
    };

    CBlockIndex *pindexBestInvalid;
    // may contain all CBlockIndex*'s that have validness >=BLOCK_VALID_TRANSACTIONS, and must contain those who aren't failed
    set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexValid;

    CCriticalSection cs_LastBlockFile;
    CBlockFileInfo infoLastBlockFile;
    int nLastBlockFile = 0;

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

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

    // Blocks that are in flight, and that are in the queue to be downloaded.
    // Protected by cs_main.
    struct QueuedBlock {
        uint256 hash;
        int64_t nTime;  // Time of "getdata" request in microseconds.
        int nQueuedBefore;  // Number of blocks in flight at the time of request.
    };
    map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;
    map<uint256, pair<NodeId, list<uint256>::iterator> > mapBlocksToDownload;
133
}
s_nakamoto's avatar
s_nakamoto committed
134

Pieter Wuille's avatar
Pieter Wuille committed
135
136
137
138
139
//////////////////////////////////////////////////////////////////////////////
//
// dispatching functions
//

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

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

159
160
161
162
163
164
165
void RegisterWallet(CWalletInterface* pwalletIn) {
    g_signals.SyncTransaction.connect(boost::bind(&CWalletInterface::SyncTransaction, pwalletIn, _1, _2, _3));
    g_signals.EraseTransaction.connect(boost::bind(&CWalletInterface::EraseFromWallet, pwalletIn, _1));
    g_signals.UpdatedTransaction.connect(boost::bind(&CWalletInterface::UpdatedTransaction, pwalletIn, _1));
    g_signals.SetBestChain.connect(boost::bind(&CWalletInterface::SetBestChain, pwalletIn, _1));
    g_signals.Inventory.connect(boost::bind(&CWalletInterface::Inventory, pwalletIn, _1));
    g_signals.Broadcast.connect(boost::bind(&CWalletInterface::ResendWalletTransactions, pwalletIn));
Pieter Wuille's avatar
Pieter Wuille committed
166
167
}

168
169
170
171
172
173
174
void UnregisterWallet(CWalletInterface* pwalletIn) {
    g_signals.Broadcast.disconnect(boost::bind(&CWalletInterface::ResendWalletTransactions, pwalletIn));
    g_signals.Inventory.disconnect(boost::bind(&CWalletInterface::Inventory, pwalletIn, _1));
    g_signals.SetBestChain.disconnect(boost::bind(&CWalletInterface::SetBestChain, pwalletIn, _1));
    g_signals.UpdatedTransaction.disconnect(boost::bind(&CWalletInterface::UpdatedTransaction, pwalletIn, _1));
    g_signals.EraseTransaction.disconnect(boost::bind(&CWalletInterface::EraseFromWallet, pwalletIn, _1));
    g_signals.SyncTransaction.disconnect(boost::bind(&CWalletInterface::SyncTransaction, pwalletIn, _1, _2, _3));
Pieter Wuille's avatar
Pieter Wuille committed
175
176
}

177
178
179
180
181
182
183
void UnregisterAllWallets() {
    g_signals.Broadcast.disconnect_all_slots();
    g_signals.Inventory.disconnect_all_slots();
    g_signals.SetBestChain.disconnect_all_slots();
    g_signals.UpdatedTransaction.disconnect_all_slots();
    g_signals.EraseTransaction.disconnect_all_slots();
    g_signals.SyncTransaction.disconnect_all_slots();
Pieter Wuille's avatar
Pieter Wuille committed
184
185
}

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

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

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

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

Pieter Wuille's avatar
Pieter Wuille committed
203
204
205
206
207
// Maintain validation-specific state about nodes, protected by cs_main, instead
// by CNode's own locks. This simplifies asynchronous operation, where
// processing of incoming data is done after the ProcessMessage call returns,
// and we're no longer holding the node's locks.
struct CNodeState {
208
    // Accumulated misbehaviour score for this peer.
Pieter Wuille's avatar
Pieter Wuille committed
209
    int nMisbehavior;
210
    // Whether this peer should be disconnected and banned.
Pieter Wuille's avatar
Pieter Wuille committed
211
    bool fShouldBan;
212
    // String name of this peer (debugging/logging purposes).
Pieter Wuille's avatar
Pieter Wuille committed
213
    std::string name;
214
215
    // List of asynchronously-determined block rejections to notify this peer about.
    std::vector<CBlockReject> rejects;
216
217
218
219
220
221
    list<QueuedBlock> vBlocksInFlight;
    int nBlocksInFlight;
    list<uint256> vBlocksToDownload;
    int nBlocksToDownload;
    int64_t nLastBlockReceive;
    int64_t nLastBlockProcess;
Pieter Wuille's avatar
Pieter Wuille committed
222
223
224
225

    CNodeState() {
        nMisbehavior = 0;
        fShouldBan = false;
226
227
228
229
        nBlocksToDownload = 0;
        nBlocksInFlight = 0;
        nLastBlockReceive = 0;
        nLastBlockProcess = 0;
Pieter Wuille's avatar
Pieter Wuille committed
230
231
232
    }
};

233
// Map maintaining per-node state. Requires cs_main.
Pieter Wuille's avatar
Pieter Wuille committed
234
235
236
237
238
239
240
241
242
243
244
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()
245
246
247
248
249
{
    LOCK(cs_main);
    return chainActive.Height();
}

Pieter Wuille's avatar
Pieter Wuille committed
250
251
252
253
254
255
256
257
void InitializeNode(NodeId nodeid, const CNode *pnode) {
    LOCK(cs_main);
    CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second;
    state.name = pnode->addrName;
}

void FinalizeNode(NodeId nodeid) {
    LOCK(cs_main);
258
259
260
261
262
263
    CNodeState *state = State(nodeid);

    BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight)
        mapBlocksInFlight.erase(entry.hash);
    BOOST_FOREACH(const uint256& hash, state->vBlocksToDownload)
        mapBlocksToDownload.erase(hash);
264
    EraseOrphansFor(nodeid);
265

Pieter Wuille's avatar
Pieter Wuille committed
266
267
    mapNodeState.erase(nodeid);
}
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323

// Requires cs_main.
void MarkBlockAsReceived(const uint256 &hash, NodeId nodeFrom = -1) {
    map<uint256, pair<NodeId, list<uint256>::iterator> >::iterator itToDownload = mapBlocksToDownload.find(hash);
    if (itToDownload != mapBlocksToDownload.end()) {
        CNodeState *state = State(itToDownload->second.first);
        state->vBlocksToDownload.erase(itToDownload->second.second);
        state->nBlocksToDownload--;
        mapBlocksToDownload.erase(itToDownload);
    }

    map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
    if (itInFlight != mapBlocksInFlight.end()) {
        CNodeState *state = State(itInFlight->second.first);
        state->vBlocksInFlight.erase(itInFlight->second.second);
        state->nBlocksInFlight--;
        if (itInFlight->second.first == nodeFrom)
            state->nLastBlockReceive = GetTimeMicros();
        mapBlocksInFlight.erase(itInFlight);
    }

}

// Requires cs_main.
bool AddBlockToQueue(NodeId nodeid, const uint256 &hash) {
    if (mapBlocksToDownload.count(hash) || mapBlocksInFlight.count(hash))
        return false;

    CNodeState *state = State(nodeid);
    if (state == NULL)
        return false;

    list<uint256>::iterator it = state->vBlocksToDownload.insert(state->vBlocksToDownload.end(), hash);
    state->nBlocksToDownload++;
    if (state->nBlocksToDownload > 5000)
        Misbehaving(nodeid, 10);
    mapBlocksToDownload[hash] = std::make_pair(nodeid, it);
    return true;
}

// Requires cs_main.
void MarkBlockAsInFlight(NodeId nodeid, const uint256 &hash) {
    CNodeState *state = State(nodeid);
    assert(state != NULL);

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

    QueuedBlock newentry = {hash, GetTimeMicros(), state->nBlocksInFlight};
    if (state->nBlocksInFlight == 0)
        state->nLastBlockReceive = newentry.nTime; // Reset when a first request is sent.
    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
324
325
326
327
328
329
330
331
332
333
334
}

bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) {
    LOCK(cs_main);
    CNodeState *state = State(nodeid);
    if (state == NULL)
        return false;
    stats.nMisbehavior = state->nMisbehavior;
    return true;
}

335
336
void RegisterNodeSignals(CNodeSignals& nodeSignals)
{
337
    nodeSignals.GetHeight.connect(&GetHeight);
338
339
    nodeSignals.ProcessMessages.connect(&ProcessMessages);
    nodeSignals.SendMessages.connect(&SendMessages);
Pieter Wuille's avatar
Pieter Wuille committed
340
341
    nodeSignals.InitializeNode.connect(&InitializeNode);
    nodeSignals.FinalizeNode.connect(&FinalizeNode);
342
}
Pieter Wuille's avatar
Pieter Wuille committed
343

344
345
void UnregisterNodeSignals(CNodeSignals& nodeSignals)
{
346
    nodeSignals.GetHeight.disconnect(&GetHeight);
347
348
    nodeSignals.ProcessMessages.disconnect(&ProcessMessages);
    nodeSignals.SendMessages.disconnect(&SendMessages);
Pieter Wuille's avatar
Pieter Wuille committed
349
350
    nodeSignals.InitializeNode.disconnect(&InitializeNode);
    nodeSignals.FinalizeNode.disconnect(&FinalizeNode);
351
}
Pieter Wuille's avatar
Pieter Wuille committed
352

353
354
//////////////////////////////////////////////////////////////////////////////
//
355
// CChain implementation
356
357
//

358
359
360
361
362
363
364
365
366
367
368
CBlockIndex *CChain::SetTip(CBlockIndex *pindex) {
    if (pindex == NULL) {
        vChain.clear();
        return NULL;
    }
    vChain.resize(pindex->nHeight + 1);
    while (pindex && vChain[pindex->nHeight] != pindex) {
        vChain[pindex->nHeight] = pindex;
        pindex = pindex->pprev;
    }
    return pindex;
369
370
}

371
CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const {
372
    int nStep = 1;
373
374
    std::vector<uint256> vHave;
    vHave.reserve(32);
375

376
377
378
379
380
381
382
383
384
385
386
    if (!pindex)
        pindex = Tip();
    while (pindex) {
        vHave.push_back(pindex->GetBlockHash());
        // Stop when we have added the genesis block.
        if (pindex->nHeight == 0)
            break;
        // Exponentially larger steps back, plus the genesis block.
        int nHeight = std::max(pindex->nHeight - nStep, 0);
        // In case pindex is not in this chain, iterate pindex->pprev to find blocks.
        while (pindex->nHeight > nHeight && !Contains(pindex))
387
            pindex = pindex->pprev;
388
389
390
        // If pindex is in this chain, use direct height-based access.
        if (pindex->nHeight > nHeight)
            pindex = (*this)[nHeight];
391
392
393
        if (vHave.size() > 10)
            nStep *= 2;
    }
Pieter Wuille's avatar
Pieter Wuille committed
394

395
    return CBlockLocator(vHave);
396
397
}

398
CBlockIndex *CChain::FindFork(const CBlockLocator &locator) const {
399
    // Find the first block the caller has in the main chain
400
    BOOST_FOREACH(const uint256& hash, locator.vHave) {
401
402
403
404
        std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
        if (mi != mapBlockIndex.end())
        {
            CBlockIndex* pindex = (*mi).second;
405
            if (Contains(pindex))
406
407
408
                return pindex;
        }
    }
409
    return Genesis();
410
411
}

412
CCoinsViewCache *pcoinsTip = NULL;
413
CBlockTreeDB *pblocktree = NULL;
Pieter Wuille's avatar
Pieter Wuille committed
414

s_nakamoto's avatar
s_nakamoto committed
415
416
417
418
419
//////////////////////////////////////////////////////////////////////////////
//
// mapOrphanTransactions
//

420
bool AddOrphanTx(const CTransaction& tx, NodeId peer)
s_nakamoto's avatar
s_nakamoto committed
421
422
423
{
    uint256 hash = tx.GetHash();
    if (mapOrphanTransactions.count(hash))
424
425
426
427
428
429
430
431
432
        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:
433
434
    unsigned int sz = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION);
    if (sz > 5000)
435
    {
436
        LogPrint("mempool", "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString());
437
438
        return false;
    }
439

440
441
    mapOrphanTransactions[hash].tx = tx;
    mapOrphanTransactions[hash].fromPeer = peer;
442
    BOOST_FOREACH(const CTxIn& txin, tx.vin)
443
        mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash);
444

445
446
    LogPrint("mempool", "stored orphan tx %s (mapsz %u prevsz %u)\n", hash.ToString(),
             mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
447
    return true;
s_nakamoto's avatar
s_nakamoto committed
448
449
}

Pieter Wuille's avatar
Pieter Wuille committed
450
void static EraseOrphanTx(uint256 hash)
s_nakamoto's avatar
s_nakamoto committed
451
{
452
    map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
453
    if (it == mapOrphanTransactions.end())
s_nakamoto's avatar
s_nakamoto committed
454
        return;
455
    BOOST_FOREACH(const CTxIn& txin, it->second.tx.vin)
s_nakamoto's avatar
s_nakamoto committed
456
    {
457
        map<uint256, set<uint256> >::iterator itPrev = mapOrphanTransactionsByPrev.find(txin.prevout.hash);
458
459
        if (itPrev == mapOrphanTransactionsByPrev.end())
            continue;
460
461
462
        itPrev->second.erase(hash);
        if (itPrev->second.empty())
            mapOrphanTransactionsByPrev.erase(itPrev);
s_nakamoto's avatar
s_nakamoto committed
463
    }
464
    mapOrphanTransactions.erase(it);
s_nakamoto's avatar
s_nakamoto committed
465
466
}

467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
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);
}


484
unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
485
{
486
    unsigned int nEvicted = 0;
487
488
489
    while (mapOrphanTransactions.size() > nMaxOrphans)
    {
        // Evict a random orphan:
490
        uint256 randomhash = GetRandHash();
491
        map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
492
493
494
495
496
497
498
        if (it == mapOrphanTransactions.end())
            it = mapOrphanTransactions.begin();
        EraseOrphanTx(it->first);
        ++nEvicted;
    }
    return nEvicted;
}
s_nakamoto's avatar
s_nakamoto committed
499
500
501
502
503
504
505







506
bool IsStandardTx(const CTransaction& tx, string& reason)
Gavin Andresen's avatar
Gavin Andresen committed
507
{
508
    AssertLockHeld(cs_main);
509
    if (tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) {
510
        reason = "version";
511
        return false;
512
    }
513

514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
    // 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)
    // Basically we don't want to propagate transactions that can't included in
    // 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)) {
532
        reason = "non-final";
533
        return false;
534
    }
535

536
537
538
539
    // 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.
540
    unsigned int sz = tx.GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION);
541
542
    if (sz >= MAX_STANDARD_TX_SIZE) {
        reason = "tx-size";
543
        return false;
544
    }
545

546
    BOOST_FOREACH(const CTxIn& txin, tx.vin)
Gavin Andresen's avatar
Gavin Andresen committed
547
    {
548
549
550
551
552
553
554
555
        // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
        // keys. (remember the 520 byte limit on redeemScript size) That works
        // out to a (15*(33+1))+3=513 byte redeemScript, 513+1+15*(73+1)=1624
        // 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) {
556
            reason = "scriptsig-size";
557
            return false;
558
559
560
        }
        if (!txin.scriptSig.IsPushOnly()) {
            reason = "scriptsig-not-pushonly";
561
            return false;
562
563
        }
        if (!txin.scriptSig.HasCanonicalPushes()) {
564
            reason = "scriptsig-non-canonical-push";
565
            return false;
566
        }
Gavin Andresen's avatar
Gavin Andresen committed
567
    }
568
569
570

    unsigned int nDataOut = 0;
    txnouttype whichType;
571
    BOOST_FOREACH(const CTxOut& txout, tx.vout) {
572
        if (!::IsStandard(txout.scriptPubKey, whichType)) {
573
            reason = "scriptpubkey";
574
            return false;
575
        }
576
577
578
        if (whichType == TX_NULL_DATA)
            nDataOut++;
        else if (txout.IsDust(CTransaction::nMinRelayTxFee)) {
579
            reason = "dust";
580
            return false;
581
        }
582
    }
583

584
585
    // only one OP_RETURN txout is permitted
    if (nDataOut > 1) {
586
        reason = "multi-op-return";
587
588
589
        return false;
    }

Gavin Andresen's avatar
Gavin Andresen committed
590
591
592
    return true;
}

593
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
594
{
595
    AssertLockHeld(cs_main);
596
597
598
599
    // Time based nLockTime implemented in 0.1.6
    if (tx.nLockTime == 0)
        return true;
    if (nBlockHeight == 0)
600
        nBlockHeight = chainActive.Height();
601
602
    if (nBlockTime == 0)
        nBlockTime = GetAdjustedTime();
603
    if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
604
605
606
607
608
609
610
        return true;
    BOOST_FOREACH(const CTxIn& txin, tx.vin)
        if (!txin.IsFinal())
            return false;
    return true;
}

Gavin Andresen's avatar
Gavin Andresen committed
611
612
//
// Check transaction inputs, and make sure any
613
// pay-to-script-hash transactions are evaluating IsStandard scripts
Gavin Andresen's avatar
Gavin Andresen committed
614
615
//
// Why bother? To avoid denial-of-service attacks; an attacker
616
617
618
// can submit a standard HASH... OP_EQUAL transaction,
// which will get accepted into blocks. The redemption
// script can be anything; an attacker could use a very
Gavin Andresen's avatar
Gavin Andresen committed
619
620
621
// expensive-to-check-upon-redemption script like:
//   DUP CHECKSIG DROP ... repeated 100 times... OP_1
//
622
bool AreInputsStandard(const CTransaction& tx, CCoinsViewCache& mapInputs)
Gavin Andresen's avatar
Gavin Andresen committed
623
{
624
    if (tx.IsCoinBase())
625
        return true; // Coinbases don't use vin normally
626

627
    for (unsigned int i = 0; i < tx.vin.size(); i++)
Gavin Andresen's avatar
Gavin Andresen committed
628
    {
629
        const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]);
Gavin Andresen's avatar
Gavin Andresen committed
630
631

        vector<vector<unsigned char> > vSolutions;
632
633
        txnouttype whichType;
        // get the scriptPubKey corresponding to this input:
634
        const CScript& prevScript = prev.scriptPubKey;
635
        if (!Solver(prevScript, whichType, vSolutions))
636
            return false;
637
        int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions);
638
639
        if (nArgsExpected < 0)
            return false;
640
641
642
643
644
645
646

        // Transactions with extra stuff in their scriptSigs are
        // non-standard. Note that this EvalScript() call will
        // be quick, because if there are any operations
        // beside "push data" in the scriptSig the
        // IsStandard() call returns false
        vector<vector<unsigned char> > stack;
647
        if (!EvalScript(stack, tx.vin[i].scriptSig, tx, i, false, 0))
648
649
            return false;

Gavin Andresen's avatar
Gavin Andresen committed
650
651
        if (whichType == TX_SCRIPTHASH)
        {
652
            if (stack.empty())
Gavin Andresen's avatar
Gavin Andresen committed
653
                return false;
654
            CScript subscript(stack.back().begin(), stack.back().end());
655
656
657
            vector<vector<unsigned char> > vSolutions2;
            txnouttype whichType2;
            if (!Solver(subscript, whichType2, vSolutions2))
658
                return false;
659
660
            if (whichType2 == TX_SCRIPTHASH)
                return false;
661
662
663
664
665
666

            int tmpExpected;
            tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2);
            if (tmpExpected < 0)
                return false;
            nArgsExpected += tmpExpected;
Gavin Andresen's avatar
Gavin Andresen committed
667
        }
668

669
        if (stack.size() != (unsigned int)nArgsExpected)
670
            return false;
Gavin Andresen's avatar
Gavin Andresen committed
671
672
673
674
675
    }

    return true;
}

676
unsigned int GetLegacySigOpCount(const CTransaction& tx)
677
{
678
    unsigned int nSigOps = 0;
679
    BOOST_FOREACH(const CTxIn& txin, tx.vin)
680
681
682
    {
        nSigOps += txin.scriptSig.GetSigOpCount(false);
    }
683
    BOOST_FOREACH(const CTxOut& txout, tx.vout)
684
685
686
687
688
    {
        nSigOps += txout.scriptPubKey.GetSigOpCount(false);
    }
    return nSigOps;
}
s_nakamoto's avatar
s_nakamoto committed
689

690
691
692
693
694
695
696
697
698
699
700
701
702
703
unsigned int GetP2SHSigOpCount(const CTransaction& tx, CCoinsViewCache& inputs)
{
    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
704
705
706

int CMerkleTx::SetMerkleBranch(const CBlock* pblock)
{
707
    AssertLockHeld(cs_main);
Pieter Wuille's avatar
Pieter Wuille committed
708
709
710
711
712
    CBlock blockTmp;

    if (pblock == NULL) {
        CCoins coins;
        if (pcoinsTip->GetCoins(GetHash(), coins)) {
713
            CBlockIndex *pindex = chainActive[coins.nHeight];
Pieter Wuille's avatar
Pieter Wuille committed
714
            if (pindex) {
715
                if (!ReadBlockFromDisk(blockTmp, pindex))
Pieter Wuille's avatar
Pieter Wuille committed
716
717
                    return 0;
                pblock = &blockTmp;
Pieter Wuille's avatar
Pieter Wuille committed
718
            }
s_nakamoto's avatar
s_nakamoto committed
719
        }
Pieter Wuille's avatar
Pieter Wuille committed
720
    }
s_nakamoto's avatar
s_nakamoto committed
721

Pieter Wuille's avatar
Pieter Wuille committed
722
    if (pblock) {
s_nakamoto's avatar
s_nakamoto committed
723
724
725
726
        // Update the tx's hashBlock
        hashBlock = pblock->GetHash();

        // Locate the transaction
727
        for (nIndex = 0; nIndex < (int)pblock->vtx.size(); nIndex++)
s_nakamoto's avatar
s_nakamoto committed
728
729
            if (pblock->vtx[nIndex] == *(CTransaction*)this)
                break;
730
        if (nIndex == (int)pblock->vtx.size())
s_nakamoto's avatar
s_nakamoto committed
731
732
733
        {
            vMerkleBranch.clear();
            nIndex = -1;
734
            LogPrintf("ERROR: SetMerkleBranch() : couldn't find tx in block\n");
s_nakamoto's avatar
s_nakamoto committed
735
736
737
738
739
740
741
742
743
744
745
746
            return 0;
        }

        // Fill in merkle branch
        vMerkleBranch = pblock->GetMerkleBranch(nIndex);
    }

    // Is the tx in a block that's in the main chain
    map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
    if (mi == mapBlockIndex.end())
        return 0;
    CBlockIndex* pindex = (*mi).second;
747
    if (!pindex || !chainActive.Contains(pindex))
s_nakamoto's avatar
s_nakamoto committed
748
749
        return 0;

750
    return chainActive.Height() - pindex->nHeight + 1;
s_nakamoto's avatar
s_nakamoto committed
751
752
}

753
754
755
756
757
758
759
760
761
762
int GetInputAge(CTxIn& vin)
{
    // Fetch previous transactions (inputs):
    CCoinsView viewDummy;
    CCoinsViewCache view(viewDummy);
    {
        LOCK(mempool.cs);
        CCoinsViewCache &viewChain = *pcoinsTip;
        CCoinsViewMemPool viewMempool(viewChain, mempool);
        view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
s_nakamoto's avatar
s_nakamoto committed
763

764
765
766
767
768
        const uint256& prevHash = vin.prevout.hash;
        CCoins coins;
        view.GetCoins(prevHash, coins); // this is certainly allowed to fail
        view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
    }
s_nakamoto's avatar
s_nakamoto committed
769

770
    if(!view.HaveCoins(vin.prevout.hash)) return -1;
s_nakamoto's avatar
s_nakamoto committed
771

772
    const CCoins &coins = view.GetCoins(vin.prevout.hash);
s_nakamoto's avatar
s_nakamoto committed
773

774
775
    return (chainActive.Tip()->nHeight+1) - coins.nHeight;
}
s_nakamoto's avatar
s_nakamoto committed
776
777


778
bool CheckTransaction(const CTransaction& tx, CValidationState &state)
779
780
{
    // Basic checks that don't depend on any context
781
    if (tx.vin.empty())
Gavin Andresen's avatar
Gavin Andresen committed
782
        return state.DoS(10, error("CheckTransaction() : vin empty"),
783
                         REJECT_INVALID, "bad-txns-vin-empty");
784
    if (tx.vout.empty())
Gavin Andresen's avatar
Gavin Andresen committed
785
        return state.DoS(10, error("CheckTransaction() : vout empty"),
786
                         REJECT_INVALID, "bad-txns-vout-empty");
787
    // Size limits
788
    if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
789
        return state.DoS(100, error("CheckTransaction() : size limits failed"),
790
                         REJECT_INVALID, "bad-txns-oversize");
791
792

    // Check for negative or overflow output values
793
    int64_t nValueOut = 0;
794
    BOOST_FOREACH(const CTxOut& txout, tx.vout)
795
796
    {
        if (txout.nValue < 0)
Gavin Andresen's avatar
Gavin Andresen committed
797
            return state.DoS(100, error("CheckTransaction() : txout.nValue negative"),
798
                             REJECT_INVALID, "bad-txns-vout-negative");
799
        if (txout.nValue > MAX_MONEY)
Gavin Andresen's avatar
Gavin Andresen committed
800
            return state.DoS(100, error("CheckTransaction() : txout.nValue too high"),
801
                             REJECT_INVALID, "bad-txns-vout-toolarge");
802
803
        nValueOut += txout.nValue;
        if (!MoneyRange(nValueOut))
804
            return state.DoS(100, error("CheckTransaction() : txout total out of range"),
805
                             REJECT_INVALID, "bad-txns-txouttotal-toolarge");
806
807
    }

808
809
    // Check for duplicate inputs
    set<COutPoint> vInOutPoints;
810
    BOOST_FOREACH(const CTxIn& txin, tx.vin)
811
812
    {
        if (vInOutPoints.count(txin.prevout))
813
            return state.DoS(100, error("CheckTransaction() : duplicate inputs"),
814
                             REJECT_INVALID, "bad-txns-inputs-duplicate");
815
816
817
        vInOutPoints.insert(txin.prevout);
    }

818
    if (tx.IsCoinBase())
819
    {
820
        if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
Gavin Andresen's avatar
Gavin Andresen committed
821
            return state.DoS(100, error("CheckTransaction() : coinbase script size"),
822
                             REJECT_INVALID, "bad-cb-length");
823
824
825
    }
    else
    {
826
        BOOST_FOREACH(const CTxIn& txin, tx.vin)
827
            if (txin.prevout.IsNull())
Gavin Andresen's avatar
Gavin Andresen committed
828
                return state.DoS(10, error("CheckTransaction() : prevout is null"),
829
                                 REJECT_INVALID, "bad-txns-prevout-null");
830
831
832
833
834
    }

    return true;
}

835
int64_t GetMinFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree, enum GetMinFee_mode mode)
836
{
Gavin Andresen's avatar
Gavin Andresen committed
837
    // Base fee is either nMinTxFee or nMinRelayTxFee
838
    int64_t nBaseFee = (mode == GMF_RELAY) ? tx.nMinRelayTxFee : tx.nMinTxFee;
839

840
    int64_t nMinFee = (1 + (int64_t)nBytes / 1000) * nBaseFee;
841
842
843

    if (fAllowFree)
    {
844
845
        // 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
846
847
848
849
850
        //   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.
        // * If we are creating a transaction we allow transactions up to 1,000 bytes
        //   to be considered safe and assume they can likely make it into this section.
        if (nBytes < (mode == GMF_SEND ? 1000 : (DEFAULT_BLOCK_PRIORITY_SIZE - 1000)))
851
            nMinFee = 0;
852
853
    }

854
855
856
857
    // This code can be removed after enough miners have upgraded to version 0.9.
    // Until then, be safe when sending and require a fee if any output
    // is less than CENT:
    if (nMinFee < nBaseFee && mode == GMF_SEND)
858
    {
859
        BOOST_FOREACH(const CTxOut& txout, tx.vout)
860
861
862
863
864
865
866
867
868
            if (txout.nValue < CENT)
                nMinFee = nBaseFee;
    }

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

Pieter Wuille's avatar
Pieter Wuille committed
869

870
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
871
                        bool* pfMissingInputs, bool fRejectInsaneFee, bool ignoreFees)
s_nakamoto's avatar
s_nakamoto committed
872
{
873
    AssertLockHeld(cs_main);
s_nakamoto's avatar
s_nakamoto committed
874
875
876
    if (pfMissingInputs)
        *pfMissingInputs = false;

877
    if (!CheckTransaction(tx, state))
878
        return error("AcceptToMemoryPool: : CheckTransaction failed");
879

s_nakamoto's avatar
s_nakamoto committed
880
    // Coinbase is only valid in a block, not as a loose transaction
881
    if (tx.IsCoinBase())
Gavin Andresen's avatar
Gavin Andresen committed
882
883
        return state.DoS(100, error("AcceptToMemoryPool: : coinbase as individual tx"),
                         REJECT_INVALID, "coinbase");
s_nakamoto's avatar
s_nakamoto committed
884

885
    // Rather not work on nonstandard transactions (unless -testnet/-regtest)
886
    string reason;
887
    if (Params().NetworkID() == CChainParams::MAIN && !IsStandardTx(tx, reason))
Gavin Andresen's avatar
Gavin Andresen committed
888
        return state.DoS(0,
889
                         error("AcceptToMemoryPool : nonstandard transaction: %s", reason),
Gavin Andresen's avatar
Gavin Andresen committed
890
                         REJECT_NONSTANDARD, reason);
891

Pieter Wuille's avatar
Pieter Wuille committed
892
    // is it already in the memory pool?
893
    uint256 hash = tx.GetHash();
894
895
    if (pool.exists(hash))
        return false;
s_nakamoto's avatar
s_nakamoto committed
896
897

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

911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934

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

    std::map<uint256, CTransactionLock>::iterator it = mapTxLocks.begin();

    while(it != mapTxLocks.end()) {
        if(mapTxLockReq.count((*it).second.txHash)){
            CTransaction& tx2 = mapTxLockReq[(*it).second.txHash];
            for (unsigned int a = 0; a < tx2.vin.size(); a++) {
                //we found the locked tx in the block
                if(tx2.GetHash() == tx.GetHash()) continue;

                //if there's a lock, look for conflicting inputs
                for (unsigned int b = 0; b < tx.vin.size(); b++) {
                    if(tx2.vin[a].prevout == tx.vin[b].prevout) {
                        return false;
                    }
                }
            }
        }
        it++;
    }


s_nakamoto's avatar
s_nakamoto committed
935
    {
936
937
938
939
        CCoinsView dummy;
        CCoinsViewCache view(dummy);

        {
940
941
        LOCK(pool.cs);
        CCoinsViewMemPool viewMemPool(*pcoinsTip, pool);
942
        view.SetBackend(viewMemPool);
Pieter Wuille's avatar
Pieter Wuille committed
943
944
945

        // do we already have it?
        if (view.HaveCoins(hash))
946
            return false;
Pieter Wuille's avatar
Pieter Wuille committed
947
948

        // do all inputs exist?
Pieter Wuille's avatar
Pieter Wuille committed
949
950
        // 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
951
952
953
954
955
956
        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
957
958
        }

Pieter Wuille's avatar
Pieter Wuille committed
959
        // are the actual inputs available?
960
        if (!view.HaveInputs(tx))
Gavin Andresen's avatar
Gavin Andresen committed
961
            return state.Invalid(error("AcceptToMemoryPool : inputs already spent"),
962
                                 REJECT_DUPLICATE, "bad-txns-inputs-spent");
963

964
965
966
967
968
969
        // Bring the best block into scope
        view.GetBestBlock();

        // 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
970

971
        // Check for non-standard pay-to-script-hash in inputs
972
        if (Params().NetworkID() == CChainParams::MAIN && !AreInputsStandard(tx, view))
973
            return error("AcceptToMemoryPool: : nonstandard transaction input");
Gavin Andresen's avatar
Gavin Andresen committed
974

975
976
977
978
        // Note: if you modify this code to accept non-standard transactions, then
        // you should add code here to check that the transaction does a
        // reasonable number of ECDSA signature verifications.

979
980
981
982
983
984
985
        int64_t nValueIn = view.GetValueIn(tx);
        int64_t nValueOut = tx.GetValueOut();
        int64_t nFees = nValueIn-nValueOut;
        double dPriority = view.GetPriority(tx, chainActive.Height());

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

        // Don't accept it if it can't get into a block
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
        if(!ignoreFees){
            int64_t txMinFee = GetMinFee(tx, nSize, true, GMF_RELAY);
            if (fLimitFree && nFees < txMinFee)
                return state.DoS(0, error("AcceptToMemoryPool : not enough fees %s, %d < %d",
                                          hash.ToString(), nFees, txMinFee),
                                 REJECT_INSUFFICIENTFEE, "insufficient fee");

            // Continuously rate-limit free transactions
            // This mitigates 'penny-flooding' -- sending thousands of free transactions just to
            // be annoying or make others' transactions take longer to confirm.
            if (fLimitFree && nFees < CTransaction::nMinRelayTxFee)
            {
                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"),
                                     REJECT_INSUFFICIENTFEE, "insufficient priority");
                LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
                dFreeCount += nSize;
            }
1018
        }
1019

1020
        if (fRejectInsaneFee && nFees > CTransaction::nMinRelayTxFee * 10000)
1021
            return error("AcceptToMemoryPool: : insane fees %s, %d > %d",
1022
                         hash.ToString(),
1023
1024
                         nFees, CTransaction::nMinRelayTxFee * 10000);

1025
1026
        // Check against previous transactions
        // This is done last to help prevent CPU exhaustion denial-of-service attacks.
1027
        if (!CheckInputs(tx, state, view, true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC))
1028
        {
1029
            return error("AcceptToMemoryPool: : ConnectInputs failed %s", hash.ToString());
1030
        }
1031
1032
        // Store transaction in memory
        pool.addUnchecked(hash, entry);
s_nakamoto's avatar
s_nakamoto committed
1033
1034
    }

1035
    g_signals.SyncTransaction(hash, tx, NULL);
s_nakamoto's avatar
s_nakamoto committed
1036
1037
1038
1039

    return true;
}

1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
bool AcceptableInputs(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool ignoreFees)
{
    AssertLockHeld(cs_main);

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

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

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

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

    {
        CCoinsView dummy;
        CCoinsViewCache view(dummy);

        {
            LOCK(pool.cs);
            CCoinsViewMemPool viewMemPool(*pcoinsTip, pool);
            view.SetBackend(viewMemPool);

1080
1081
1082
1083
            // do we already have it?
            if (view.HaveCoins(hash))
                return false;

1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
            // 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)) {
                    return false;
                }
            }

            // are the actual inputs available?
            if (!view.HaveInputs(tx))
                return state.Invalid(error("AcceptToMemoryPool : inputs already spent"),
                                     REJECT_DUPLICATE, "bad-txns-inputs-spent");

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

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

        // Don't accept it if it can't get into a block
        if(!ignoreFees){
            int64_t nValueIn = view.GetValueIn(tx);
            int64_t nValueOut = tx.GetValueOut();
            int64_t nFees = nValueIn-nValueOut;
            double dPriority = view.GetPriority(tx, chainActive.Height());

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

            int64_t txMinFee = GetMinFee(tx, nSize, true, GMF_RELAY);
            if (nFees < txMinFee)
                return state.DoS(0, error("AcceptToMemoryPool : not enough fees %s, %d < %d",
                                          hash.ToString(), nFees, txMinFee),
                                 REJECT_INSUFFICIENTFEE, "insufficient fee");

            // Continuously rate-limit free transactions
            // This mitigates 'penny-flooding' -- sending thousands of free transactions just to
            // be annoying or make others' transactions take longer to confirm.
            if (nFees < CTransaction::nMinRelayTxFee)
            {
                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"),
                                     REJECT_INSUFFICIENTFEE, "insufficient priority");
                LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
                dFreeCount += nSize;
            }
        }

        // Check against previous transactions
        // This is done last to help prevent CPU exhaustion denial-of-service attacks.
        if (!CheckInputs(tx, state, view, false, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC))
        {
            return error("AcceptToMemoryPool: : ConnectInputs failed %s", hash.ToString());
        }
    }

    return true;
}

1157

1158
int CMerkleTx::GetDepthInMainChainINTERNAL(CBlockIndex* &pindexRet) const
s_nakamoto's avatar
s_nakamoto committed
1159
1160
1161
{
    if (hashBlock == 0 || nIndex == -1)
        return 0;
1162
    AssertLockHeld(cs_main);
s_nakamoto's avatar
s_nakamoto committed
1163
1164
1165
1166
1167
1168

    // Find the block it claims to be in
    map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
    if (mi == mapBlockIndex.end())
        return 0;
    CBlockIndex* pindex = (*mi).second;
1169
    if (!pindex || !chainActive.Contains(pindex))
s_nakamoto's avatar
s_nakamoto committed
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
        return 0;

    // Make sure the merkle branch connects to this block
    if (!fMerkleVerified)
    {
        if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot)
            return 0;
        fMerkleVerified = true;
    }

1180
    pindexRet = pindex;
1181
    return chainActive.Height() - pindex->nHeight + 1;
s_nakamoto's avatar
s_nakamoto committed
1182
1183
}

Evan Duffield's avatar
Evan Duffield committed
1184
1185
1186
1187
int CMerkleTx::IsTransactionLocked() const
{
    if(nInstantXDepth == 0) return 0;

1188
1189
1190
1191
    //compile consessus vote
    std::map<uint256, CTransactionLock>::iterator i = mapTxLocks.find(GetHash());
    if (i != mapTxLocks.end()){
        if((*i).second.CountSignatures() >= INSTANTX_SIGNATURES_REQUIRED){
1192
            LogPrintf("InstantX::ProcessConsensusVote - Transaction Lock Is Complete %s\n", (*i).second.GetHash().ToString().c_str());
1193
            return nInstantXDepth;
Evan Duffield's avatar
Evan Duffield committed
1194
        } else {
1195
            LogPrintf("InstantX::ProcessConsensusVote - Incomplete TX Lock %d %s\n", (*i).second.CountSignatures(), (*i).second.GetHash().ToString().c_str());
1196
            return 0;
Evan Duffield's avatar
Evan Duffield committed
1197
1198
1199
1200
1201
1202
        }
    }

    return 0;
}

1203
int CMerkleTx::GetDepthInMainChain(CBlockIndex* &pindexRet, bool enableIX) const
1204
{
1205
    AssertLockHeld(cs_main);
1206
1207
1208
1209
    int nResult = GetDepthInMainChainINTERNAL(pindexRet);
    if (nResult == 0 && !mempool.exists(GetHash()))
        return -1; // Not in chain, not in mempool

1210
1211
1212
1213
1214
    if(enableIX){
        if (nResult < 6){
            int minConfirms = IsTransactionLocked();
            return minConfirms+nResult;
        }
Evan Duffield's avatar
Evan Duffield committed
1215
1216
    }

1217
1218
    return nResult;
}
s_nakamoto's avatar
s_nakamoto committed
1219
1220
1221
1222
1223

int CMerkleTx::GetBlocksToMaturity() const
{
    if (!IsCoinBase())
        return 0;
1224
    return max(0, COINBASE_MATURITY - GetDepthInMainChain());
s_nakamoto's avatar
s_nakamoto committed
1225
1226
1227
}


1228
bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree)
s_nakamoto's avatar
s_nakamoto committed
1229
{
Pieter Wuille's avatar
Pieter Wuille committed
1230
    CValidationState state;
1231
    return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL);
s_nakamoto's avatar
s_nakamoto committed
1232
1233
1234
}


1235
// 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
1236
bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
1237
{
Pieter Wuille's avatar
Pieter Wuille committed
1238
    CBlockIndex *pindexSlow = NULL;
1239
1240
1241
    {
        LOCK(cs_main);
        {
1242
            if (mempool.lookup(hash, txOut))
1243
1244
1245
1246
            {
                return true;
            }
        }
Pieter Wuille's avatar
Pieter Wuille committed
1247

1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
        if (fTxIndex) {
            CDiskTxPos postx;
            if (pblocktree->ReadTxIndex(hash, postx)) {
                CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
                CBlockHeader header;
                try {
                    file >> header;
                    fseek(file, postx.nTxOffset, SEEK_CUR);
                    file >> txOut;
                } catch (std::exception &e) {
1258
                    return error("%s : Deserialize or I/O error - %s", __func__, e.what());
1259
1260
1261
                }
                hashBlock = header.GetHash();
                if (txOut.GetHash() != hash)
1262
                    return error("%s : txid mismatch", __func__);
1263
1264
1265
1266
                return true;
            }
        }

Pieter Wuille's avatar
Pieter Wuille committed
1267
1268
1269
        if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
            int nHeight = -1;
            {
1270
                CCoinsViewCache &view = *pcoinsTip;
Pieter Wuille's avatar
Pieter Wuille committed
1271
1272
1273
1274
1275
                CCoins coins;
                if (view.GetCoins(hash, coins))
                    nHeight = coins.nHeight;
            }
            if (nHeight > 0)
1276
                pindexSlow = chainActive[nHeight];
1277
1278
        }
    }
s_nakamoto's avatar
s_nakamoto committed
1279

Pieter Wuille's avatar
Pieter Wuille committed
1280
1281
    if (pindexSlow) {
        CBlock block;
1282
        if (ReadBlockFromDisk(block, pindexSlow)) {
Pieter Wuille's avatar
Pieter Wuille committed
1283
1284
1285
1286
1287
1288
1289
1290
1291
            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
1292

Pieter Wuille's avatar
Pieter Wuille committed
1293
1294
    return false;
}
s_nakamoto's avatar
s_nakamoto committed
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305






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

1306
1307
1308
1309
1310
bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos)
{
    // Open history file to append
    CAutoFile fileout = CAutoFile(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
    if (!fileout)
1311
        return error("WriteBlockToDisk : OpenBlockFile failed");
1312
1313
1314
1315
1316
1317
1318
1319

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

    // Write block
    long fileOutPos = ftell(fileout);
    if (fileOutPos < 0)
1320
        return error("WriteBlockToDisk : ftell failed");
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
    pos.nPos = (unsigned int)fileOutPos;
    fileout << block;

    // Flush stdio buffers and commit to disk before returning
    fflush(fileout);
    if (!IsInitialBlockDownload())
        FileCommit(fileout);

    return true;
}

1332
1333
1334
1335
1336
1337
1338
bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos)
{
    block.SetNull();

    // Open history file to read
    CAutoFile filein = CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
    if (!filein)
1339
        return error("ReadBlockFromDisk : OpenBlockFile failed");
1340
1341
1342
1343
1344
1345

    // Read block
    try {
        filein >> block;
    }
    catch (std::exception &e) {
1346
        return error("%s : Deserialize or I/O error - %s", __func__, e.what());
1347
1348
1349
1350
    }

    // Check the header
    if (!CheckProofOfWork(block.GetHash(), block.nBits))
1351
        return error("ReadBlockFromDisk : Errors in block header");
1352
1353
1354
1355

    return true;
}

1356
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex)
s_nakamoto's avatar
s_nakamoto committed
1357
{
1358
    if (!ReadBlockFromDisk(block, pindex->GetBlockPos()))
s_nakamoto's avatar
s_nakamoto committed
1359
        return false;
1360
1361
    if (block.GetHash() != pindex->GetBlockHash())
        return error("ReadBlockFromDisk(CBlock&, CBlockIndex*) : GetHash() doesn't match index");
s_nakamoto's avatar
s_nakamoto committed
1362
1363
1364
    return true;
}

1365
uint256 static GetOrphanRoot(const uint256& hash)
s_nakamoto's avatar
s_nakamoto committed
1366
{
1367
1368
1369
1370
    map<uint256, COrphanBlock*>::iterator it = mapOrphanBlocks.find(hash);
    if (it == mapOrphanBlocks.end())
        return hash;

s_nakamoto's avatar
s_nakamoto committed
1371
    // Work back to the first block in the orphan chain
1372
1373
1374
1375
1376
1377
    do {
        map<uint256, COrphanBlock*>::iterator it2 = mapOrphanBlocks.find(it->second->hashPrev);
        if (it2 == mapOrphanBlocks.end())
            return it->first;
        it = it2;
    } while(true);
s_nakamoto's avatar
s_nakamoto committed
1378
1379
}

1380
1381
1382
// Remove a random orphan block (which does not have any dependent orphans).
void static PruneOrphanBlocks()
{
1383
    if (mapOrphanBlocksByPrev.size() <= (size_t)std::max((int64_t)0, GetArg("-maxorphanblocks", DEFAULT_MAX_ORPHAN_BLOCKS)))
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
        return;

    // Pick a random orphan block.
    int pos = insecure_rand() % mapOrphanBlocksByPrev.size();
    std::multimap<uint256, COrphanBlock*>::iterator it = mapOrphanBlocksByPrev.begin();
    while (pos--) it++;

    // As long as this block has other orphans depending on it, move to one of those successors.
    do {
        std::multimap<uint256, COrphanBlock*>::iterator it2 = mapOrphanBlocksByPrev.find(it->second->hashBlock);
        if (it2 == mapOrphanBlocksByPrev.end())
            break;
        it = it2;
    } while(1);

    uint256 hash = it->second->hashBlock;
    delete it->second;
    mapOrphanBlocksByPrev.erase(it);
    mapOrphanBlocks.erase(hash);
}

vertoe's avatar
vertoe committed
1405
double ConvertBitsToDouble(unsigned int nBits)
s_nakamoto's avatar
s_nakamoto committed
1406
{
vertoe's avatar
vertoe committed
1407
    int nShift = (nBits >> 24) & 0xff;
1408

vertoe's avatar
vertoe committed
1409
1410
    double dDiff =
        (double)0x0000ffff / (double)(nBits & 0x00ffffff);
s_nakamoto's avatar
s_nakamoto committed
1411

vertoe's avatar
vertoe committed
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
    while (nShift < 29)
    {
        dDiff *= 256.0;
        nShift++;
    }
    while (nShift > 29)
    {
        dDiff /= 256.0;
        nShift--;
    }

    return dDiff;
}

int64_t GetBlockValue(int nBits, int nHeight, int64_t nFees)
{
    double dDiff = (double)0x0000ffff / (double)(nBits & 0x00ffffff);

    /* fixed bug caused diff to not be correctly calculated */
    if(nHeight > 4500 || TestNet()) dDiff = ConvertBitsToDouble(nBits);

    int64_t nSubsidy = 0;
    if(nHeight >= 5465) {
        if((nHeight >= 17000 && dDiff > 75) || nHeight >= 24000) { // GPU/ASIC difficulty calc
            // 2222222/(((x+2600)/9)^2)
            nSubsidy = (2222222.0 / (pow((dDiff+2600.0)/9.0,2.0)));
            if (nSubsidy > 25) nSubsidy = 25;
            if (nSubsidy < 5) nSubsidy = 5;
        } else { // CPU mining calc
            nSubsidy = (11111.0 / (pow((dDiff+51.0)/6.0,2.0)));
            if (nSubsidy > 500) nSubsidy = 500;
            if (nSubsidy < 25) nSubsidy = 25;
        }
    } else {
        nSubsidy = (1111.0 / (pow((dDiff+1.0),2.0)));
        if (nSubsidy > 500) nSubsidy = 500;
        if (nSubsidy < 1) nSubsidy = 1;
    }

    // LogPrintf("height %u diff %4.2f reward %i \n", nHeight, dDiff, nSubsidy);
    nSubsidy *= COIN;

    if(TestNet()){
        for(int i = 46200; i <= nHeight; i += 210240) nSubsidy -= nSubsidy/14;
    } else {
        // yearly decline of production by 7.1% per year, projected 21.3M coins max by year 2050.
        for(int i = 210240; i <= nHeight; i += 210240) nSubsidy -= nSubsidy/14;
    }
s_nakamoto's avatar
s_nakamoto committed
1460
1461
1462
1463

    return nSubsidy + nFees;
}

vertoe's avatar
vertoe committed
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
int64_t GetMasternodePayment(int nHeight, int64_t blockValue)
{
    int64_t ret = blockValue/5; // start at 20%

    if(TestNet()) {
        if(nHeight > 46000)             ret += blockValue / 20; //25% - 2014-10-07
        if(nHeight > 46000+((576*1)*1)) ret += blockValue / 20; //30% - 2014-10-08
        if(nHeight > 46000+((576*1)*2)) ret += blockValue / 20; //35% - 2014-10-09
        if(nHeight > 46000+((576*1)*3)) ret += blockValue / 20; //40% - 2014-10-10
        if(nHeight > 46000+((576*1)*4)) ret += blockValue / 20; //45% - 2014-10-11
        if(nHeight > 46000+((576*1)*5)) ret += blockValue / 20; //50% - 2014-10-12
        if(nHeight > 46000+((576*1)*6)) ret += blockValue / 20; //55% - 2014-10-13
        if(nHeight > 46000+((576*1)*7)) ret += blockValue / 20; //60% - 2014-10-14
    }

1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
    if(nHeight > 158000)               ret += blockValue / 20; // 158000 - 25.0% - 2014-10-24
    if(nHeight > 158000+((576*30)* 1)) ret += blockValue / 20; // 175280 - 30.0% - 2014-11-25
    if(nHeight > 158000+((576*30)* 2)) ret += blockValue / 20; // 192560 - 35.0% - 2014-12-26
    if(nHeight > 158000+((576*30)* 3)) ret += blockValue / 40; // 209840 - 37.5% - 2015-01-26
    if(nHeight > 158000+((576*30)* 4)) ret += blockValue / 40; // 227120 - 40.0% - 2015-02-27
    if(nHeight > 158000+((576*30)* 5)) ret += blockValue / 40; // 244400 - 42.5% - 2015-03-30
    if(nHeight > 158000+((576*30)* 6)) ret += blockValue / 40; // 261680 - 45.0% - 2015-05-01
    if(nHeight > 158000+((576*30)* 7)) ret += blockValue / 40; // 278960 - 47.5% - 2015-06-01
    if(nHeight > 158000+((576*30)* 9)) ret += blockValue / 40; // 313520 - 50.0% - 2015-08-03
    if(nHeight > 158000+((576*30)*11)) ret += blockValue / 40; // 348080 - 52.5% - 2015-10-05
    if(nHeight > 158000+((576*30)*13)) ret += blockValue / 40; // 382640 - 55.0% - 2015-12-07
    if(nHeight > 158000+((576*30)*15)) ret += blockValue / 40; // 417200 - 57.5% - 2016-02-08
    if(nHeight > 158000+((576*30)*17)) ret += blockValue / 40; // 451760 - 60.0% - 2016-04-11
vertoe's avatar
vertoe committed
1492
1493
1494
1495

    return ret;
}

vertoe's avatar
vertoe committed
1496
1497
1498
static const int64_t nTargetTimespan = 24 * 60 * 60; // Darkcoin: 1 day
static const int64_t nTargetSpacing = 2.5 * 60; // Darkcoin: 2.5 minutes
static const int64_t nInterval = nTargetTimespan / nTargetSpacing; // 576 blocks
1499
1500
1501
1502
1503

//
// minimum amount of work that could possibly be required nTime after
// minimum work required was nBase
//
1504
unsigned int ComputeMinWork(unsigned int nBase, int64_t nTime)
1505
{
1506
    const CBigNum &bnLimit = Params().ProofOfWorkLimit();
1507
1508
    // Testnet has min-difficulty blocks
    // after nTargetSpacing*2 time between blocks:
1509
1510
    if (TestNet() && nTime > nTargetSpacing*2)
        return bnLimit.GetCompact();
1511

1512
1513
    CBigNum bnResult;
    bnResult.SetCompact(nBase);
1514
    while (nTime > 0 && bnResult < bnLimit)
1515
1516
1517
1518
1519
1520
    {
        // Maximum 400% adjustment...
        bnResult *= 4;
        // ... in best-case exactly 4-times-normal target time
        nTime -= nTargetTimespan*4;
    }
1521
1522
    if (bnResult > bnLimit)
        bnResult = bnLimit;
1523
1524
1525
    return bnResult.GetCompact();
}

vertoe's avatar
vertoe committed
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
unsigned int static KimotoGravityWell(const CBlockIndex* pindexLast, const CBlockHeader *pblock, uint64_t TargetBlocksSpacingSeconds, uint64_t PastBlocksMin, uint64_t PastBlocksMax) {
        const CBlockIndex *BlockLastSolved = pindexLast;
        const CBlockIndex *BlockReading = pindexLast;
        const CBlockHeader *BlockCreating = pblock;
        BlockCreating = BlockCreating;
        uint64_t PastBlocksMass = 0;
        int64_t PastRateActualSeconds = 0;
        int64_t PastRateTargetSeconds = 0;
        double PastRateAdjustmentRatio = double(1);
        CBigNum PastDifficultyAverage;
        CBigNum PastDifficultyAveragePrev;
        double EventHorizonDeviation;
        double EventHorizonDeviationFast;
        double EventHorizonDeviationSlow;

    if (BlockLastSolved == NULL || BlockLastSolved->nHeight == 0 || (uint64_t)BlockLastSolved->nHeight < PastBlocksMin) { return Params().ProofOfWorkLimit().GetCompact(); }

        for (unsigned int i = 1; BlockReading && BlockReading->nHeight > 0; i++) {
                if (PastBlocksMax > 0 && i > PastBlocksMax) { break; }
                PastBlocksMass++;

                if (i == 1) { PastDifficultyAverage.SetCompact(BlockReading->nBits); }
                else { PastDifficultyAverage = ((CBigNum().SetCompact(BlockReading->nBits) - PastDifficultyAveragePrev) / i) + PastDifficultyAveragePrev; }
                PastDifficultyAveragePrev = PastDifficultyAverage;

                PastRateActualSeconds = BlockLastSolved->GetBlockTime() - BlockReading->GetBlockTime();
                PastRateTargetSeconds = TargetBlocksSpacingSeconds * PastBlocksMass;
                PastRateAdjustmentRatio = double(1);
                if (PastRateActualSeconds < 0) { PastRateActualSeconds = 0; }
                if (PastRateActualSeconds != 0 && PastRateTargetSeconds != 0) {
                PastRateAdjustmentRatio = double(PastRateTargetSeconds) / double(PastRateActualSeconds);
                }
                EventHorizonDeviation = 1 + (0.7084 * pow((double(PastBlocksMass)/double(28.2)), -1.228));
                EventHorizonDeviationFast = EventHorizonDeviation;
                EventHorizonDeviationSlow = 1 / EventHorizonDeviation;

                if (PastBlocksMass >= PastBlocksMin) {
                        if ((PastRateAdjustmentRatio <= EventHorizonDeviationSlow) || (PastRateAdjustmentRatio >= EventHorizonDeviationFast)) { assert(BlockReading); break; }
                }
                if (BlockReading->pprev == NULL) { assert(BlockReading); break; }
                BlockReading = BlockReading->pprev;
        }

        CBigNum bnNew(PastDifficultyAverage);
        if (PastRateActualSeconds != 0 && PastRateTargetSeconds != 0) {
                bnNew *= PastRateActualSeconds;
                bnNew /= PastRateTargetSeconds;
        }

    if (bnNew > Params().ProofOfWorkLimit()) {
        bnNew = Params().ProofOfWorkLimit();
    }

    return bnNew.GetCompact();
}

1582
unsigned int static DarkGravityWave(const CBlockIndex* pindexLast, const CBlockHeader *pblock) {
vertoe's avatar
vertoe committed
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
    /* current difficulty formula, darkcoin - DarkGravity v3, written by Evan Duffield - evan@darkcoin.io */
    const CBlockIndex *BlockLastSolved = pindexLast;
    const CBlockIndex *BlockReading = pindexLast;
    const CBlockHeader *BlockCreating = pblock;
    BlockCreating = BlockCreating;
    int64_t nActualTimespan = 0;
    int64_t LastBlockTime = 0;
    int64_t PastBlocksMin = 24;
    int64_t PastBlocksMax = 24;
    int64_t CountBlocks = 0;
    CBigNum PastDifficultyAverage;
    CBigNum PastDifficultyAveragePrev;

    if (BlockLastSolved == NULL || BlockLastSolved->nHeight == 0 || BlockLastSolved->nHeight < PastBlocksMin) {
        return Params().ProofOfWorkLimit().GetCompact();
    }

    for (unsigned int i = 1; BlockReading && BlockReading->nHeight > 0; i++) {
        if (PastBlocksMax > 0 && i > PastBlocksMax) { break; }
        CountBlocks++;

        if(CountBlocks <= PastBlocksMin) {
            if (CountBlocks == 1) { PastDifficultyAverage.SetCompact(BlockReading->nBits); }
            else { PastDifficultyAverage = ((PastDifficultyAveragePrev * CountBlocks)+(CBigNum().SetCompact(BlockReading->nBits))) / (CountBlocks+1); }
            PastDifficultyAveragePrev = PastDifficultyAverage;
        }

        if(LastBlockTime > 0){
            int64_t Diff = (LastBlockTime - BlockReading->GetBlockTime());
            nActualTimespan += Diff;
        }
        LastBlockTime = BlockReading->GetBlockTime();

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

    CBigNum bnNew(PastDifficultyAverage);

1622
    int64_t _nTargetTimespan = CountBlocks*nTargetSpacing;
vertoe's avatar
vertoe committed
1623

1624
1625
1626
1627
    if (nActualTimespan < _nTargetTimespan/3)
        nActualTimespan = _nTargetTimespan/3;
    if (nActualTimespan > _nTargetTimespan*3)
        nActualTimespan = _nTargetTimespan*3;
vertoe's avatar
vertoe committed
1628
1629
1630

    // Retarget
    bnNew *= nActualTimespan;
1631
    bnNew /= _nTargetTimespan;
vertoe's avatar
vertoe committed
1632
1633
1634
1635
1636
1637
1638
1639

    if (bnNew > Params().ProofOfWorkLimit()){
        bnNew = Params().ProofOfWorkLimit();
    }

    return bnNew.GetCompact();
}

1640
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock)
s_nakamoto's avatar
s_nakamoto committed
1641
{
1642
        unsigned int retarget = DIFF_DGW;
s_nakamoto's avatar
s_nakamoto committed
1643

vertoe's avatar
vertoe committed
1644
        if (!TestNet()) {
1645
1646
            if (pindexLast->nHeight + 1 >= 34140) retarget = DIFF_DGW;
            else if (pindexLast->nHeight + 1 >= 15200) retarget = DIFF_KGW;
vertoe's avatar
vertoe committed
1647
            else retarget = DIFF_BTC;
Evan Duffield's avatar
Evan Duffield committed
1648
1649
1650
        } else {
            if (pindexLast->nHeight + 1 >= 256) retarget = DIFF_DGW;
            else retarget = DIFF_BTC;
1651
        }
s_nakamoto's avatar
s_nakamoto committed
1652

1653
1654
        // Default Bitcoin style retargeting
        if (retarget == DIFF_BTC)
1655
        {
1656
1657
1658
1659
            unsigned int nProofOfWorkLimit = Params().ProofOfWorkLimit().GetCompact();

            // Genesis block
            if (pindexLast == NULL)
1660
                return nProofOfWorkLimit;
1661
1662
1663

            // Only change once per interval
            if ((pindexLast->nHeight+1) % nInterval != 0)
1664
            {
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
                // Special difficulty rule for testnet:
                if (TestNet())
                {
                    // If the new block's timestamp is more than 2* 10 minutes
                    // then allow mining of a min-difficulty block.
                    if (pblock->nTime > pindexLast->nTime + nTargetSpacing*2)
                        return nProofOfWorkLimit;
                    else
                    {
                        // Return the last non-special-min-difficulty-rules-block
                        const CBlockIndex* pindex = pindexLast;
                        while (pindex->pprev && pindex->nHeight % nInterval != 0 && pindex->nBits == nProofOfWorkLimit)
                            pindex = pindex->pprev;
                        return pindex->nBits;
                    }
                }
                return pindexLast->nBits;
1682
            }
s_nakamoto's avatar
s_nakamoto committed
1683

1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
            // Darkcoin: This fixes an issue where a 51% attack can change difficulty at will.
            // Go back the full period unless it's the first retarget after genesis.
            // Code courtesy of Art Forz.
            int blockstogoback = nInterval-1;
            if ((pindexLast->nHeight+1) != nInterval)
                blockstogoback = nInterval;

            // Go back by what we want to be 14 days worth of blocks
            const CBlockIndex* pindexFirst = pindexLast;
            for (int i = 0; pindexFirst && i < blockstogoback; i++)
                pindexFirst = pindexFirst->pprev;
            assert(pindexFirst);

            // Limit adjustment step
            int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
            LogPrintf("  nActualTimespan = %d  before bounds\n", nActualTimespan);
            if (nActualTimespan < nTargetTimespan/4)
                nActualTimespan = nTargetTimespan/4;
            if (nActualTimespan > nTargetTimespan*4)
                nActualTimespan = nTargetTimespan*4;

            // Retarget
            CBigNum bnNew;
            bnNew.SetCompact(pindexLast->nBits);
            bnNew *= nActualTimespan;
            bnNew /= nTargetTimespan;

            if (bnNew > Params().ProofOfWorkLimit())
                bnNew = Params().ProofOfWorkLimit();

            /// debug print
            LogPrintf("GetNextWorkRequired RETARGET\n");
            LogPrintf("nTargetTimespan = %d    nActualTimespan = %d\n", nTargetTimespan, nActualTimespan);
            LogPrintf("Before: %08x  %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString());
            LogPrintf("After:  %08x  %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString());

            return bnNew.GetCompact();
s_nakamoto's avatar
s_nakamoto committed
1721

1722
        }
s_nakamoto's avatar
s_nakamoto committed
1723

1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
        // Retarget using Kimoto Gravity Wave
        else if (retarget == DIFF_KGW)
        {
            static const uint64_t blocksTargetSpacing = 2.5 * 60; // 2.5 minutes
            static const unsigned int timeDaySeconds = 60 * 60 * 24;
            uint64_t pastSecondsMin = timeDaySeconds * 0.025;
            uint64_t pastSecondsMax = timeDaySeconds * 7;
            uint64_t pastBlocksMin = pastSecondsMin / blocksTargetSpacing;
            uint64_t pastBlocksMax = pastSecondsMax / blocksTargetSpacing;

            return KimotoGravityWell(pindexLast, pblock, blocksTargetSpacing, pastBlocksMin, pastBlocksMax);
        }
s_nakamoto's avatar
s_nakamoto committed
1736

1737
1738
1739
1740
1741
        // Retarget using Dark Gravity Wave 3
        else if (retarget == DIFF_DGW)
        {
            return DarkGravityWave(pindexLast, pblock);
        }
s_nakamoto's avatar
s_nakamoto committed
1742

1743
        return DarkGravityWave(pindexLast, pblock);
s_nakamoto's avatar
s_nakamoto committed
1744
1745
1746
1747
1748
1749
1750
1751
}

bool CheckProofOfWork(uint256 hash, unsigned int nBits)
{
    CBigNum bnTarget;
    bnTarget.SetCompact(nBits);

    // Check range
1752
    if (bnTarget <= 0 || bnTarget > Params().ProofOfWorkLimit())
s_nakamoto's avatar
s_nakamoto committed
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
        return error("CheckProofOfWork() : nBits below minimum work");

    // Check proof of work matches claimed amount
    if (hash > bnTarget.getuint256())
        return error("CheckProofOfWork() : hash doesn't match nBits");

    return true;
}

bool IsInitialBlockDownload()
{
1764
    LOCK(cs_main);
1765
    if (fImporting || fReindex || chainActive.Height() < Checkpoints::GetTotalBlocksEstimate())
s_nakamoto's avatar
s_nakamoto committed
1766
        return true;
1767
    static int64_t nLastUpdate;
s_nakamoto's avatar
s_nakamoto committed
1768
    static CBlockIndex* pindexLastBest;
1769
    if (chainActive.Tip() != pindexLastBest)
s_nakamoto's avatar
s_nakamoto committed
1770
    {
1771
        pindexLastBest = chainActive.Tip();
s_nakamoto's avatar
s_nakamoto committed
1772
1773
1774
        nLastUpdate = GetTime();
    }
    return (GetTime() - nLastUpdate < 10 &&
1775
            chainActive.Tip()->GetBlockTime() < GetTime() - 24 * 60 * 60);
s_nakamoto's avatar
s_nakamoto committed
1776
1777
}

1778
bool fLargeWorkForkFound = false;
1779
bool fLargeWorkInvalidChainFound = false;
1780
1781
1782
1783
CBlockIndex *pindexBestForkTip = NULL, *pindexBestForkBase = NULL;

void CheckForkWarningConditions()
{
1784
    AssertLockHeld(cs_main);
1785
1786
1787
1788
1789
    // 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;

1790
1791
    // If our best fork is no longer within 72 blocks (+/- 12 hours if no one mines it)
    // of our head, drop it
1792
    if (pindexBestForkTip && chainActive.Height() - pindexBestForkTip->nHeight >= 72)
1793
1794
        pindexBestForkTip = NULL;

1795
    if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > chainActive.Tip()->nChainWork + (chainActive.Tip()->GetBlockWork() * 6).getuint256()))
1796
    {
1797
        if (!fLargeWorkForkFound && pindexBestForkBase)
1798
        {
1799
            if(pindexBestForkBase->phashBlock){
1800
1801
1802
1803
                std::string warning = std::string("'Warning: Large-work fork detected, forking after block ") +
                    pindexBestForkBase->phashBlock->ToString() + std::string("'");
                CAlert::Notify(warning, true);
            }
1804
        }
1805
        if (pindexBestForkTip && pindexBestForkBase)
1806
        {
1807
1808
1809
1810
1811
1812
            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;
            }
1813
1814
1815
        }
        else
        {
1816
            LogPrintf("CheckForkWarningConditions: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n");
1817
1818
1819
1820
1821
            fLargeWorkInvalidChainFound = true;
        }
    }
    else
    {
1822
        fLargeWorkForkFound = false;
1823
1824
        fLargeWorkInvalidChainFound = false;
    }
1825
1826
1827
1828
}

void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip)
{
1829
    AssertLockHeld(cs_main);
1830
1831
    // If we are on a fork that is sufficiently large, set a warning flag
    CBlockIndex* pfork = pindexNewForkTip;
1832
    CBlockIndex* plonger = chainActive.Tip();
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
    while (pfork && pfork != plonger)
    {
        while (plonger && plonger->nHeight > pfork->nHeight)
            plonger = plonger->pprev;
        if (pfork == plonger)
            break;
        pfork = pfork->pprev;
    }

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

    CheckForkWarningConditions();
}

1860
// Requires cs_main.
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
void Misbehaving(NodeId pnode, int howmuch)
{
    if (howmuch == 0)
        return;

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

    state->nMisbehavior += howmuch;
    if (state->nMisbehavior >= GetArg("-banscore", 100))
    {
        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
1879
void static InvalidChainFound(CBlockIndex* pindexNew)
s_nakamoto's avatar
s_nakamoto committed
1880
{
1881
    if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
s_nakamoto's avatar
s_nakamoto committed
1882
    {
1883
1884
1885
1886
1887
        pindexBestInvalid = pindexNew;
        // The current code doesn't actually read the BestInvalidWork entry in
        // the block database anymore, as it is derived from the flags in block
        // index entry. We only write it for backward compatibility.
        pblocktree->WriteBestInvalidWork(CBigNum(pindexBestInvalid->nChainWork));
1888
        uiInterface.NotifyBlocksChanged();
s_nakamoto's avatar
s_nakamoto committed
1889
    }
1890
    LogPrintf("InvalidChainFound: invalid block=%s  height=%d  log2_work=%.8g  date=%s\n",
1891
      pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
Pieter Wuille's avatar
Pieter Wuille committed
1892
      log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S",
1893
      pindexNew->GetBlockTime()));
1894
    LogPrintf("InvalidChainFound:  current best=%s  height=%d  log2_work=%.8g  date=%s\n",
1895
1896
      chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0),
      DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()));
1897
    CheckForkWarningConditions();
s_nakamoto's avatar
s_nakamoto committed
1898
1899
}

1900
1901
1902
1903
1904
1905
1906
1907
1908
void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state) {
    int nDoS = 0;
    if (state.IsInvalid(nDoS)) {
        std::map<uint256, NodeId>::iterator it = mapBlockSource.find(pindex->GetBlockHash());
        if (it != mapBlockSource.end() && State(it->second)) {
            CBlockReject reject = {state.GetRejectCode(), state.GetRejectReason(), pindex->GetBlockHash()};
            State(it->second)->rejects.push_back(reject);
            if (nDoS > 0)
                Misbehaving(it->second, nDoS);
1909
        }
1910
1911
1912
1913
1914
1915
1916
    }
    if (!state.CorruptionPossible()) {
        pindex->nStatus |= BLOCK_FAILED_VALID;
        pblocktree->WriteBlockIndex(CDiskBlockIndex(pindex));
        setBlockIndexValid.erase(pindex);
        InvalidChainFound(pindex);
    }
1917
1918
}

1919
void UpdateTime(CBlockHeader& block, const CBlockIndex* pindexPrev)
1920
{
1921
    block.nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
1922
1923

    // Updating time can change work required on testnet:
1924
    if (TestNet())
1925
        block.nBits = GetNextWorkRequired(pindexPrev, &block);
1926
1927
}

1928
void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight, const uint256 &txhash)
Pieter Wuille's avatar
Pieter Wuille committed
1929
{
1930
    bool ret;
Pieter Wuille's avatar
Pieter Wuille committed
1931
    // mark inputs spent
1932
1933
    if (!tx.IsCoinBase()) {
        BOOST_FOREACH(const CTxIn &txin, tx.vin) {
Pieter Wuille's avatar
Pieter Wuille committed
1934
            CCoins &coins = inputs.GetCoins(txin.prevout.hash);
Pieter Wuille's avatar
Pieter Wuille committed
1935
            CTxInUndo undo;
1936
1937
            ret = coins.Spend(txin.prevout, undo);
            assert(ret);
Pieter Wuille's avatar
Pieter Wuille committed
1938
1939
1940
1941
1942
            txundo.vprevout.push_back(undo);
        }
    }

    // add outputs
1943
1944
    ret = inputs.SetCoins(txhash, CCoins(tx, nHeight));
    assert(ret);
Pieter Wuille's avatar
Pieter Wuille committed
1945
1946
}

1947
1948
1949
bool CScriptCheck::operator()() const {
    const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
    if (!VerifyScript(scriptSig, scriptPubKey, *ptxTo, nIn, nFlags, nHashType))
1950
        return error("CScriptCheck() : %s VerifySignature failed", ptxTo->GetHash().ToString());
1951
1952
1953
    return true;
}

Pieter Wuille's avatar
Pieter Wuille committed
1954
1955
bool VerifySignature(const CCoins& txFrom, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType)
{
1956
    return CScriptCheck(txFrom, txTo, nIn, flags, nHashType)();
Pieter Wuille's avatar
Pieter Wuille committed
1957
1958
}

1959
bool CheckInputs(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, std::vector<CScriptCheck> *pvChecks)
s_nakamoto's avatar
s_nakamoto committed
1960
{
1961
    if (!tx.IsCoinBase())
s_nakamoto's avatar
s_nakamoto committed
1962
    {
1963
        if (pvChecks)
1964
            pvChecks->reserve(tx.vin.size());
1965

Pieter Wuille's avatar
Pieter Wuille committed
1966
1967
        // 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.
1968
        if (!inputs.HaveInputs(tx))
1969
            return state.Invalid(error("CheckInputs() : %s inputs unavailable", tx.GetHash().ToString()));
Pieter Wuille's avatar
Pieter Wuille committed
1970

1971
1972
        // While checking, GetBestBlock() refers to the parent block.
        // This is also true for mempool checks.
1973
1974
        CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second;
        int nSpendHeight = pindexPrev->nHeight + 1;
1975
1976
        int64_t nValueIn = 0;
        int64_t nFees = 0;
1977
        for (unsigned int i = 0; i < tx.vin.size(); i++)
s_nakamoto's avatar
s_nakamoto committed
1978
        {
1979
            const COutPoint &prevout = tx.vin[i].prevout;
Pieter Wuille's avatar
Pieter Wuille committed
1980
            const CCoins &coins = inputs.GetCoins(prevout.hash);
s_nakamoto's avatar
s_nakamoto committed
1981
1982

            // If prev is coinbase, check that it's matured
Pieter Wuille's avatar
Pieter Wuille committed
1983
            if (coins.IsCoinBase()) {
1984
                if (nSpendHeight - coins.nHeight < COINBASE_MATURITY)
Gavin Andresen's avatar
Gavin Andresen committed
1985
1986
                    return state.Invalid(
                        error("CheckInputs() : tried to spend coinbase at depth %d", nSpendHeight - coins.nHeight),
1987
                        REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
Pieter Wuille's avatar
Pieter Wuille committed
1988
            }
s_nakamoto's avatar
s_nakamoto committed
1989

1990
            // Check for negative or overflow input values
Pieter Wuille's avatar
Pieter Wuille committed
1991
1992
            nValueIn += coins.vout[prevout.n].nValue;
            if (!MoneyRange(coins.vout[prevout.n].nValue) || !MoneyRange(nValueIn))
Gavin Andresen's avatar
Gavin Andresen committed
1993
                return state.DoS(100, error("CheckInputs() : txin values out of range"),
1994
                                 REJECT_INVALID, "bad-txns-inputvalues-outofrange");
1995
1996

        }
Pieter Wuille's avatar
Pieter Wuille committed
1997

1998
        if (nValueIn < tx.GetValueOut())
1999
            return state.DoS(100, error("CheckInputs() : %s value in < value out", tx.GetHash().ToString()),
2000
                             REJECT_INVALID, "bad-txns-in-belowout");
Pieter Wuille's avatar
Pieter Wuille committed
2001
2002

        // Tally transaction fees
2003
        int64_t nTxFee = nValueIn - tx.GetValueOut();
Pieter Wuille's avatar
Pieter Wuille committed
2004
        if (nTxFee < 0)
2005
            return state.DoS(100, error("CheckInputs() : %s nTxFee < 0", tx.GetHash().ToString()),
2006
                             REJECT_INVALID, "bad-txns-fee-negative");
Pieter Wuille's avatar
Pieter Wuille committed
2007
2008
        nFees += nTxFee;
        if (!MoneyRange(nFees))
Gavin Andresen's avatar
Gavin Andresen committed
2009
            return state.DoS(100, error("CheckInputs() : nFees out of range"),
2010
                             REJECT_INVALID, "bad-txns-fee-outofrange");
Pieter Wuille's avatar
Pieter Wuille committed
2011

2012
2013
2014
2015
        // 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
2016
        // Skip ECDSA signature verification when connecting blocks
2017
        // before the last block chain checkpoint. This is safe because block merkle hashes are
Pieter Wuille's avatar
Pieter Wuille committed
2018
        // still computed and checked, and any change will be caught at the next checkpoint.
2019
        if (fScriptChecks) {
2020
2021
            for (unsigned int i = 0; i < tx.vin.size(); i++) {
                const COutPoint &prevout = tx.vin[i].prevout;
Pieter Wuille's avatar
Pieter Wuille committed
2022
                const CCoins &coins = inputs.GetCoins(prevout.hash);
2023

2024
                // Verify signature
2025
                CScriptCheck check(coins, tx, i, flags, 0);
2026
2027
2028
                if (pvChecks) {
                    pvChecks->push_back(CScriptCheck());
                    check.swap(pvChecks->back());
2029
2030
2031
2032
                } else if (!check()) {
                    if (flags & SCRIPT_VERIFY_STRICTENC) {
                        // For now, check whether the failure was caused by non-canonical
                        // encodings or not; if so, don't trigger DoS protection.
2033
                        CScriptCheck check(coins, tx, i, flags & (~SCRIPT_VERIFY_STRICTENC), 0);
2034
                        if (check())
Gavin Andresen's avatar
Gavin Andresen committed
2035
                            return state.Invalid(false, REJECT_NONSTANDARD, "non-canonical");
2036
                    }
Gavin Andresen's avatar
Gavin Andresen committed
2037
                    return state.DoS(100,false, REJECT_NONSTANDARD, "non-canonical");
2038
                }
2039
            }
s_nakamoto's avatar
s_nakamoto committed
2040
2041
2042
2043
2044
2045
        }
    }

    return true;
}

2046
bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
s_nakamoto's avatar
s_nakamoto committed
2047
{
2048
    assert(pindex->GetBlockHash() == view.GetBestBlock());
s_nakamoto's avatar
s_nakamoto committed
2049

2050
2051
2052
2053
2054
    if (pfClean)
        *pfClean = false;

    bool fClean = true;

Pieter Wuille's avatar
Pieter Wuille committed
2055
    CBlockUndo blockUndo;
Pieter Wuille's avatar
Pieter Wuille committed
2056
2057
2058
2059
2060
    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
2061

2062
    if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
2063
        return error("DisconnectBlock() : block and undo data inconsistent");
Pieter Wuille's avatar
Pieter Wuille committed
2064
2065

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

2070
2071
2072
2073
2074
2075
        // 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.
        CCoins outsEmpty;
        CCoins &outs = view.HaveCoins(hash) ? view.GetCoins(hash) : outsEmpty;
2076
        outs.ClearUnspendable();
Pieter Wuille's avatar
Pieter Wuille committed
2077
2078

        CCoins outsBlock = CCoins(tx, pindex->nHeight);
2079
2080
2081
2082
2083
        // 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)
            outs.nVersion = outsBlock.nVersion;
Pieter Wuille's avatar
Pieter Wuille committed
2084
        if (outs != outsBlock)
2085
            fClean = fClean && error("DisconnectBlock() : added transaction mismatch? database corrupted");
Pieter Wuille's avatar
Pieter Wuille committed
2086
2087

        // remove outputs
Pieter Wuille's avatar
Pieter Wuille committed
2088
        outs = CCoins();
Pieter Wuille's avatar
Pieter Wuille committed
2089
2090
2091
2092

        // restore inputs
        if (i > 0) { // not coinbases
            const CTxUndo &txundo = blockUndo.vtxundo[i-1];
2093
2094
            if (txundo.vprevout.size() != tx.vin.size())
                return error("DisconnectBlock() : transaction and undo data inconsistent");
Pieter Wuille's avatar
Pieter Wuille committed
2095
2096
2097
2098
2099
            for (unsigned int j = tx.vin.size(); j-- > 0;) {
                const COutPoint &out = tx.vin[j].prevout;
                const CTxInUndo &undo = txundo.vprevout[j];
                CCoins coins;
                view.GetCoins(out.hash, coins); // this can fail if the prevout was already entirely spent
2100
2101
2102
2103
2104
                if (undo.nHeight != 0) {
                    // undo data contains height: this is the last output of the prevout tx being spent
                    if (!coins.IsPruned())
                        fClean = fClean && error("DisconnectBlock() : undo data overwriting existing transaction");
                    coins = CCoins();
Pieter Wuille's avatar
Pieter Wuille committed
2105
2106
2107
2108
                    coins.fCoinBase = undo.fCoinBase;
                    coins.nHeight = undo.nHeight;
                    coins.nVersion = undo.nVersion;
                } else {
2109
2110
                    if (coins.IsPruned())
                        fClean = fClean && error("DisconnectBlock() : undo data adding output to missing transaction");
Pieter Wuille's avatar
Pieter Wuille committed
2111
2112
                }
                if (coins.IsAvailable(out.n))
2113
                    fClean = fClean && error("DisconnectBlock() : undo data overwriting existing output");
Pieter Wuille's avatar
Pieter Wuille committed
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
                if (coins.vout.size() < out.n+1)
                    coins.vout.resize(out.n+1);
                coins.vout[out.n] = undo.txout;
                if (!view.SetCoins(out.hash, coins))
                    return error("DisconnectBlock() : cannot restore coin inputs");
            }
        }
    }

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

2126
2127
2128
2129
2130
2131
    if (pfClean) {
        *pfClean = fClean;
        return true;
    } else {
        return fClean;
    }
s_nakamoto's avatar
s_nakamoto committed
2132
2133
}

2134
2135
2136
2137
2138
2139
2140
2141
2142

/*
    DisconnectBlockAndInputs

    Remove conflicting blocks for successful InstantX transaction locks
    This should be very rare (Probably will never happen)
*/
bool DisconnectBlockAndInputs(CValidationState &state, CTransaction txLock)
{
Evan Duffield's avatar
Evan Duffield committed
2143
2144
    /*
    // All modifications to the coin state will be done in this cache.
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
    // Only when all have succeeded, we push it to pcoinsTip.
    CCoinsViewCache view(*pcoinsTip, true);

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

    int HeightMin = chainActive.Tip()->nHeight-5;
    bool foundConflictingTx = false;

    //remove anything conflicting in the memory pool
Evan Duffield's avatar
Evan Duffield committed
2155
2156
2157
    list<CTransaction> txConflicted;
    mempool.removeConflicts(txLock, txConflicted);

2158
2159
2160
2161
2162
2163
2164
2165
2166

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

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

        CBlock block;
Evan Duffield's avatar
Evan Duffield committed
2167
        if (!ReadBlockFromDisk(block, BlockReading))
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
            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() && BlockReading->nHeight > HeightMin){
                BOOST_FOREACH(const CTxIn& in1, txLock.vin){
                    BOOST_FOREACH(const CTxIn& in2, tx.vin){
                        if(in1 == in2) foundConflictingTx = true;
                    }
                }
            }
        }

        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) {
Evan Duffield's avatar
Evan Duffield committed
2193
        LogPrintf("REORGANIZE: Disconnect Conflicting Blocks %lli blocks; %s..\n", vDisconnect.size(), pindexNew->GetBlockHash().ToString().c_str());
2194
2195
2196
2197
2198
2199
2200
2201
2202
        BOOST_FOREACH(CBlockIndex* pindex, vDisconnect) {
            LogPrintf(" -- disconnect %s\n", pindex->GetBlockHash().ToString().c_str());
        }
    }

    // Disconnect shorter branch
    vector<CTransaction> vResurrect;
    BOOST_FOREACH(CBlockIndex* pindex, vDisconnect) {
        CBlock block;
Evan Duffield's avatar
Evan Duffield committed
2203
        if (!ReadBlockFromDisk(block, pindex))
2204
            return state.Abort(_("Failed to read block"));
Evan Duffield's avatar
Evan Duffield committed
2205
2206
        int64_t nStart = GetTimeMicros();
        if (!DisconnectBlock(block, state, pindex, view))
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
            return error("DisconnectBlockAndInputs/SetBestBlock() : DisconnectBlock %s failed", pindex->GetBlockHash().ToString().c_str());
        if (fBenchmark)
            LogPrintf("- Disconnect: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);

        // 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() && pindex->nHeight > HeightMin){
                bool isConflict = false;
                BOOST_FOREACH(const CTxIn& in1, txLock.vin){
                    BOOST_FOREACH(const CTxIn& in2, tx.vin){
                        if(in1 != in2) isConflict = true;
                    }
                }
                if(!isConflict) vResurrect.push_back(tx);
            }
        }

    }

Evan Duffield's avatar
Evan Duffield committed
2228
    mempool.check(pcoinsTip);
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241

    // At this point, all changes have been done to the database.
    // Proceed by updating the memory structures.

    // Disconnect shorter branch
    BOOST_FOREACH(CBlockIndex* pindex, vDisconnect)
        if (pindex->pprev)
            pindex->pprev->pnext = NULL;

    // Resurrect memory transactions that were in the disconnected branch
    BOOST_FOREACH(CTransaction& tx, vResurrect) {
        // ignore validation errors in resurrected transactions
        CValidationState stateDummy;
Evan Duffield's avatar
Evan Duffield committed
2242
        if (!tx.AcceptToMemoryPool(mempool, stateDummy, tx, true, false))
2243
2244
2245
2246
            mempool.remove(tx, true);
    }

    // Update best block in wallet (so we can detect restored wallets)
Evan Duffield's avatar
Evan Duffield committed
2247

2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
    if ((pindexNew->nHeight % 20160) == 0 || (!fIsInitialDownload && (pindexNew->nHeight % 144) == 0))
    {
        const CBlockLocator locator(pindexNew);
        ::SetBestChain(locator);
    }

    // New best block
    hashBestChain = pindexNew->GetBlockHash();
    chainActive.Tip() = pindexNew;
    pblockindexFBBHLast = NULL;
    chainActive.Tip()->nHeight = chainActive.Tip()->nHeight;
    nBestChainWork = pindexNew->nChainWork;
    nTimeBestReceived = GetTime();
    nTransactionsUpdated++;
    LogPrintf("DisconnectBlockAndInputs / SetBestChain: new best=%s  height=%d  log2_work=%.8g  tx=%lu  date=%s progress=%f\n",
      hashBestChain.ToString().c_str(), chainActive.Tip()->nHeight, log(nBestChainWork.getdouble())/log(2.0), (unsigned long)pindexNew->nChainTx,
      DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()).c_str(),
      Checkpoints::GuessVerificationProgress(chainActive.Tip()));

    // Check the version of the last 100 blocks to see if we need to upgrade:
    if (!fIsInitialDownload)
    {
        int nUpgraded = 0;
        const CBlockIndex* pindex = chainActive.Tip();
        for (int i = 0; i < 100 && pindex != NULL; i++)
        {
            if (pindex->nVersion > CBlock::CURRENT_VERSION)
                ++nUpgraded;
            pindex = pindex->pprev;
        }
        if (nUpgraded > 0)
            LogPrintf("DisconnectBlockAndInputs/SetBestChain: %d of last 100 blocks above version %d\n", nUpgraded, CBlock::CURRENT_VERSION);
        if (nUpgraded > 100/2)
            // strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user:
            strMiscWarning = _("Warning: This version is obsolete, upgrade required!");
    }

    std::string strCmd = GetArg("-blocknotify", "");

    if (!fIsInitialDownload && !strCmd.empty())
    {
        boost::replace_all(strCmd, "%s", hashBestChain.GetHex());
        boost::thread t(runCommand, strCmd); // thread runs free
    }
Evan Duffield's avatar
Evan Duffield committed
2292
2293

*/    return true;
2294
2295
}

2296
void static FlushBlockFile(bool fFinalize = false)
Pieter Wuille's avatar
Pieter Wuille committed
2297
2298
2299
{
    LOCK(cs_LastBlockFile);

2300
    CDiskBlockPos posOld(nLastBlockFile, 0);
Pieter Wuille's avatar
Pieter Wuille committed
2301
2302

    FILE *fileOld = OpenBlockFile(posOld);
2303
    if (fileOld) {
2304
2305
        if (fFinalize)
            TruncateFile(fileOld, infoLastBlockFile.nSize);
2306
2307
2308
        FileCommit(fileOld);
        fclose(fileOld);
    }
Pieter Wuille's avatar
Pieter Wuille committed
2309
2310

    fileOld = OpenUndoFile(posOld);
2311
    if (fileOld) {
2312
2313
        if (fFinalize)
            TruncateFile(fileOld, infoLastBlockFile.nUndoSize);
2314
2315
2316
        FileCommit(fileOld);
        fclose(fileOld);
    }
Pieter Wuille's avatar
Pieter Wuille committed
2317
2318
}

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

2321
2322
static CCheckQueue<CScriptCheck> scriptcheckqueue(128);

2323
void ThreadScriptCheck() {
vertoe's avatar
vertoe committed
2324
    RenameThread("darkcoin-scriptch");
2325
2326
2327
    scriptcheckqueue.Thread();
}

2328
bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck)
s_nakamoto's avatar
s_nakamoto committed
2329
{
2330
    AssertLockHeld(cs_main);
s_nakamoto's avatar
s_nakamoto committed
2331
    // Check it again in case a previous version let a bad block in
2332
    if (!CheckBlock(block, state, !fJustCheck, !fJustCheck))
s_nakamoto's avatar
s_nakamoto committed
2333
2334
        return false;

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

2339
2340
    // Special case for the genesis block, skipping connection of its transactions
    // (its coinbase is unspendable)
2341
    if (block.GetHash() == Params().HashGenesisBlock()) {
2342
        view.SetBestBlock(pindex->GetBlockHash());
2343
2344
        return true;
    }
2345
2346
    bool fScriptChecks = pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate();

2347
2348
2349
2350
2351
2352
2353
    // Do not allow blocks that contain transactions which 'overwrite' older transactions,
    // unless those are already completely spent.
    // If such overwrites are allowed, coinbases and transactions depending upon those
    // can be duplicated to remove the ability to spend the first instance -- even after
    // being sent to another address.
    // See BIP30 and http://r6.ca/blog/20120206T005236Z.html for more information.
    // This logic is not necessary for memory pool transactions, as AcceptToMemoryPool
2354
    // already refuses previously-known transaction ids entirely.
2355
2356
2357
2358
    // This rule was originally applied all blocks whose timestamp was after March 15, 2012, 0:00 UTC.
    // Now that the whole chain is irreversibly beyond that time it is applied to all blocks except the
    // two in the chain that violate it. This prevents exploiting the issue against nodes in their
    // initial block download.
2359
2360
    bool fEnforceBIP30 = (!pindex->phashBlock) || // Enforce on CreateNewBlock invocations which don't have a hash.
                          !((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
2361
                           (pindex->nHeight==91880 && pindex->GetBlockHash() == uint256("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")));
Pieter Wuille's avatar
Pieter Wuille committed
2362
    if (fEnforceBIP30) {
2363
2364
        for (unsigned int i = 0; i < block.vtx.size(); i++) {
            uint256 hash = block.GetTxHash(i);
Pieter Wuille's avatar
Pieter Wuille committed
2365
            if (view.HaveCoins(hash) && !view.GetCoins(hash).IsPruned())
Gavin Andresen's avatar
Gavin Andresen committed
2366
                return state.DoS(100, error("ConnectBlock() : tried to overwrite transaction"),
2367
                                 REJECT_INVALID, "bad-txns-BIP30");
Pieter Wuille's avatar
Pieter Wuille committed
2368
2369
        }
    }
2370

2371
    // BIP16 didn't become active until Apr 1 2012
2372
    int64_t nBIP16SwitchTime = 1333238400;
2373
    bool fStrictPayToScriptHash = (pindex->nTime >= nBIP16SwitchTime);
2374

2375
2376
2377
    unsigned int flags = SCRIPT_VERIFY_NOCACHE |
                         (fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE);

Pieter Wuille's avatar
Pieter Wuille committed
2378
2379
    CBlockUndo blockundo;

2380
2381
    CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL);

2382
2383
    int64_t nStart = GetTimeMicros();
    int64_t nFees = 0;
2384
    int nInputs = 0;
2385
    unsigned int nSigOps = 0;
2386
    CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
2387
    std::vector<std::pair<uint256, CDiskTxPos> > vPos;
2388
2389
    vPos.reserve(block.vtx.size());
    for (unsigned int i = 0; i < block.vtx.size(); i++)
s_nakamoto's avatar
s_nakamoto committed
2390
    {
2391
        const CTransaction &tx = block.vtx[i];
Pieter Wuille's avatar
Pieter Wuille committed
2392

2393
        nInputs += tx.vin.size();
2394
        nSigOps += GetLegacySigOpCount(tx);
2395
        if (nSigOps > MAX_BLOCK_SIGOPS)
Gavin Andresen's avatar
Gavin Andresen committed
2396
            return state.DoS(100, error("ConnectBlock() : too many sigops"),
2397
                             REJECT_INVALID, "bad-blk-sigops");
2398

2399
2400
        if (!tx.IsCoinBase())
        {
2401
            if (!view.HaveInputs(tx))
Gavin Andresen's avatar
Gavin Andresen committed
2402
                return state.DoS(100, error("ConnectBlock() : inputs missing/spent"),
2403
                                 REJECT_INVALID, "bad-txns-inputs-missingorspent");
2404

2405
2406
2407
2408
2409
            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.
2410
                nSigOps += GetP2SHSigOpCount(tx, view);
2411
                if (nSigOps > MAX_BLOCK_SIGOPS)
Gavin Andresen's avatar
Gavin Andresen committed
2412
                    return state.DoS(100, error("ConnectBlock() : too many sigops"),
2413
                                     REJECT_INVALID, "bad-blk-sigops");
2414
            }
2415

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

2418
            std::vector<CScriptCheck> vChecks;
2419
            if (!CheckInputs(tx, state, view, fScriptChecks, flags, nScriptCheckThreads ? &vChecks : NULL))
2420
                return false;
2421
            control.Add(vChecks);
2422
2423
        }

Pieter Wuille's avatar
Pieter Wuille committed
2424
        CTxUndo txundo;
2425
        UpdateCoins(tx, state, view, txundo, pindex->nHeight, block.GetTxHash(i));
Pieter Wuille's avatar
Pieter Wuille committed
2426
2427
        if (!tx.IsCoinBase())
            blockundo.vtxundo.push_back(txundo);
2428

2429
        vPos.push_back(std::make_pair(block.GetTxHash(i), pos));
2430
        pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
s_nakamoto's avatar
s_nakamoto committed
2431
    }
2432
    int64_t nTime = GetTimeMicros() - nStart;
2433
    if (fBenchmark)
2434
        LogPrintf("- Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin)\n", (unsigned)block.vtx.size(), 0.001 * nTime, 0.001 * nTime / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * nTime / (nInputs-1));
Gavin Andresen's avatar
Gavin Andresen committed
2435

2436
    if (block.vtx[0].GetValueOut() > GetBlockValue(pindex->pprev->nBits, pindex->pprev->nHeight, nFees))
Gavin Andresen's avatar
Gavin Andresen committed
2437
        return state.DoS(100,
2438
                         error("ConnectBlock() : coinbase pays too much (actual=%d vs limit=%d)",
2439
                               block.vtx[0].GetValueOut(), GetBlockValue(pindex->pprev->nBits, pindex->pprev->nHeight, nFees)),
Philip Kaufmann's avatar
Philip Kaufmann committed
2440
                               REJECT_INVALID, "bad-cb-amount");
Pieter Wuille's avatar
Pieter Wuille committed
2441

2442
    if (!control.Wait())
Pieter Wuille's avatar
Pieter Wuille committed
2443
        return state.DoS(100, false);
2444
    int64_t nTime2 = GetTimeMicros() - nStart;
2445
    if (fBenchmark)
2446
        LogPrintf("- Verify %u txins: %.2fms (%.3fms/txin)\n", nInputs - 1, 0.001 * nTime2, nInputs <= 1 ? 0 : 0.001 * nTime2 / (nInputs-1));
2447

2448
2449
2450
    if (fJustCheck)
        return true;

Pieter Wuille's avatar
Pieter Wuille committed
2451
    // Write undo information to disk
2452
    if (pindex->GetUndoPos().IsNull() || (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS)
Pieter Wuille's avatar
Pieter Wuille committed
2453
    {
2454
2455
        if (pindex->GetUndoPos().IsNull()) {
            CDiskBlockPos pos;
Pieter Wuille's avatar
Pieter Wuille committed
2456
            if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
2457
                return error("ConnectBlock() : FindUndoPos failed");
Pieter Wuille's avatar
Pieter Wuille committed
2458
            if (!blockundo.WriteToDisk(pos, pindex->pprev->GetBlockHash()))
Pieter Wuille's avatar
Pieter Wuille committed
2459
                return state.Abort(_("Failed to write undo data"));
2460
2461
2462
2463
2464
2465
2466
2467

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

        pindex->nStatus = (pindex->nStatus & ~BLOCK_VALID_MASK) | BLOCK_VALID_SCRIPTS;

Pieter Wuille's avatar
Pieter Wuille committed
2468
        CDiskBlockIndex blockindex(pindex);
2469
        if (!pblocktree->WriteBlockIndex(blockindex))
Pieter Wuille's avatar
Pieter Wuille committed
2470
            return state.Abort(_("Failed to write block index"));
s_nakamoto's avatar
s_nakamoto committed
2471
2472
    }

2473
    if (fTxIndex)
Pieter Wuille's avatar
Pieter Wuille committed
2474
        if (!pblocktree->WriteTxIndex(vPos))
Pieter Wuille's avatar
Pieter Wuille committed
2475
            return state.Abort(_("Failed to write transaction index"));
2476

2477
    // add this block to the view's block chain
2478
2479
2480
    bool ret;
    ret = view.SetBestBlock(pindex->GetBlockHash());
    assert(ret);
Pieter Wuille's avatar
Pieter Wuille committed
2481

s_nakamoto's avatar
s_nakamoto committed
2482
    // Watch for transactions paying to me
2483
    for (unsigned int i = 0; i < block.vtx.size(); i++)
2484
        g_signals.SyncTransaction(block.GetTxHash(i), block.vtx[i], &block);
s_nakamoto's avatar
s_nakamoto committed
2485
2486
2487
2488

    return true;
}

2489
// Update the on-disk chain state.
2490
bool static WriteChainState(CValidationState &state) {
2491
2492
    static int64_t nLastWrite = 0;
    if (!IsInitialBlockDownload() || pcoinsTip->GetCacheSize() > nCoinCacheSize || GetTimeMicros() > nLastWrite + 600*1000000) {
2493
2494
2495
2496
2497
2498
        // 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()))
2499
            return state.Error("out of disk space");
Pieter Wuille's avatar
Pieter Wuille committed
2500
        FlushBlockFile();
2501
        pblocktree->Sync();
Pieter Wuille's avatar
Pieter Wuille committed
2502
        if (!pcoinsTip->Flush())
Pieter Wuille's avatar
Pieter Wuille committed
2503
            return state.Abort(_("Failed to write to coin database"));
2504
        nLastWrite = GetTimeMicros();
Pieter Wuille's avatar
Pieter Wuille committed
2505
    }
2506
2507
    return true;
}
Pieter Wuille's avatar
Pieter Wuille committed
2508

2509
// Update chainActive and related internal data structures.
2510
void static UpdateTip(CBlockIndex *pindexNew) {
2511
    chainActive.SetTip(pindexNew);
s_nakamoto's avatar
s_nakamoto committed
2512

2513
    // Update best block in wallet (so we can detect restored wallets)
2514
2515
2516
    bool fIsInitialDownload = IsInitialBlockDownload();
    if ((chainActive.Height() % 20160) == 0 || (!fIsInitialDownload && (chainActive.Height() % 144) == 0))
        g_signals.SetBestChain(chainActive.GetLocator());
2517

s_nakamoto's avatar
s_nakamoto committed
2518
2519
    // New best block
    nTimeBestReceived = GetTime();
2520
    mempool.AddTransactionsUpdated(1);
2521
2522
    LogPrintf("UpdateTip: new best=%s  height=%d  log2_work=%.8g  tx=%lu  date=%s progress=%f\n",
      chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.Tip()->nChainTx,
2523
      DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
2524
      Checkpoints::GuessVerificationProgress(chainActive.Tip()));
s_nakamoto's avatar
s_nakamoto committed
2525

2526
2527
2528
2529
    // Check the version of the last 100 blocks to see if we need to upgrade:
    if (!fIsInitialDownload)
    {
        int nUpgraded = 0;
2530
        const CBlockIndex* pindex = chainActive.Tip();
2531
2532
2533
2534
2535
2536
2537
        for (int i = 0; i < 100 && pindex != NULL; i++)
        {
            if (pindex->nVersion > CBlock::CURRENT_VERSION)
                ++nUpgraded;
            pindex = pindex->pprev;
        }
        if (nUpgraded > 0)
2538
            LogPrintf("SetBestChain: %d of last 100 blocks above version %d\n", nUpgraded, (int)CBlock::CURRENT_VERSION);
2539
2540
        if (nUpgraded > 100/2)
            // strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user:
2541
            strMiscWarning = _("Warning: This version is obsolete, upgrade required!");
2542
    }
2543
}
2544

2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
// Disconnect chainActive's tip.
bool static DisconnectTip(CValidationState &state) {
    CBlockIndex *pindexDelete = chainActive.Tip();
    assert(pindexDelete);
    mempool.check(pcoinsTip);
    // Read block from disk.
    CBlock block;
    if (!ReadBlockFromDisk(block, pindexDelete))
        return state.Abort(_("Failed to read block"));
    // Apply the block atomically to the chain state.
    int64_t nStart = GetTimeMicros();
2556
    {
2557
2558
2559
2560
        CCoinsViewCache view(*pcoinsTip, true);
        if (!DisconnectBlock(block, state, pindexDelete, view))
            return error("DisconnectTip() : DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
        assert(view.Flush());
2561
    }
2562
2563
2564
2565
2566
    if (fBenchmark)
        LogPrintf("- Disconnect: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
    // Write the chain state to disk, if necessary.
    if (!WriteChainState(state))
        return false;
Gavin Andresen's avatar
Gavin Andresen committed
2567
    // Resurrect mempool transactions from the disconnected block.
2568
2569
    BOOST_FOREACH(const CTransaction &tx, block.vtx) {
        // ignore validation errors in resurrected transactions
Gavin Andresen's avatar
Gavin Andresen committed
2570
        list<CTransaction> removed;
vertoe's avatar
vertoe committed
2571
        CValidationState stateDummy;
2572
2573
        if (!tx.IsCoinBase())
            if (!AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
Gavin Andresen's avatar
Gavin Andresen committed
2574
                mempool.remove(tx, removed, true);
2575
2576
2577
2578
    }
    mempool.check(pcoinsTip);
    // Update chainActive and related variables.
    UpdateTip(pindexDelete->pprev);
Gavin Andresen's avatar
Gavin Andresen committed
2579
2580
2581
2582
2583
    // Let wallets know transactions went from 1-confirmed to
    // 0-confirmed or conflicted:
    BOOST_FOREACH(const CTransaction &tx, block.vtx) {
        SyncWithWallets(tx.GetHash(), tx, NULL);
    }
2584
    return true;
2585
}
2586

2587
2588
2589
// Connect a new block to chainActive.
bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew) {
    assert(pindexNew->pprev == chainActive.Tip());
2590
    mempool.check(pcoinsTip);
2591
2592
2593
2594
2595
2596
    // Read block from disk.
    CBlock block;
    if (!ReadBlockFromDisk(block, pindexNew))
        return state.Abort(_("Failed to read block"));
    // Apply the block atomically to the chain state.
    int64_t nStart = GetTimeMicros();
s_nakamoto's avatar
s_nakamoto committed
2597
    {
2598
2599
2600
2601
2602
2603
        CCoinsViewCache view(*pcoinsTip, true);
        CInv inv(MSG_BLOCK, pindexNew->GetBlockHash());
        if (!ConnectBlock(block, state, pindexNew, view)) {
            if (state.IsInvalid())
                InvalidBlockFound(pindexNew, state);
            return error("ConnectTip() : ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
2604
        }
2605
2606
        mapBlockSource.erase(inv.hash);
        assert(view.Flush());
s_nakamoto's avatar
s_nakamoto committed
2607
    }
2608
2609
2610
2611
2612
2613
    if (fBenchmark)
        LogPrintf("- Connect: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
    // Write the chain state to disk, if necessary.
    if (!WriteChainState(state))
        return false;
    // Remove conflicting transactions from the mempool.
Gavin Andresen's avatar
Gavin Andresen committed
2614
    list<CTransaction> txConflicted;
2615
    BOOST_FOREACH(const CTransaction &tx, block.vtx) {
Gavin Andresen's avatar
Gavin Andresen committed
2616
2617
2618
        list<CTransaction> unused;
        mempool.remove(tx, unused);
        mempool.removeConflicts(tx, txConflicted);
2619
2620
2621
2622
    }
    mempool.check(pcoinsTip);
    // Update chainActive & related variables.
    UpdateTip(pindexNew);
Gavin Andresen's avatar
Gavin Andresen committed
2623
2624
2625
2626
2627
2628
2629
2630
2631
    // Tell wallet about transactions that went from mempool
    // to conflicted:
    BOOST_FOREACH(const CTransaction &tx, txConflicted) {
        SyncWithWallets(tx.GetHash(), tx, NULL);
    }
    // ... and about transactions that got confirmed:
    BOOST_FOREACH(const CTransaction &tx, block.vtx) {
        SyncWithWallets(tx.GetHash(), tx, &block);
    }
s_nakamoto's avatar
s_nakamoto committed
2632
2633
2634
    return true;
}

2635
2636
2637
2638
// Make chainMostWork correspond to the chain with the most work in it, that isn't
// known to be invalid (it's however far from certain to be valid).
void static FindMostWorkChain() {
    CBlockIndex *pindexNew = NULL;
s_nakamoto's avatar
s_nakamoto committed
2639

2640
2641
2642
2643
    // In case the current best is invalid, do not consider it.
    while (chainMostWork.Tip() && (chainMostWork.Tip()->nStatus & BLOCK_FAILED_MASK)) {
        setBlockIndexValid.erase(chainMostWork.Tip());
        chainMostWork.SetTip(chainMostWork.Tip()->pprev);
Pieter Wuille's avatar
Pieter Wuille committed
2644
    }
2645

2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
    do {
        // Find the best candidate header.
        {
            std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexValid.rbegin();
            if (it == setBlockIndexValid.rend())
                return;
            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)) {
            if (pindexTest->nStatus & BLOCK_FAILED_MASK) {
                // Candidate has an invalid ancestor, remove entire chain from the set.
                if (pindexBestInvalid == NULL || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
                    pindexBestInvalid = pindexNew;                CBlockIndex *pindexFailed = pindexNew;
                while (pindexTest != pindexFailed) {
                    pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
                    setBlockIndexValid.erase(pindexFailed);
                    pindexFailed = pindexFailed->pprev;
                }
                fInvalidAncestor = true;
                break;
Pieter Wuille's avatar
Pieter Wuille committed
2671
            }
2672
            pindexTest = pindexTest->pprev;
s_nakamoto's avatar
s_nakamoto committed
2673
        }
2674
2675
        if (fInvalidAncestor)
            continue;
s_nakamoto's avatar
s_nakamoto committed
2676

2677
2678
        break;
    } while(true);
s_nakamoto's avatar
s_nakamoto committed
2679

2680
2681
2682
    // Check whether it's actually an improvement.
    if (chainMostWork.Tip() && !CBlockIndexWorkComparator()(chainMostWork.Tip(), pindexNew))
        return;
Pieter Wuille's avatar
Pieter Wuille committed
2683

2684
2685
2686
    // We have a new best.
    chainMostWork.SetTip(pindexNew);
}
s_nakamoto's avatar
s_nakamoto committed
2687

2688
2689
// Try to activate to the most-work chain (thereby connecting it).
bool ActivateBestChain(CValidationState &state) {
2690
    LOCK(cs_main);
2691
2692
2693
2694
2695
    CBlockIndex *pindexOldTip = chainActive.Tip();
    bool fComplete = false;
    while (!fComplete) {
        FindMostWorkChain();
        fComplete = true;
s_nakamoto's avatar
s_nakamoto committed
2696

2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
        // Check whether we have something to do.
        if (chainMostWork.Tip() == NULL) break;

        // Disconnect active blocks which are no longer in the best chain.
        while (chainActive.Tip() && !chainMostWork.Contains(chainActive.Tip())) {
            if (!DisconnectTip(state))
                return false;
        }

        // Connect new blocks.
        while (!chainActive.Contains(chainMostWork.Tip())) {
            CBlockIndex *pindexConnect = chainMostWork[chainActive.Height() + 1];
            if (!ConnectTip(state, pindexConnect)) {
                if (state.IsInvalid()) {
                    // The block violates a consensus rule.
                    if (!state.CorruptionPossible())
                        InvalidChainFound(chainMostWork.Tip());
                    fComplete = false;
                    state = CValidationState();
                    break;
                } else {
                    // A system error occurred (disk space, database error, ...).
                    return false;
                }
            }
        }
2723
    }
s_nakamoto's avatar
s_nakamoto committed
2724

2725
2726
2727
2728
2729
2730
2731
2732
    if (chainActive.Tip() != pindexOldTip) {
        std::string strCmd = GetArg("-blocknotify", "");
        if (!IsInitialBlockDownload() && !strCmd.empty())
        {
            boost::replace_all(strCmd, "%s", chainActive.Tip()->GetBlockHash().GetHex());
            boost::thread t(runCommand, strCmd); // thread runs free
        }
    }
Pieter Wuille's avatar
Pieter Wuille committed
2733

s_nakamoto's avatar
s_nakamoto committed
2734
2735
2736
    return true;
}

2737
bool AddToBlockIndex(CBlock& block, CValidationState& state, const CDiskBlockPos& pos)
s_nakamoto's avatar
s_nakamoto committed
2738
2739
{
    // Check for duplicate
2740
    uint256 hash = block.GetHash();
s_nakamoto's avatar
s_nakamoto committed
2741
    if (mapBlockIndex.count(hash))
2742
        return state.Invalid(error("AddToBlockIndex() : %s already exists", hash.ToString()), 0, "duplicate");
s_nakamoto's avatar
s_nakamoto committed
2743
2744

    // Construct new block index object
2745
    CBlockIndex* pindexNew = new CBlockIndex(block);
2746
    assert(pindexNew);
2747
2748
2749
2750
    {
         LOCK(cs_nBlockSequenceId);
         pindexNew->nSequenceId = nBlockSequenceId++;
    }
s_nakamoto's avatar
s_nakamoto committed
2751
2752
    map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
    pindexNew->phashBlock = &((*mi).first);
2753
    map<uint256, CBlockIndex*>::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock);
s_nakamoto's avatar
s_nakamoto committed
2754
2755
2756
2757
2758
    if (miPrev != mapBlockIndex.end())
    {
        pindexNew->pprev = (*miPrev).second;
        pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
    }
2759
    pindexNew->nTx = block.vtx.size();
Pieter Wuille's avatar
Pieter Wuille committed
2760
    pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + pindexNew->GetBlockWork().getuint256();
2761
2762
2763
    pindexNew->nChainTx = (pindexNew->pprev ? pindexNew->pprev->nChainTx : 0) + pindexNew->nTx;
    pindexNew->nFile = pos.nFile;
    pindexNew->nDataPos = pos.nPos;
Pieter Wuille's avatar
Pieter Wuille committed
2764
    pindexNew->nUndoPos = 0;
2765
2766
    pindexNew->nStatus = BLOCK_VALID_TRANSACTIONS | BLOCK_HAVE_DATA;
    setBlockIndexValid.insert(pindexNew);
s_nakamoto's avatar
s_nakamoto committed
2767

Pieter Wuille's avatar
Pieter Wuille committed
2768
    if (!pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexNew)))
Pieter Wuille's avatar
Pieter Wuille committed
2769
        return state.Abort(_("Failed to write block index"));
s_nakamoto's avatar
s_nakamoto committed
2770

2771
    // New best?
2772
    if (!ActivateBestChain(state))
2773
        return false;
s_nakamoto's avatar
s_nakamoto committed
2774

2775
    LOCK(cs_main);
2776
    if (pindexNew == chainActive.Tip())
s_nakamoto's avatar
s_nakamoto committed
2777
    {
2778
2779
        // Clear fork warning if its no longer applicable
        CheckForkWarningConditions();
s_nakamoto's avatar
s_nakamoto committed
2780
2781
        // Notify UI to display prev block's coinbase if it was ours
        static uint256 hashPrevBestCoinBase;
2782
        g_signals.UpdatedTransaction(hashPrevBestCoinBase);
2783
        hashPrevBestCoinBase = block.GetTxHash(0);
2784
2785
    } else
        CheckForkWarningConditionsOnNewFork(pindexNew);
s_nakamoto's avatar
s_nakamoto committed
2786

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

2790
    uiInterface.NotifyBlocksChanged();
s_nakamoto's avatar
s_nakamoto committed
2791
2792
2793
2794
    return true;
}


2795
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
2796
2797
2798
2799
2800
{
    bool fUpdatedLast = false;

    LOCK(cs_LastBlockFile);

2801
2802
2803
2804
2805
    if (fKnown) {
        if (nLastBlockFile != pos.nFile) {
            nLastBlockFile = pos.nFile;
            infoLastBlockFile.SetNull();
            pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile);
2806
            fUpdatedLast = true;
2807
2808
2809
        }
    } else {
        while (infoLastBlockFile.nSize + nAddSize >= MAX_BLOCKFILE_SIZE) {
2810
            LogPrintf("Leaving block file %i: %s\n", nLastBlockFile, infoLastBlockFile.ToString());
2811
            FlushBlockFile(true);
2812
2813
2814
2815
2816
2817
2818
            nLastBlockFile++;
            infoLastBlockFile.SetNull();
            pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile); // check whether data for the new file somehow already exist; can fail just fine
            fUpdatedLast = true;
        }
        pos.nFile = nLastBlockFile;
        pos.nPos = infoLastBlockFile.nSize;
Pieter Wuille's avatar
Pieter Wuille committed
2819
2820
2821
2822
2823
    }

    infoLastBlockFile.nSize += nAddSize;
    infoLastBlockFile.AddBlock(nHeight, nTime);

2824
2825
2826
2827
    if (!fKnown) {
        unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
        unsigned int nNewChunks = (infoLastBlockFile.nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
        if (nNewChunks > nOldChunks) {
2828
2829
2830
            if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) {
                FILE *file = OpenBlockFile(pos);
                if (file) {
2831
                    LogPrintf("Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile);
2832
2833
2834
                    AllocateFileRange(file, pos.nPos, nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos);
                    fclose(file);
                }
2835
            }
2836
            else
2837
                return state.Error("out of disk space");
2838
2839
2840
        }
    }

2841
    if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile))
Pieter Wuille's avatar
Pieter Wuille committed
2842
        return state.Abort(_("Failed to write file info"));
Pieter Wuille's avatar
Pieter Wuille committed
2843
    if (fUpdatedLast)
2844
        pblocktree->WriteLastBlockFile(nLastBlockFile);
Pieter Wuille's avatar
Pieter Wuille committed
2845
2846
2847
2848

    return true;
}

Pieter Wuille's avatar
Pieter Wuille committed
2849
bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize)
Pieter Wuille's avatar
Pieter Wuille committed
2850
2851
2852
2853
2854
{
    pos.nFile = nFile;

    LOCK(cs_LastBlockFile);

2855
    unsigned int nNewSize;
Pieter Wuille's avatar
Pieter Wuille committed
2856
2857
    if (nFile == nLastBlockFile) {
        pos.nPos = infoLastBlockFile.nUndoSize;
2858
        nNewSize = (infoLastBlockFile.nUndoSize += nAddSize);
2859
        if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile))
Pieter Wuille's avatar
Pieter Wuille committed
2860
            return state.Abort(_("Failed to write block info"));
2861
2862
    } else {
        CBlockFileInfo info;
2863
        if (!pblocktree->ReadBlockFileInfo(nFile, info))
Pieter Wuille's avatar
Pieter Wuille committed
2864
            return state.Abort(_("Failed to read block info"));
2865
2866
        pos.nPos = info.nUndoSize;
        nNewSize = (info.nUndoSize += nAddSize);
2867
        if (!pblocktree->WriteBlockFileInfo(nFile, info))
Pieter Wuille's avatar
Pieter Wuille committed
2868
            return state.Abort(_("Failed to write block info"));
2869
2870
2871
2872
2873
    }

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

    return true;
}

s_nakamoto's avatar
s_nakamoto committed
2889

2890
bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot)
s_nakamoto's avatar
s_nakamoto committed
2891
2892
2893
2894
2895
{
    // These are checks that are independent of context
    // that can be verified before saving an orphan block.

    // Size limits
2896
    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
2897
        return state.DoS(100, error("CheckBlock() : size limits failed"),
2898
                         REJECT_INVALID, "bad-blk-length");
s_nakamoto's avatar
s_nakamoto committed
2899

2900
    // Check proof of work matches claimed amount
2901
    if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits))
Gavin Andresen's avatar
Gavin Andresen committed
2902
        return state.DoS(50, error("CheckBlock() : proof of work failed"),
2903
                         REJECT_INVALID, "high-hash");
2904

s_nakamoto's avatar
s_nakamoto committed
2905
    // Check timestamp
2906
    if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
Gavin Andresen's avatar
Gavin Andresen committed
2907
        return state.Invalid(error("CheckBlock() : block timestamp too far in the future"),
2908
                             REJECT_INVALID, "time-too-new");
s_nakamoto's avatar
s_nakamoto committed
2909
2910

    // First transaction must be coinbase, the rest must not be
2911
    if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
Gavin Andresen's avatar
Gavin Andresen committed
2912
        return state.DoS(100, error("CheckBlock() : first tx is not coinbase"),
2913
                         REJECT_INVALID, "bad-cb-missing");
2914
2915
    for (unsigned int i = 1; i < block.vtx.size(); i++)
        if (block.vtx[i].IsCoinBase())
Gavin Andresen's avatar
Gavin Andresen committed
2916
            return state.DoS(100, error("CheckBlock() : more than one coinbase"),
2917
                             REJECT_INVALID, "bad-cb-multiple");
s_nakamoto's avatar
s_nakamoto committed
2918

Evan Duffield's avatar
Evan Duffield committed
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929

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

    std::map<uint256, CTransactionLock>::iterator it = mapTxLocks.begin();

    while(it != mapTxLocks.end()) {
        if(mapTxLockReq.count((*it).second.txHash)){
            CTransaction& tx = mapTxLockReq[(*it).second.txHash];
            for (unsigned int a = 0; a < tx.vin.size(); a++) {
                for (unsigned int b = 0; b < block.vtx.size(); b++) {
                    //we found the locked tx in the block
2930
                    if(tx.GetHash() == block.vtx[b].GetHash()) continue;
Evan Duffield's avatar
Evan Duffield committed
2931

2932
                    //if there's a lock, look for conflicting inputs
Evan Duffield's avatar
Evan Duffield committed
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
                    for (unsigned int c = 0; c < block.vtx[b].vin.size(); c++) {
                        if(tx.vin[a].prevout == block.vtx[b].vin[c].prevout) {
                            return state.DoS(100, error("CheckBlock() : found conflicting transaction with transaction lock"),
                                             REJECT_INVALID, "conflicting-tx-ix");
                        }
                    }
                }
            }
        }
        it++;
    }
Evan Duffield's avatar
Evan Duffield committed
2944
2945


Evan Duffield's avatar
Evan Duffield committed
2946
2947
    // ----------- masternode payments -----------

2948
2949
    bool MasternodePayments = false;

2950
    if(TestNet()){
2951
2952
2953
2954
2955
2956
2957
2958
2959
        if(block.nTime > START_MASTERNODE_PAYMENTS_TESTNET) MasternodePayments = true;
    } else {
        if(block.nTime > START_MASTERNODE_PAYMENTS) MasternodePayments = true;
    }

    if(MasternodePayments)
    {
        LOCK2(cs_main, mempool.cs);

2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
        CBlockIndex *pindex = chainActive.Tip();
        if(pindex != NULL){
            if(pindex->GetBlockHash() == block.hashPrevBlock){
                int64_t masternodePaymentAmount = GetMasternodePayment(pindex->nHeight+1, block.vtx[0].GetValueOut());
                bool fIsInitialDownload = IsInitialBlockDownload();

                // If we don't already have its previous block, skip masternode payment step
                if (!fIsInitialDownload && pindex != NULL)
                {
                    bool foundPaymentAmount = false;
                    bool foundPayee = false;
2971
                    bool foundPaymentAndPayee = false;
2972

2973
2974
2975
                    CScript payee;
                    if(!masternodePayments.GetBlockPayee(chainActive.Tip()->nHeight+1, payee) || payee == CScript()){
                        foundPayee = true; //doesn't require a specific payee
2976
2977
                        foundPaymentAmount = true;
                        foundPaymentAndPayee = true;
Evan Duffield's avatar
Evan Duffield committed
2978
                        LogPrintf("CheckBlock() : Using non-specific masternode payments %d\n", chainActive.Tip()->nHeight+1);
2979
                    }
2980

2981
2982
2983
2984
2985
                    for (unsigned int i = 0; i < block.vtx[0].vout.size(); i++) {
                        if(block.vtx[0].vout[i].nValue == masternodePaymentAmount )
                            foundPaymentAmount = true;
                        if(block.vtx[0].vout[i].scriptPubKey == payee )
                            foundPayee = true;
2986
2987
                        if(block.vtx[0].vout[i].nValue == masternodePaymentAmount && block.vtx[0].vout[i].scriptPubKey == payee)
                            foundPaymentAndPayee = true;
2988
                    }
2989

2990
                    if(!foundPaymentAndPayee) {
2991
2992
2993
                        CTxDestination address1;
                        ExtractDestination(payee, address1);
                        CBitcoinAddress address2(address1);
2994

2995
                        LogPrintf("CheckBlock() : Couldn't find masternode payment(%d|%d) or payee(%d|%s) nHeight %d. \n", foundPaymentAmount, masternodePaymentAmount, foundPayee, address2.ToString().c_str(), chainActive.Tip()->nHeight+1);
2996
                        if(!RegTest()) return state.DoS(100, error("CheckBlock() : Couldn't find masternode payment or payee"));
Evan Duffield's avatar
Evan Duffield committed
2997
2998
                    } else {
                        LogPrintf("CheckBlock() : Found masternode payment %d\n", chainActive.Tip()->nHeight+1);
2999
                    }
Evan Duffield's avatar
Evan Duffield committed
3000
3001
                } else {
                    LogPrintf("CheckBlock() : Is initial download, skipping masternode payment check %d\n", chainActive.Tip()->nHeight+1);
3002
                }
3003
3004
            } else {
                LogPrintf("CheckBlock() : Skipping masternode payment check - nHeight %d Hash %s\n", chainActive.Tip()->nHeight+1, block.GetHash().ToString().c_str());
3005
            }
Evan Duffield's avatar
Evan Duffield committed
3006
3007
        } else {
            LogPrintf("CheckBlock() : pindex is null, skipping masternode payment check\n");
3008
3009
3010
3011
        }
    }


s_nakamoto's avatar
s_nakamoto committed
3012
    // Check transactions
3013
    BOOST_FOREACH(const CTransaction& tx, block.vtx)
3014
        if (!CheckTransaction(tx, state))
Pieter Wuille's avatar
Pieter Wuille committed
3015
            return error("CheckBlock() : CheckTransaction failed");
s_nakamoto's avatar
s_nakamoto committed
3016

Pieter Wuille's avatar
Pieter Wuille committed
3017
3018
3019
    // Build the merkle tree already. We need it anyway later, and it makes the
    // block cache the transaction hashes, which means they don't need to be
    // recalculated many times during this block's validation.
3020
    block.BuildMerkleTree();
Pieter Wuille's avatar
Pieter Wuille committed
3021

3022
3023
3024
    // Check for duplicate txids. This is caught by ConnectInputs(),
    // but catching it earlier avoids a potential DoS attack:
    set<uint256> uniqueTx;
3025
3026
    for (unsigned int i = 0; i < block.vtx.size(); i++) {
        uniqueTx.insert(block.GetTxHash(i));
3027
    }
3028
    if (uniqueTx.size() != block.vtx.size())
Gavin Andresen's avatar
Gavin Andresen committed
3029
        return state.DoS(100, error("CheckBlock() : duplicate transaction"),
3030
                         REJECT_INVALID, "bad-txns-duplicate", true);
3031

3032
    unsigned int nSigOps = 0;
3033
    BOOST_FOREACH(const CTransaction& tx, block.vtx)
Gavin Andresen's avatar
Gavin Andresen committed
3034
    {
3035
        nSigOps += GetLegacySigOpCount(tx);
Gavin Andresen's avatar
Gavin Andresen committed
3036
3037
    }
    if (nSigOps > MAX_BLOCK_SIGOPS)
Gavin Andresen's avatar
Gavin Andresen committed
3038
        return state.DoS(100, error("CheckBlock() : out-of-bounds SigOpCount"),
3039
                         REJECT_INVALID, "bad-blk-sigops", true);
s_nakamoto's avatar
s_nakamoto committed
3040

3041
    // Check merkle root
3042
    if (fCheckMerkleRoot && block.hashMerkleRoot != block.vMerkleTree.back())
Gavin Andresen's avatar
Gavin Andresen committed
3043
        return state.DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"),
3044
                         REJECT_INVALID, "bad-txnmrklroot", true);
s_nakamoto's avatar
s_nakamoto committed
3045
3046
3047
3048

    return true;
}

3049
bool AcceptBlock(CBlock& block, CValidationState& state, CDiskBlockPos* dbp)
s_nakamoto's avatar
s_nakamoto committed
3050
{
3051
    AssertLockHeld(cs_main);
s_nakamoto's avatar
s_nakamoto committed
3052
    // Check for duplicate
3053
    uint256 hash = block.GetHash();
s_nakamoto's avatar
s_nakamoto committed
3054
    if (mapBlockIndex.count(hash))
3055
        return state.Invalid(error("AcceptBlock() : block already in mapBlockIndex"), 0, "duplicate");
s_nakamoto's avatar
s_nakamoto committed
3056
3057

    // Get prev block index
3058
3059
    CBlockIndex* pindexPrev = NULL;
    int nHeight = 0;
3060
    if (hash != Params().HashGenesisBlock()) {
3061
        map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
3062
        if (mi == mapBlockIndex.end())
3063
            return state.DoS(10, error("AcceptBlock() : prev block not found"), 0, "bad-prevblk");
3064
3065
3066
        pindexPrev = (*mi).second;
        nHeight = pindexPrev->nHeight+1;

3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
        if(TestNet()) {
            if (block.nBits != GetNextWorkRequired(pindexPrev, &block))
                return state.DoS(100, error("AcceptBlock() : incorrect proof of work"),
                                 REJECT_INVALID, "bad-diffbits");
        } else {
            // Check proof of work (Here for the architecture issues with DGW v1 and v2)
            if(nHeight <= 68589){
                unsigned int nBitsNext = GetNextWorkRequired(pindexPrev, &block);
                double n1 = ConvertBitsToDouble(block.nBits);
                double n2 = ConvertBitsToDouble(nBitsNext);

                if (abs(n1-n2) > n1*0.5)
                    return state.DoS(100, error("AcceptBlock() : incorrect proof of work (DGW pre-fork) - %f", abs(n1-n2)),
                                    REJECT_INVALID, "bad-diffbits");
            } else {
                if (block.nBits != GetNextWorkRequired(pindexPrev, &block))
                    return state.DoS(100, error("AcceptBlock() : incorrect proof of work"),
                                    REJECT_INVALID, "bad-diffbits");
            }
        }
3087
3088

        // Check timestamp against prev
3089
        if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
Gavin Andresen's avatar
Gavin Andresen committed
3090
            return state.Invalid(error("AcceptBlock() : block's timestamp is too early"),
3091
                                 REJECT_INVALID, "time-too-old");
3092
3093

        // Check that all transactions are finalized
3094
3095
        BOOST_FOREACH(const CTransaction& tx, block.vtx)
            if (!IsFinalTx(tx, nHeight, block.GetBlockTime()))
Gavin Andresen's avatar
Gavin Andresen committed
3096
                return state.DoS(10, error("AcceptBlock() : contains a non-final transaction"),
3097
                                 REJECT_INVALID, "bad-txns-nonfinal");
3098
3099
3100

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

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

3109
        // Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
3110
        if (block.nVersion < 2)
3111
        {
3112
3113
            if ((!TestNet() && CBlockIndex::IsSuperMajority(2, pindexPrev, 950, 1000)) ||
                (TestNet() && CBlockIndex::IsSuperMajority(2, pindexPrev, 75, 100)))
3114
            {
Gavin Andresen's avatar
Gavin Andresen committed
3115
                return state.Invalid(error("AcceptBlock() : rejected nVersion=1 block"),
3116
                                     REJECT_OBSOLETE, "bad-version");
3117
            }
3118
        }
3119
        // Enforce block.nVersion=2 rule that the coinbase starts with serialized block height
3120
        if (block.nVersion >= 2)
3121
        {
3122
            // if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet):
3123
3124
            if ((!TestNet() && CBlockIndex::IsSuperMajority(2, pindexPrev, 750, 1000)) ||
                (TestNet() && CBlockIndex::IsSuperMajority(2, pindexPrev, 51, 100)))
3125
3126
            {
                CScript expect = CScript() << nHeight;
Pieter Wuille's avatar
Pieter Wuille committed
3127
3128
                if (block.vtx[0].vin[0].scriptSig.size() < expect.size() ||
                    !std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin()))
Gavin Andresen's avatar
Gavin Andresen committed
3129
                    return state.DoS(100, error("AcceptBlock() : block height mismatch in coinbase"),
3130
                                     REJECT_INVALID, "bad-cb-height");
3131
            }
3132
3133
3134
        }
    }

s_nakamoto's avatar
s_nakamoto committed
3135
    // Write block to history file
Pieter Wuille's avatar
Pieter Wuille committed
3136
    try {
3137
        unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
Pieter Wuille's avatar
Pieter Wuille committed
3138
3139
3140
        CDiskBlockPos blockPos;
        if (dbp != NULL)
            blockPos = *dbp;
3141
        if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.nTime, dbp != NULL))
Pieter Wuille's avatar
Pieter Wuille committed
3142
3143
            return error("AcceptBlock() : FindBlockPos failed");
        if (dbp == NULL)
3144
            if (!WriteBlockToDisk(block, blockPos))
Pieter Wuille's avatar
Pieter Wuille committed
3145
                return state.Abort(_("Failed to write block"));
3146
        if (!AddToBlockIndex(block, state, blockPos))
Pieter Wuille's avatar
Pieter Wuille committed
3147
3148
3149
3150
            return error("AcceptBlock() : AddToBlockIndex failed");
    } catch(std::runtime_error &e) {
        return state.Abort(_("System error: ") + e.what());
    }
s_nakamoto's avatar
s_nakamoto committed
3151
3152

    // Relay inventory, but don't relay old inventory during initial block download
3153
    int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate();
3154
    if (chainActive.Tip()->GetBlockHash() == hash)
3155
3156
3157
    {
        LOCK(cs_vNodes);
        BOOST_FOREACH(CNode* pnode, vNodes)
3158
            if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
3159
3160
                pnode->PushInventory(CInv(MSG_BLOCK, hash));
    }
s_nakamoto's avatar
s_nakamoto committed
3161
3162
3163
3164

    return true;
}

3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
bool CBlockIndex::IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired, unsigned int nToCheck)
{
    unsigned int nFound = 0;
    for (unsigned int i = 0; i < nToCheck && nFound < nRequired && pstart != NULL; i++)
    {
        if (pstart->nVersion >= minVersion)
            ++nFound;
        pstart = pstart->pprev;
    }
    return (nFound >= nRequired);
}

3177
int64_t CBlockIndex::GetMedianTime() const
3178
{
3179
    AssertLockHeld(cs_main);
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
    const CBlockIndex* pindex = this;
    for (int i = 0; i < nMedianTimeSpan/2; i++)
    {
        if (!chainActive.Next(pindex))
            return GetBlockTime();
        pindex = chainActive.Next(pindex);
    }
    return pindex->GetMedianTimePast();
}

3190
3191
void PushGetBlocks(CNode* pnode, CBlockIndex* pindexBegin, uint256 hashEnd)
{
3192
    AssertLockHeld(cs_main);
3193
3194
3195
3196
3197
3198
    // Filter out duplicate requests
    if (pindexBegin == pnode->pindexLastGetBlocksBegin && hashEnd == pnode->hashLastGetBlocksEnd)
        return;
    pnode->pindexLastGetBlocksBegin = pindexBegin;
    pnode->hashLastGetBlocksEnd = hashEnd;

3199
    pnode->PushMessage("getblocks", chainActive.GetLocator(pindexBegin), hashEnd);
3200
3201
}

Pieter Wuille's avatar
Pieter Wuille committed
3202
bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp)
s_nakamoto's avatar
s_nakamoto committed
3203
{
3204
    AssertLockHeld(cs_main);
3205

s_nakamoto's avatar
s_nakamoto committed
3206
3207
3208
    // Check for duplicate
    uint256 hash = pblock->GetHash();
    if (mapBlockIndex.count(hash))
3209
        return state.Invalid(error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString()), 0, "duplicate");
s_nakamoto's avatar
s_nakamoto committed
3210
    if (mapOrphanBlocks.count(hash))
3211
        return state.Invalid(error("ProcessBlock() : already have block (orphan) %s", hash.ToString()), 0, "duplicate");
s_nakamoto's avatar
s_nakamoto committed
3212
3213

    // Preliminary checks
3214
    if (!CheckBlock(*pblock, state))
s_nakamoto's avatar
s_nakamoto committed
3215
3216
        return error("ProcessBlock() : CheckBlock FAILED");

3217
    CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex);
3218
    if (pcheckpoint && pblock->hashPrevBlock != (chainActive.Tip() ? chainActive.Tip()->GetBlockHash() : uint256(0)))
3219
3220
    {
        // Extra checks to prevent "fill up memory by spamming with bogus blocks"
3221
        int64_t deltaTime = pblock->GetBlockTime() - pcheckpoint->nTime;
3222
3223
        if (deltaTime < 0)
        {
Gavin Andresen's avatar
Gavin Andresen committed
3224
            return state.DoS(100, error("ProcessBlock() : block with timestamp before last checkpoint"),
3225
                             REJECT_CHECKPOINT, "time-too-old");
3226
3227
3228
3229
3230
3231
3232
        }
        CBigNum bnNewBlock;
        bnNewBlock.SetCompact(pblock->nBits);
        CBigNum bnRequired;
        bnRequired.SetCompact(ComputeMinWork(pcheckpoint->nBits, deltaTime));
        if (bnNewBlock > bnRequired)
        {
Gavin Andresen's avatar
Gavin Andresen committed
3233
            return state.DoS(100, error("ProcessBlock() : block with too little proof-of-work"),
3234
                             REJECT_INVALID, "bad-diffbits");
3235
3236
3237
3238
        }
    }


3239
    // If we don't already have its previous block, shunt it off to holding area until we get it
3240
    if (pblock->hashPrevBlock != 0 && !mapBlockIndex.count(pblock->hashPrevBlock))
s_nakamoto's avatar
s_nakamoto committed
3241
    {
3242
        LogPrintf("ProcessBlock: ORPHAN BLOCK %lu, prev=%s\n", (unsigned long)mapOrphanBlocks.size(), pblock->hashPrevBlock.ToString());
s_nakamoto's avatar
s_nakamoto committed
3243

3244
3245
        // Accept orphans as long as there is a node to request its parents from
        if (pfrom) {
3246
            PruneOrphanBlocks();
3247
3248
3249
3250
3251
3252
3253
3254
            COrphanBlock* pblock2 = new COrphanBlock();
            {
                CDataStream ss(SER_DISK, CLIENT_VERSION);
                ss << *pblock;
                pblock2->vchBlock = std::vector<unsigned char>(ss.begin(), ss.end());
            }
            pblock2->hashBlock = hash;
            pblock2->hashPrev = pblock->hashPrevBlock;
3255
            mapOrphanBlocks.insert(make_pair(hash, pblock2));
3256
            mapOrphanBlocksByPrev.insert(make_pair(pblock2->hashPrev, pblock2));
3257
3258

            // Ask this guy to fill in what we're missing
3259
            PushGetBlocks(pfrom, chainActive.Tip(), GetOrphanRoot(hash));
3260
        }
s_nakamoto's avatar
s_nakamoto committed
3261
3262
3263
3264
        return true;
    }

    // Store to disk
3265
    if (!AcceptBlock(*pblock, state, dbp))
s_nakamoto's avatar
s_nakamoto committed
3266
3267
3268
3269
3270
        return error("ProcessBlock() : AcceptBlock FAILED");

    // Recursively process any orphan blocks that depended on this one
    vector<uint256> vWorkQueue;
    vWorkQueue.push_back(hash);
3271
    for (unsigned int i = 0; i < vWorkQueue.size(); i++)
s_nakamoto's avatar
s_nakamoto committed
3272
3273
    {
        uint256 hashPrev = vWorkQueue[i];
3274
        for (multimap<uint256, COrphanBlock*>::iterator mi = mapOrphanBlocksByPrev.lower_bound(hashPrev);
s_nakamoto's avatar
s_nakamoto committed
3275
3276
3277
             mi != mapOrphanBlocksByPrev.upper_bound(hashPrev);
             ++mi)
        {
3278
3279
3280
3281
3282
3283
            CBlock block;
            {
                CDataStream ss(mi->second->vchBlock, SER_DISK, CLIENT_VERSION);
                ss >> block;
            }
            block.BuildMerkleTree();
3284
3285
            // Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan resolution (that is, feeding people an invalid block based on LegitBlockX in order to get anyone relaying LegitBlockX banned)
            CValidationState stateDummy;
3286
3287
3288
3289
            if (AcceptBlock(block, stateDummy))
                vWorkQueue.push_back(mi->second->hashBlock);
            mapOrphanBlocks.erase(mi->second->hashBlock);
            delete mi->second;
s_nakamoto's avatar
s_nakamoto committed
3290
3291
3292
3293
        }
        mapOrphanBlocksByPrev.erase(hashPrev);
    }

3294
    if(!fLiteMode){
3295
        if (!fImporting && !fReindex && chainActive.Height() > Checkpoints::GetTotalBlocksEstimate()){
3296
            darkSendPool.NewBlock();
Evan Duffield's avatar
Evan Duffield committed
3297
            masternodePayments.ProcessBlock(GetHeight()+10);
3298
        }
3299
    }
3300

3301
    LogPrintf("ProcessBlock: ACCEPTED\n");
s_nakamoto's avatar
s_nakamoto committed
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
    return true;
}








3312
3313
3314
3315
CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter& filter)
{
    header = block.GetBlockHeader();

3316
3317
3318
3319
3320
3321
3322
    vector<bool> vMatch;
    vector<uint256> vHashes;

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

    for (unsigned int i = 0; i < block.vtx.size(); i++)
3323
3324
3325
3326
    {
        uint256 hash = block.vtx[i].GetHash();
        if (filter.IsRelevantAndUpdate(block.vtx[i], hash))
        {
3327
3328
            vMatch.push_back(true);
            vMatchedTxn.push_back(make_pair(i, hash));
3329
        }
3330
3331
3332
        else
            vMatch.push_back(false);
        vHashes.push_back(hash);
3333
    }
3334
3335

    txn = CPartialMerkleTree(vHashes, vMatch);
3336
3337
3338
3339
3340
3341
3342
3343
3344
}








Pieter Wuille's avatar
Pieter Wuille committed
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::vector<uint256> &vTxid) {
    if (height == 0) {
        // hash at height 0 is the txids themself
        return vTxid[pos];
    } else {
        // calculate left hash
        uint256 left = CalcHash(height-1, pos*2, vTxid), right;
        // calculate right hash if not beyong the end of the array - copy left hash otherwise1
        if (pos*2+1 < CalcTreeWidth(height-1))
            right = CalcHash(height-1, pos*2+1, vTxid);
        else
            right = left;
        // combine subhashes
        return Hash(BEGIN(left), END(left), BEGIN(right), END(right));
    }
}

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

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

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

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

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

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

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







3465
3466
bool AbortNode(const std::string &strMessage) {
    strMiscWarning = strMessage;
3467
    LogPrintf("*** %s\n", strMessage);
3468
    uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_ERROR);
3469
3470
3471
    StartShutdown();
    return false;
}
Pieter Wuille's avatar
Pieter Wuille committed
3472

3473
bool CheckDiskSpace(uint64_t nAdditionalBytes)
s_nakamoto's avatar
s_nakamoto committed
3474
{
3475
    uint64_t nFreeBytesAvailable = filesystem::space(GetDataDir()).available;
s_nakamoto's avatar
s_nakamoto committed
3476

3477
3478
    // Check for nMinDiskSpace bytes (currently 50MB)
    if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
3479
3480
        return AbortNode(_("Error: Disk space is low!"));

s_nakamoto's avatar
s_nakamoto committed
3481
3482
3483
    return true;
}

Pieter Wuille's avatar
Pieter Wuille committed
3484
FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly)
3485
{
Pieter Wuille's avatar
Pieter Wuille committed
3486
    if (pos.IsNull())
s_nakamoto's avatar
s_nakamoto committed
3487
        return NULL;
Pieter Wuille's avatar
Pieter Wuille committed
3488
3489
3490
3491
3492
    boost::filesystem::path path = GetDataDir() / "blocks" / strprintf("%s%05u.dat", prefix, pos.nFile);
    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
3493
    if (!file) {
3494
        LogPrintf("Unable to open file %s\n", path.string());
s_nakamoto's avatar
s_nakamoto committed
3495
        return NULL;
Pieter Wuille's avatar
Pieter Wuille committed
3496
    }
Pieter Wuille's avatar
Pieter Wuille committed
3497
3498
    if (pos.nPos) {
        if (fseek(file, pos.nPos, SEEK_SET)) {
3499
            LogPrintf("Unable to seek to position %u of %s\n", pos.nPos, path.string());
Pieter Wuille's avatar
Pieter Wuille committed
3500
3501
3502
3503
            fclose(file);
            return NULL;
        }
    }
s_nakamoto's avatar
s_nakamoto committed
3504
3505
3506
    return file;
}

Pieter Wuille's avatar
Pieter Wuille committed
3507
3508
3509
3510
FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly) {
    return OpenDiskFile(pos, "blk", fReadOnly);
}

3511
FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly) {
Pieter Wuille's avatar
Pieter Wuille committed
3512
3513
3514
    return OpenDiskFile(pos, "rev", fReadOnly);
}

3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
CBlockIndex * InsertBlockIndex(uint256 hash)
{
    if (hash == 0)
        return NULL;

    // Return existing
    map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
    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
3540
    boost::this_thread::interruption_point();
3541

Pieter Wuille's avatar
Pieter Wuille committed
3542
    // Calculate nChainWork
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
    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;
Pieter Wuille's avatar
Pieter Wuille committed
3554
        pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + pindex->GetBlockWork().getuint256();
3555
3556
3557
        pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
        if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS && !(pindex->nStatus & BLOCK_FAILED_MASK))
            setBlockIndexValid.insert(pindex);
3558
3559
        if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->nChainWork > pindexBestInvalid->nChainWork))
            pindexBestInvalid = pindex;
3560
3561
3562
3563
    }

    // Load block file info
    pblocktree->ReadLastBlockFile(nLastBlockFile);
3564
    LogPrintf("LoadBlockIndexDB(): last block file = %i\n", nLastBlockFile);
3565
    if (pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile))
3566
        LogPrintf("LoadBlockIndexDB(): last block file info: %s\n", infoLastBlockFile.ToString());
3567

3568
3569
3570
3571
3572
    // Check whether we need to continue reindexing
    bool fReindexing = false;
    pblocktree->ReadReindexing(fReindexing);
    fReindex |= fReindexing;

3573
3574
    // Check whether we have a transaction index
    pblocktree->ReadFlag("txindex", fTxIndex);
3575
    LogPrintf("LoadBlockIndexDB(): transaction index %s\n", fTxIndex ? "enabled" : "disabled");
3576

3577
    // Load pointer to end of best chain
3578
3579
    std::map<uint256, CBlockIndex*>::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
    if (it == mapBlockIndex.end())
3580
        return true;
3581
    chainActive.SetTip(it->second);
3582
    LogPrintf("LoadBlockIndexDB(): hashBestChain=%s height=%d date=%s progress=%f\n",
3583
        chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(),
3584
3585
        DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
        Checkpoints::GuessVerificationProgress(chainActive.Tip()));
3586

Pieter Wuille's avatar
Pieter Wuille committed
3587
3588
3589
    return true;
}

3590
3591
bool VerifyDB(int nCheckLevel, int nCheckDepth)
{
3592
    LOCK(cs_main);
3593
    if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL)
Pieter Wuille's avatar
Pieter Wuille committed
3594
3595
        return true;

3596
    // Verify blocks in the best chain
3597
    if (nCheckDepth <= 0)
3598
        nCheckDepth = 1000000000; // suffices until the year 19000
3599
3600
    if (nCheckDepth > chainActive.Height())
        nCheckDepth = chainActive.Height();
Pieter Wuille's avatar
Pieter Wuille committed
3601
    nCheckLevel = std::max(0, std::min(4, nCheckLevel));
3602
    LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
Pieter Wuille's avatar
Pieter Wuille committed
3603
    CCoinsViewCache coins(*pcoinsTip, true);
3604
    CBlockIndex* pindexState = chainActive.Tip();
Pieter Wuille's avatar
Pieter Wuille committed
3605
3606
    CBlockIndex* pindexFailure = NULL;
    int nGoodTransactions = 0;
Pieter Wuille's avatar
Pieter Wuille committed
3607
    CValidationState state;
3608
    for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev)
3609
    {
Gavin Andresen's avatar
Gavin Andresen committed
3610
        boost::this_thread::interruption_point();
3611
        if (pindex->nHeight < chainActive.Height()-nCheckDepth)
3612
3613
            break;
        CBlock block;
Pieter Wuille's avatar
Pieter Wuille committed
3614
        // check level 0: read from disk
3615
        if (!ReadBlockFromDisk(block, pindex))
3616
            return error("VerifyDB() : *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
3617
        // check level 1: verify block validity
3618
        if (nCheckLevel >= 1 && !CheckBlock(block, state))
3619
            return error("VerifyDB() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
Pieter Wuille's avatar
Pieter Wuille committed
3620
3621
3622
3623
3624
3625
        // 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()))
3626
                    return error("VerifyDB() : *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
Pieter Wuille's avatar
Pieter Wuille committed
3627
3628
3629
3630
3631
            }
        }
        // check level 3: check for inconsistencies during memory-only disconnect of tip blocks
        if (nCheckLevel >= 3 && pindex == pindexState && (coins.GetCacheSize() + pcoinsTip->GetCacheSize()) <= 2*nCoinCacheSize + 32000) {
            bool fClean = true;
3632
            if (!DisconnectBlock(block, state, pindex, coins, &fClean))
3633
                return error("VerifyDB() : *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
Pieter Wuille's avatar
Pieter Wuille committed
3634
3635
3636
3637
3638
3639
            pindexState = pindex->pprev;
            if (!fClean) {
                nGoodTransactions = 0;
                pindexFailure = pindex;
            } else
                nGoodTransactions += block.vtx.size();
3640
3641
        }
    }
Pieter Wuille's avatar
Pieter Wuille committed
3642
    if (pindexFailure)
3643
        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
3644
3645
3646
3647

    // check level 4: try reconnecting blocks
    if (nCheckLevel >= 4) {
        CBlockIndex *pindex = pindexState;
3648
        while (pindex != chainActive.Tip()) {
Gavin Andresen's avatar
Gavin Andresen committed
3649
            boost::this_thread::interruption_point();
3650
            pindex = chainActive.Next(pindex);
3651
            CBlock block;
3652
            if (!ReadBlockFromDisk(block, pindex))
3653
                return error("VerifyDB() : *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
3654
            if (!ConnectBlock(block, state, pindex, coins))
3655
                return error("VerifyDB() : *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
Pieter Wuille's avatar
Pieter Wuille committed
3656
        }
3657
3658
    }

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

3661
3662
3663
    return true;
}

3664
3665
3666
3667
void UnloadBlockIndex()
{
    mapBlockIndex.clear();
    setBlockIndexValid.clear();
3668
    chainActive.SetTip(NULL);
3669
    pindexBestInvalid = NULL;
3670
3671
}

3672
bool LoadBlockIndex()
s_nakamoto's avatar
s_nakamoto committed
3673
{
3674
    // Load block index from databases
3675
    if (!fReindex && !LoadBlockIndexDB())
s_nakamoto's avatar
s_nakamoto committed
3676
        return false;
3677
3678
    return true;
}
3679
3680


3681
bool InitBlockIndex() {
3682
    LOCK(cs_main);
3683
    // Check whether we're already initialized
3684
    if (chainActive.Genesis() != NULL)
3685
3686
3687
3688
3689
        return true;

    // Use the provided setting for -txindex in the new database
    fTxIndex = GetBoolArg("-txindex", false);
    pblocktree->WriteFlag("txindex", fTxIndex);
3690
    LogPrintf("Initializing databases...\n");
3691
3692
3693
3694

    // Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
    if (!fReindex) {
        try {
3695
3696
            CBlock &block = const_cast<CBlock&>(Params().GenesisBlock());
            // Start new block file
3697
3698
3699
3700
            unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
            CDiskBlockPos blockPos;
            CValidationState state;
            if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.nTime))
3701
                return error("LoadBlockIndex() : FindBlockPos failed");
3702
            if (!WriteBlockToDisk(block, blockPos))
3703
                return error("LoadBlockIndex() : writing genesis block to disk failed");
3704
            if (!AddToBlockIndex(block, state, blockPos))
3705
3706
3707
3708
                return error("LoadBlockIndex() : genesis block not accepted");
        } catch(std::runtime_error &e) {
            return error("LoadBlockIndex() : failed to initialize block database: %s", e.what());
        }
s_nakamoto's avatar
s_nakamoto committed
3709
3710
3711
3712
3713
3714
3715
3716
3717
    }

    return true;
}



void PrintBlockTree()
{
3718
    AssertLockHeld(cs_main);
3719
    // pre-compute tree structure
s_nakamoto's avatar
s_nakamoto committed
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
    map<CBlockIndex*, vector<CBlockIndex*> > mapNext;
    for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
    {
        CBlockIndex* pindex = (*mi).second;
        mapNext[pindex->pprev].push_back(pindex);
        // test
        //while (rand() % 3 == 0)
        //    mapNext[pindex->pprev].push_back(pindex);
    }

    vector<pair<int, CBlockIndex*> > vStack;
3731
    vStack.push_back(make_pair(0, chainActive.Genesis()));
s_nakamoto's avatar
s_nakamoto committed
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743

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

        // print split or gap
        if (nCol > nPrevCol)
        {
            for (int i = 0; i < nCol-1; i++)
3744
3745
                LogPrintf("| ");
            LogPrintf("|\\\n");
s_nakamoto's avatar
s_nakamoto committed
3746
3747
3748
3749
        }
        else if (nCol < nPrevCol)
        {
            for (int i = 0; i < nCol; i++)
3750
3751
                LogPrintf("| ");
            LogPrintf("|\n");
Pieter Wuille's avatar
Pieter Wuille committed
3752
       }
s_nakamoto's avatar
s_nakamoto committed
3753
3754
3755
3756
        nPrevCol = nCol;

        // print columns
        for (int i = 0; i < nCol; i++)
3757
            LogPrintf("| ");
s_nakamoto's avatar
s_nakamoto committed
3758
3759
3760

        // print item
        CBlock block;
3761
        ReadBlockFromDisk(block, pindex);
3762
        LogPrintf("%d (blk%05u.dat:0x%x)  %s  tx %u\n",
s_nakamoto's avatar
s_nakamoto committed
3763
            pindex->nHeight,
Pieter Wuille's avatar
Pieter Wuille committed
3764
            pindex->GetBlockPos().nFile, pindex->GetBlockPos().nPos,
3765
            DateTimeStrFormat("%Y-%m-%d %H:%M:%S", block.GetBlockTime()),
s_nakamoto's avatar
s_nakamoto committed
3766
3767
            block.vtx.size());

3768
        // put the main time-chain first
s_nakamoto's avatar
s_nakamoto committed
3769
        vector<CBlockIndex*>& vNext = mapNext[pindex];
3770
        for (unsigned int i = 0; i < vNext.size(); i++)
s_nakamoto's avatar
s_nakamoto committed
3771
        {
3772
            if (chainActive.Next(vNext[i]))
s_nakamoto's avatar
s_nakamoto committed
3773
3774
3775
3776
3777
3778
3779
            {
                swap(vNext[0], vNext[i]);
                break;
            }
        }

        // iterate children
3780
        for (unsigned int i = 0; i < vNext.size(); i++)
s_nakamoto's avatar
s_nakamoto committed
3781
3782
3783
3784
            vStack.push_back(make_pair(nCol+i, vNext[i]));
    }
}

3785
bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
3786
{
3787
    int64_t nStart = GetTimeMillis();
3788

3789
    int nLoaded = 0;
Pieter Wuille's avatar
Pieter Wuille committed
3790
    try {
3791
        CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
3792
        uint64_t nStartByte = 0;
3793
3794
3795
3796
3797
3798
3799
3800
        if (dbp) {
            // (try to) skip already indexed part
            CBlockFileInfo info;
            if (pblocktree->ReadBlockFileInfo(dbp->nFile, info)) {
                nStartByte = info.nSize;
                blkdat.Seek(info.nSize);
            }
        }
3801
        uint64_t nRewind = blkdat.GetPos();
3802
3803
3804
        while (blkdat.good() && !blkdat.eof()) {
            boost::this_thread::interruption_point();

3805
3806
3807
            blkdat.SetPos(nRewind);
            nRewind++; // start one byte further next time, in case of failure
            blkdat.SetLimit(); // remove former limit
3808
            unsigned int nSize = 0;
3809
3810
            try {
                // locate a header
3811
                unsigned char buf[MESSAGE_START_SIZE];
3812
                blkdat.FindByte(Params().MessageStart()[0]);
3813
3814
                nRewind = blkdat.GetPos()+1;
                blkdat >> FLATDATA(buf);
3815
                if (memcmp(buf, Params().MessageStart(), MESSAGE_START_SIZE))
3816
3817
                    continue;
                // read size
3818
                blkdat >> nSize;
3819
3820
                if (nSize < 80 || nSize > MAX_BLOCK_SIZE)
                    continue;
3821
3822
3823
3824
3825
            } catch (std::exception &e) {
                // no valid block header found; don't complain
                break;
            }
            try {
3826
                // read block
3827
                uint64_t nBlockPos = blkdat.GetPos();
3828
                blkdat.SetLimit(nBlockPos + nSize);
3829
3830
3831
                CBlock block;
                blkdat >> block;
                nRewind = blkdat.GetPos();
3832
3833
3834

                // process block
                if (nBlockPos >= nStartByte) {
3835
                    LOCK(cs_main);
3836
3837
                    if (dbp)
                        dbp->nPos = nBlockPos;
Pieter Wuille's avatar
Pieter Wuille committed
3838
3839
                    CValidationState state;
                    if (ProcessBlock(state, NULL, &block, dbp))
3840
                        nLoaded++;
Pieter Wuille's avatar
Pieter Wuille committed
3841
3842
                    if (state.IsError())
                        break;
3843
                }
3844
            } catch (std::exception &e) {
3845
                LogPrintf("%s : Deserialize or I/O error - %s", __func__, e.what());
3846
3847
            }
        }
3848
        fclose(fileIn);
Pieter Wuille's avatar
Pieter Wuille committed
3849
3850
    } catch(std::runtime_error &e) {
        AbortNode(_("Error: system error: ") + e.what());
3851
    }
3852
    if (nLoaded > 0)
3853
        LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart);
3854
3855
    return nLoaded > 0;
}
s_nakamoto's avatar
s_nakamoto committed
3856

3857

s_nakamoto's avatar
s_nakamoto committed
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875








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

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

3877
    if (GetBoolArg("-testsafemode", false))
s_nakamoto's avatar
s_nakamoto committed
3878
3879
        strRPC = "test";

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

s_nakamoto's avatar
s_nakamoto committed
3883
3884
3885
3886
3887
3888
3889
    // Misc warnings like out of disk space and clock is wrong
    if (strMiscWarning != "")
    {
        nPriority = 1000;
        strStatusBar = strMiscWarning;
    }

3890
    if (fLargeWorkForkFound)
s_nakamoto's avatar
s_nakamoto committed
3891
3892
    {
        nPriority = 2000;
3893
3894
3895
        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
3896
3897
    {
        nPriority = 2000;
3898
        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
3899
3900
3901
3902
    }

    // Alerts
    {
3903
        LOCK(cs_mapAlerts);
3904
        BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
s_nakamoto's avatar
s_nakamoto committed
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
        {
            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;
3919
    assert(!"GetWarnings() : invalid parameter");
s_nakamoto's avatar
s_nakamoto committed
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
    return "error";
}








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


3936
bool static AlreadyHave(const CInv& inv)
s_nakamoto's avatar
s_nakamoto committed
3937
3938
3939
{
    switch (inv.type)
    {
Jeff Garzik's avatar
Jeff Garzik committed
3940
3941
    case MSG_TX:
        {
Pieter Wuille's avatar
Pieter Wuille committed
3942
            bool txInMap = false;
3943
            txInMap = mempool.exists(inv.hash);
Pieter Wuille's avatar
Pieter Wuille committed
3944
            return txInMap || mapOrphanTransactions.count(inv.hash) ||
3945
                pcoinsTip->HaveCoins(inv.hash);
Jeff Garzik's avatar
Jeff Garzik committed
3946
3947
3948
3949
        }
    case MSG_BLOCK:
        return mapBlockIndex.count(inv.hash) ||
               mapOrphanBlocks.count(inv.hash);
s_nakamoto's avatar
s_nakamoto committed
3950
3951
3952
3953
3954
3955
    }
    // Don't know what it is, just say we already got one
    return true;
}


3956
3957
3958
3959
3960
3961
void static ProcessGetData(CNode* pfrom)
{
    std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();

    vector<CInv> vNotFound;

3962
3963
    LOCK(cs_main);

3964
3965
3966
3967
3968
3969
3970
    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
3971
            boost::this_thread::interruption_point();
3972
3973
3974
3975
            it++;

            if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
            {
3976
                bool send = false;
3977
3978
3979
                map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(inv.hash);
                if (mi != mapBlockIndex.end())
                {
3980
3981
3982
3983
3984
                    // If the requested block is at a height below our last
                    // checkpoint, only serve it if it's in the checkpointed chain
                    int nHeight = mi->second->nHeight;
                    CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex);
                    if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
Philip Kaufmann's avatar
Philip Kaufmann committed
3985
3986
3987
3988
3989
3990
                        if (!chainActive.Contains(mi->second))
                        {
                            LogPrintf("ProcessGetData(): ignoring request for old block that isn't in the main chain\n");
                        } else {
                            send = true;
                        }
3991
                    } else {
Philip Kaufmann's avatar
Philip Kaufmann committed
3992
                        send = true;
3993
3994
3995
3996
3997
                    }
                }
                if (send)
                {
                    // Send block from disk
3998
                    CBlock block;
3999
                    ReadBlockFromDisk(block, (*mi).second);
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
                    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;
4031
                        vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash()));
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
                        pfrom->PushMessage("inv", vInv);
                        pfrom->hashContinue = 0;
                    }
                }
            }
            else if (inv.IsKnownType())
            {
                // Send stream from relay memory
                bool pushed = false;
                {
                    LOCK(cs_mapRelay);
                    map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
                    if (mi != mapRelay.end()) {
                        pfrom->PushMessage(inv.GetCommand(), (*mi).second);
                        pushed = true;
                    }
                }
                if (!pushed && inv.type == MSG_TX) {
4050
4051

                    if(mapDarksendBroadcastTxes.count(inv.hash)){
4052
4053
                        CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
                        ss.reserve(1000);
4054
4055
4056
4057
4058
4059
4060
                        ss <<
                            mapDarksendBroadcastTxes[inv.hash].tx <<
                            mapDarksendBroadcastTxes[inv.hash].vin <<
                            mapDarksendBroadcastTxes[inv.hash].vchSig <<
                            mapDarksendBroadcastTxes[inv.hash].sigTime;

                        pfrom->PushMessage("dstx", ss);
4061
                        pushed = true;
4062
4063
4064
4065
4066
4067
4068
4069
4070
                    } else {
                        CTransaction tx;
                        if (mempool.lookup(inv.hash, tx)) {
                            CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
                            ss.reserve(1000);
                            ss << tx;
                            pfrom->PushMessage("tx", ss);
                            pushed = true;
                        }
4071
4072
4073
4074
4075
4076
4077
4078
                    }
                }
                if (!pushed) {
                    vNotFound.push_back(inv);
                }
            }

            // Track requests for our stuff.
4079
            g_signals.Inventory(inv.hash);
4080

4081
4082
            if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
                break;
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
        }
    }

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

Pieter Wuille's avatar
Pieter Wuille committed
4100
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
s_nakamoto's avatar
s_nakamoto committed
4101
4102
{
    RandAddSeedPerfmon();
4103
    LogPrint("net", "received: %s (%u bytes)\n", strCommand, vRecv.size());
s_nakamoto's avatar
s_nakamoto committed
4104
4105
    if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
    {
4106
        LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
s_nakamoto's avatar
s_nakamoto committed
4107
4108
4109
        return true;
    }

Pieter Wuille's avatar
Pieter Wuille committed
4110
4111
4112
4113
    {
        LOCK(cs_main);
        State(pfrom->GetId())->nLastBlockProcess = GetTimeMicros();
    }
s_nakamoto's avatar
s_nakamoto committed
4114
4115
4116
4117
4118
4119
4120



    if (strCommand == "version")
    {
        // Each connection can only send one version message
        if (pfrom->nVersion != 0)
4121
        {
Gavin Andresen's avatar
Gavin Andresen committed
4122
            pfrom->PushMessage("reject", strCommand, REJECT_DUPLICATE, string("Duplicate version message"));
Pieter Wuille's avatar
Pieter Wuille committed
4123
            Misbehaving(pfrom->GetId(), 1);
s_nakamoto's avatar
s_nakamoto committed
4124
            return false;
4125
        }
s_nakamoto's avatar
s_nakamoto committed
4126

4127
        int64_t nTime;
s_nakamoto's avatar
s_nakamoto committed
4128
4129
        CAddress addrMe;
        CAddress addrFrom;
4130
        uint64_t nNonce = 1;
s_nakamoto's avatar
s_nakamoto committed
4131
        vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
4132
        if (pfrom->nVersion < MIN_PEER_PROTO_VERSION)
Pieter Wuille's avatar
Pieter Wuille committed
4133
        {
4134
            // disconnect from peers older than this proto version
4135
            LogPrintf("partner %s using obsolete version %i; disconnecting\n", pfrom->addr.ToString(), pfrom->nVersion);
Gavin Andresen's avatar
Gavin Andresen committed
4136
4137
            pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE,
                               strprintf("Version must be %d or greater", MIN_PEER_PROTO_VERSION));
Pieter Wuille's avatar
Pieter Wuille committed
4138
4139
4140
4141
            pfrom->fDisconnect = true;
            return false;
        }

s_nakamoto's avatar
s_nakamoto committed
4142
4143
        if (pfrom->nVersion == 10300)
            pfrom->nVersion = 300;
Pieter Wuille's avatar
Pieter Wuille committed
4144
        if (!vRecv.empty())
s_nakamoto's avatar
s_nakamoto committed
4145
            vRecv >> addrFrom >> nNonce;
Mike Hearn's avatar
Mike Hearn committed
4146
        if (!vRecv.empty()) {
4147
            vRecv >> LIMITED_STRING(pfrom->strSubVer, 256);
Mike Hearn's avatar
Mike Hearn committed
4148
4149
            pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
        }
Pieter Wuille's avatar
Pieter Wuille committed
4150
        if (!vRecv.empty())
s_nakamoto's avatar
s_nakamoto committed
4151
            vRecv >> pfrom->nStartingHeight;
4152
4153
4154
4155
        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
4156

4157
4158
4159
4160
4161
4162
        if (pfrom->fInbound && addrMe.IsRoutable())
        {
            pfrom->addrLocal = addrMe;
            SeenLocal(addrMe);
        }

s_nakamoto's avatar
s_nakamoto committed
4163
4164
4165
        // Disconnect if we connected to ourself
        if (nNonce == nLocalHostNonce && nNonce > 1)
        {
4166
            LogPrintf("connected to self at %s, disconnecting\n", pfrom->addr.ToString());
s_nakamoto's avatar
s_nakamoto committed
4167
4168
4169
4170
            pfrom->fDisconnect = true;
            return true;
        }

Gavin Andresen's avatar
Gavin Andresen committed
4171
4172
4173
4174
        // Be shy and don't send version until we hear
        if (pfrom->fInbound)
            pfrom->PushVersion();

s_nakamoto's avatar
s_nakamoto committed
4175
4176
4177
4178
        pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);


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

s_nakamoto's avatar
s_nakamoto committed
4182
4183
4184
        if (!pfrom->fInbound)
        {
            // Advertise our address
Pieter Wuille's avatar
Pieter Wuille committed
4185
            if (!fNoListen && !IsInitialBlockDownload())
s_nakamoto's avatar
s_nakamoto committed
4186
            {
4187
4188
4189
                CAddress addr = GetLocalAddress(&pfrom->addr);
                if (addr.IsRoutable())
                    pfrom->PushAddress(addr);
s_nakamoto's avatar
s_nakamoto committed
4190
4191
4192
            }

            // Get recent addresses
4193
            if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000)
s_nakamoto's avatar
s_nakamoto committed
4194
4195
4196
4197
            {
                pfrom->PushMessage("getaddr");
                pfrom->fGetAddr = true;
            }
4198
4199
4200
4201
4202
4203
4204
            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
4205
4206
        }

s_nakamoto's avatar
s_nakamoto committed
4207
        // Relay alerts
4208
4209
        {
            LOCK(cs_mapAlerts);
4210
            BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
s_nakamoto's avatar
s_nakamoto committed
4211
                item.second.RelayTo(pfrom);
4212
        }
s_nakamoto's avatar
s_nakamoto committed
4213
4214
4215

        pfrom->fSuccessfullyConnected = true;

4216
        LogPrintf("receive version message: %s: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", pfrom->cleanSubVer, pfrom->nVersion, pfrom->nStartingHeight, addrMe.ToString(), addrFrom.ToString(), pfrom->addr.ToString());
4217

4218
        AddTimeData(pfrom->addr, nTime);
s_nakamoto's avatar
s_nakamoto committed
4219
4220
4221
4222
4223
4224
    }


    else if (pfrom->nVersion == 0)
    {
        // Must have a version message before anything else
Pieter Wuille's avatar
Pieter Wuille committed
4225
        Misbehaving(pfrom->GetId(), 1);
s_nakamoto's avatar
s_nakamoto committed
4226
4227
4228
4229
4230
4231
        return false;
    }


    else if (strCommand == "verack")
    {
4232
        pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
s_nakamoto's avatar
s_nakamoto committed
4233
4234
4235
4236
4237
4238
4239
    }


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

        // Don't want addr from older versions unless seeding
4242
        if (pfrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000)
s_nakamoto's avatar
s_nakamoto committed
4243
4244
            return true;
        if (vAddr.size() > 1000)
4245
        {
Pieter Wuille's avatar
Pieter Wuille committed
4246
            Misbehaving(pfrom->GetId(), 20);
4247
            return error("message addr size() = %u", vAddr.size());
4248
        }
s_nakamoto's avatar
s_nakamoto committed
4249
4250

        // Store the new addresses
4251
        vector<CAddress> vAddrOk;
4252
4253
        int64_t nNow = GetAdjustedTime();
        int64_t nSince = nNow - 10 * 60;
4254
        BOOST_FOREACH(CAddress& addr, vAddr)
s_nakamoto's avatar
s_nakamoto committed
4255
        {
Gavin Andresen's avatar
Gavin Andresen committed
4256
4257
            boost::this_thread::interruption_point();

s_nakamoto's avatar
s_nakamoto committed
4258
4259
            if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
                addr.nTime = nNow - 5 * 24 * 60 * 60;
s_nakamoto's avatar
s_nakamoto committed
4260
            pfrom->AddAddressKnown(addr);
4261
            bool fReachable = IsReachable(addr);
s_nakamoto's avatar
s_nakamoto committed
4262
            if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
s_nakamoto's avatar
s_nakamoto committed
4263
4264
4265
            {
                // Relay to a limited number of other nodes
                {
4266
                    LOCK(cs_vNodes);
4267
4268
                    // 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
4269
4270
                    static uint256 hashSalt;
                    if (hashSalt == 0)
4271
                        hashSalt = GetRandHash();
4272
                    uint64_t hashAddr = addr.GetHash();
Pieter Wuille's avatar
Pieter Wuille committed
4273
                    uint256 hashRand = hashSalt ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60));
4274
                    hashRand = Hash(BEGIN(hashRand), END(hashRand));
s_nakamoto's avatar
s_nakamoto committed
4275
                    multimap<uint256, CNode*> mapMix;
4276
                    BOOST_FOREACH(CNode* pnode, vNodes)
4277
                    {
4278
                        if (pnode->nVersion < CADDR_TIME_VERSION)
s_nakamoto's avatar
s_nakamoto committed
4279
                            continue;
4280
4281
4282
4283
4284
4285
                        unsigned int nPointer;
                        memcpy(&nPointer, &pnode, sizeof(nPointer));
                        uint256 hashKey = hashRand ^ nPointer;
                        hashKey = Hash(BEGIN(hashKey), END(hashKey));
                        mapMix.insert(make_pair(hashKey, pnode));
                    }
4286
                    int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s)
s_nakamoto's avatar
s_nakamoto committed
4287
4288
4289
4290
                    for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
                        ((*mi).second)->PushAddress(addr);
                }
            }
4291
4292
4293
            // Do not store addresses outside our network
            if (fReachable)
                vAddrOk.push_back(addr);
s_nakamoto's avatar
s_nakamoto committed
4294
        }
4295
        addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60);
s_nakamoto's avatar
s_nakamoto committed
4296
4297
        if (vAddr.size() < 1000)
            pfrom->fGetAddr = false;
4298
4299
        if (pfrom->fOneShot)
            pfrom->fDisconnect = true;
s_nakamoto's avatar
s_nakamoto committed
4300
4301
4302
4303
4304
4305
4306
    }


    else if (strCommand == "inv")
    {
        vector<CInv> vInv;
        vRecv >> vInv;
4307
        if (vInv.size() > MAX_INV_SZ)
4308
        {
Pieter Wuille's avatar
Pieter Wuille committed
4309
            Misbehaving(pfrom->GetId(), 20);
4310
            return error("message inv size() = %u", vInv.size());
4311
        }
s_nakamoto's avatar
s_nakamoto committed
4312

4313
4314
        LOCK(cs_main);

4315
        for (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
s_nakamoto's avatar
s_nakamoto committed
4316
        {
4317
4318
            const CInv &inv = vInv[nInv];

Gavin Andresen's avatar
Gavin Andresen committed
4319
            boost::this_thread::interruption_point();
s_nakamoto's avatar
s_nakamoto committed
4320
4321
            pfrom->AddInventoryKnown(inv);

4322
            bool fAlreadyHave = AlreadyHave(inv);
4323
            LogPrint("net", "  got inventory: %s  %s\n", inv.ToString(), fAlreadyHave ? "have" : "new");
s_nakamoto's avatar
s_nakamoto committed
4324

4325
            if (!fAlreadyHave) {
4326
4327
4328
4329
4330
4331
                if (!fImporting && !fReindex) {
                    if (inv.type == MSG_BLOCK)
                        AddBlockToQueue(pfrom->GetId(), inv.hash);
                    else
                        pfrom->AskFor(inv);
                }
4332
            } else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) {
4333
                PushGetBlocks(pfrom, chainActive.Tip(), GetOrphanRoot(inv.hash));
4334
            }
s_nakamoto's avatar
s_nakamoto committed
4335
4336

            // Track requests for our stuff
4337
            g_signals.Inventory(inv.hash);
4338
4339
4340
4341
4342

            if (pfrom->nSendSize > (SendBufferSize() * 2)) {
                Misbehaving(pfrom->GetId(), 50);
                return error("send buffer size() = %u", pfrom->nSendSize);
            }
s_nakamoto's avatar
s_nakamoto committed
4343
4344
4345
4346
4347
4348
4349
4350
        }
    }


    else if (strCommand == "getdata")
    {
        vector<CInv> vInv;
        vRecv >> vInv;
4351
        if (vInv.size() > MAX_INV_SZ)
4352
        {
Pieter Wuille's avatar
Pieter Wuille committed
4353
            Misbehaving(pfrom->GetId(), 20);
4354
            return error("message getdata size() = %u", vInv.size());
4355
        }
s_nakamoto's avatar
s_nakamoto committed
4356

4357
        if (fDebug || (vInv.size() != 1))
4358
            LogPrint("net", "received getdata (%u invsz)\n", vInv.size());
4359

4360
        if ((fDebug && vInv.size() > 0) || (vInv.size() == 1))
4361
            LogPrint("net", "received getdata for: %s\n", vInv[0].ToString());
s_nakamoto's avatar
s_nakamoto committed
4362

4363
4364
        pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end());
        ProcessGetData(pfrom);
s_nakamoto's avatar
s_nakamoto committed
4365
4366
4367
4368
4369
4370
4371
4372
4373
    }


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

4374
4375
        LOCK(cs_main);

4376
        // Find the last block the caller has in the main chain
4377
        CBlockIndex* pindex = chainActive.FindFork(locator);
s_nakamoto's avatar
s_nakamoto committed
4378
4379
4380

        // Send the rest of the chain
        if (pindex)
4381
            pindex = chainActive.Next(pindex);
4382
        int nLimit = 500;
4383
        LogPrint("net", "getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString(), nLimit);
4384
        for (; pindex; pindex = chainActive.Next(pindex))
s_nakamoto's avatar
s_nakamoto committed
4385
4386
4387
        {
            if (pindex->GetBlockHash() == hashStop)
            {
4388
                LogPrint("net", "  getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
s_nakamoto's avatar
s_nakamoto committed
4389
4390
4391
                break;
            }
            pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
4392
            if (--nLimit <= 0)
s_nakamoto's avatar
s_nakamoto committed
4393
4394
4395
            {
                // When this block is requested, we'll send an inv that'll make them
                // getblocks the next batch of inventory.
4396
                LogPrint("net", "  getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
s_nakamoto's avatar
s_nakamoto committed
4397
4398
4399
4400
4401
4402
4403
                pfrom->hashContinue = pindex->GetBlockHash();
                break;
            }
        }
    }


4404
4405
4406
4407
4408
4409
    else if (strCommand == "getheaders")
    {
        CBlockLocator locator;
        uint256 hashStop;
        vRecv >> locator >> hashStop;

4410
4411
        LOCK(cs_main);

4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
        CBlockIndex* pindex = NULL;
        if (locator.IsNull())
        {
            // If locator is null, return the hashStop block
            map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashStop);
            if (mi == mapBlockIndex.end())
                return true;
            pindex = (*mi).second;
        }
        else
        {
            // Find the last block the caller has in the main chain
4424
            pindex = chainActive.FindFork(locator);
4425
            if (pindex)
4426
                pindex = chainActive.Next(pindex);
4427
4428
        }

4429
        // we must use CBlocks, as CBlockHeaders won't include the 0x00 nTx count at the end
4430
        vector<CBlock> vHeaders;
4431
        int nLimit = 2000;
4432
        LogPrint("net", "getheaders %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString());
4433
        for (; pindex; pindex = chainActive.Next(pindex))
4434
4435
4436
4437
4438
4439
4440
4441
4442
        {
            vHeaders.push_back(pindex->GetBlockHeader());
            if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
                break;
        }
        pfrom->PushMessage("headers", vHeaders);
    }


4443
    else if (strCommand == "tx"|| strCommand == "dstx")
s_nakamoto's avatar
s_nakamoto committed
4444
4445
    {
        vector<uint256> vWorkQueue;
4446
        vector<uint256> vEraseQueue;
s_nakamoto's avatar
s_nakamoto committed
4447
        CTransaction tx;
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494

        //masternode signed transaction
        bool allowFree = false;
        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;

            BOOST_FOREACH(CMasterNode& mn, vecMasternodes) {
                if(mn.vin == vin) {
                    if(!mn.allowFreeTx){
                        //multiple peers can send us a valid masternode transaction
                        if(fDebug) LogPrintf("dstx: Masternode sending too many transactions %s\n", tx.GetHash().ToString().c_str());
                        return true;
                    }

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

                    std::string errorMessage = "";
                    if(!darkSendSigner.VerifyMessage(mn.pubkey2, vchSig, strMessage, errorMessage)){
                        LogPrintf("dstx: Got bad masternode address signature %s \n", vin.ToString().c_str());
                        //pfrom->Misbehaving(20);
                        return false;
                    }

                    LogPrintf("dstx: Got Masternode transaction %s\n", tx.GetHash().ToString().c_str());

                    allowFree = true;
                    mn.allowFreeTx = false;

                    if(!mapDarksendBroadcastTxes.count(tx.GetHash())){
                        CDarksendBroadcastTx dstx;
                        dstx.tx = tx;
                        dstx.vin = vin;
                        dstx.vchSig = vchSig;
                        dstx.sigTime = sigTime;

                        mapDarksendBroadcastTxes.insert(make_pair(tx.GetHash(), dstx));
                    }
                }
            }
        }
s_nakamoto's avatar
s_nakamoto committed
4495
4496
4497
4498

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

4499
4500
        LOCK(cs_main);

s_nakamoto's avatar
s_nakamoto committed
4501
        bool fMissingInputs = false;
Pieter Wuille's avatar
Pieter Wuille committed
4502
        CValidationState state;
4503
        if (AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs, allowFree))
s_nakamoto's avatar
s_nakamoto committed
4504
        {
4505
            mempool.check(pcoinsTip);
4506
            RelayTransaction(tx, inv.hash);
s_nakamoto's avatar
s_nakamoto committed
4507
4508
            mapAlreadyAskedFor.erase(inv);
            vWorkQueue.push_back(inv.hash);
4509
            vEraseQueue.push_back(inv.hash);
s_nakamoto's avatar
s_nakamoto committed
4510

4511

4512
            LogPrint("mempool", "AcceptToMemoryPool: %s %s : accepted %s (poolsz %u)\n",
4513
4514
                pfrom->addr.ToString(), pfrom->cleanSubVer,
                tx.GetHash().ToString(),
4515
4516
                mempool.mapTx.size());

s_nakamoto's avatar
s_nakamoto committed
4517
            // Recursively process any orphan transactions that depended on this one
4518
            set<NodeId> setMisbehaving;
4519
            for (unsigned int i = 0; i < vWorkQueue.size(); i++)
s_nakamoto's avatar
s_nakamoto committed
4520
            {
4521
4522
4523
4524
4525
                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
4526
4527
                     ++mi)
                {
4528
                    const uint256& orphanHash = *mi;
4529
4530
                    const CTransaction& orphanTx = mapOrphanTransactions[orphanHash].tx;
                    NodeId fromPeer = mapOrphanTransactions[orphanHash].fromPeer;
4531
                    bool fMissingInputs2 = false;
4532
4533
4534
                    // 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)
4535
                    CValidationState stateDummy;
s_nakamoto's avatar
s_nakamoto committed
4536

4537
4538
4539
4540
                    vEraseQueue.push_back(orphanHash);

                    if (setMisbehaving.count(fromPeer))
                        continue;
4541
                    if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2))
s_nakamoto's avatar
s_nakamoto committed
4542
                    {
4543
                        LogPrint("mempool", "   accepted orphan tx %s\n", orphanHash.ToString());
4544
4545
4546
                        RelayTransaction(orphanTx, orphanHash);
                        mapAlreadyAskedFor.erase(CInv(MSG_TX, orphanHash));
                        vWorkQueue.push_back(orphanHash);
4547
4548
4549
                    }
                    else if (!fMissingInputs2)
                    {
4550
4551
4552
4553
4554
4555
4556
4557
4558
                        int nDos = 0;
                        if (stateDummy.IsInvalid(nDos) && nDos > 0)
                        {
                            // Punish peer that gave us an invalid orphan tx
                            Misbehaving(fromPeer, nDos);
                            setMisbehaving.insert(fromPeer);
                            LogPrint("mempool", "   invalid orphan tx %s\n", orphanHash.ToString());
                        }
                        // too-little-fee orphan
4559
                        LogPrint("mempool", "   removed orphan tx %s\n", orphanHash.ToString());
s_nakamoto's avatar
s_nakamoto committed
4560
                    }
4561
                    mempool.check(pcoinsTip);
s_nakamoto's avatar
s_nakamoto committed
4562
4563
4564
                }
            }

4565
            BOOST_FOREACH(uint256 hash, vEraseQueue)
s_nakamoto's avatar
s_nakamoto committed
4566
4567
4568
4569
                EraseOrphanTx(hash);
        }
        else if (fMissingInputs)
        {
4570
            AddOrphanTx(tx, pfrom->GetId());
4571
4572

            // DoS prevention: do not allow mapOrphanTransactions to grow unbounded
4573
4574
            unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
            unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
4575
            if (nEvicted > 0)
4576
                LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted);
s_nakamoto's avatar
s_nakamoto committed
4577
        }
4578
        int nDoS = 0;
4579
        if (state.IsInvalid(nDoS))
Philip Kaufmann's avatar
Philip Kaufmann committed
4580
        {
4581
4582
4583
            LogPrint("mempool", "%s from %s %s was not accepted into the memory pool: %s\n", tx.GetHash().ToString(),
                pfrom->addr.ToString(), pfrom->cleanSubVer,
                state.GetRejectReason());
Gavin Andresen's avatar
Gavin Andresen committed
4584
4585
            pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
                               state.GetRejectReason(), inv.hash);
4586
            if (nDoS > 0)
Pieter Wuille's avatar
Pieter Wuille committed
4587
                Misbehaving(pfrom->GetId(), nDoS);
Gavin Andresen's avatar
Gavin Andresen committed
4588
        }
s_nakamoto's avatar
s_nakamoto committed
4589
4590
4591
    }


4592
    else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing
s_nakamoto's avatar
s_nakamoto committed
4593
    {
4594
4595
        CBlock block;
        vRecv >> block;
s_nakamoto's avatar
s_nakamoto committed
4596

4597
        LogPrint("net", "received block %s\n", block.GetHash().ToString());
4598
        // block.print();
s_nakamoto's avatar
s_nakamoto committed
4599

4600
        CInv inv(MSG_BLOCK, block.GetHash());
s_nakamoto's avatar
s_nakamoto committed
4601
4602
        pfrom->AddInventoryKnown(inv);

4603
        LOCK(cs_main);
4604
4605
        // Remember who we got this block from.
        mapBlockSource[inv.hash] = pfrom->GetId();
4606
        MarkBlockAsReceived(inv.hash, pfrom->GetId());
4607

Pieter Wuille's avatar
Pieter Wuille committed
4608
        CValidationState state;
4609
        ProcessBlock(state, pfrom, &block);
s_nakamoto's avatar
s_nakamoto committed
4610
4611
4612
4613
4614
4615
    }


    else if (strCommand == "getaddr")
    {
        pfrom->vAddrToSend.clear();
4616
4617
4618
        vector<CAddress> vAddr = addrman.GetAddr();
        BOOST_FOREACH(const CAddress &addr, vAddr)
            pfrom->PushAddress(addr);
s_nakamoto's avatar
s_nakamoto committed
4619
4620
4621
    }


4622
4623
    else if (strCommand == "mempool")
    {
4624
        LOCK2(cs_main, pfrom->cs_filter);
4625

4626
4627
4628
        std::vector<uint256> vtxid;
        mempool.queryHashes(vtxid);
        vector<CInv> vInv;
Matt Corallo's avatar
Matt Corallo committed
4629
4630
        BOOST_FOREACH(uint256& hash, vtxid) {
            CInv inv(MSG_TX, hash);
4631
4632
4633
4634
            CTransaction tx;
            bool fInMemPool = mempool.lookup(hash, tx);
            if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
            if ((pfrom->pfilter && pfrom->pfilter->IsRelevantAndUpdate(tx, hash)) ||
Matt Corallo's avatar
Matt Corallo committed
4635
4636
               (!pfrom->pfilter))
                vInv.push_back(inv);
4637
4638
4639
4640
            if (vInv.size() == MAX_INV_SZ) {
                pfrom->PushMessage("inv", vInv);
                vInv.clear();
            }
4641
4642
4643
4644
4645
4646
        }
        if (vInv.size() > 0)
            pfrom->PushMessage("inv", vInv);
    }


s_nakamoto's avatar
s_nakamoto committed
4647
4648
    else if (strCommand == "ping")
    {
Jeff Garzik's avatar
Jeff Garzik committed
4649
4650
        if (pfrom->nVersion > BIP0031_VERSION)
        {
4651
            uint64_t nonce = 0;
Jeff Garzik's avatar
Jeff Garzik committed
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
            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
4666
4667
4668
    }


Josh Lehan's avatar
Josh Lehan committed
4669
4670
    else if (strCommand == "pong")
    {
4671
4672
        int64_t pingUsecEnd = GetTimeMicros();
        uint64_t nonce = 0;
Josh Lehan's avatar
Josh Lehan committed
4673
4674
4675
        size_t nAvail = vRecv.in_avail();
        bool bPingFinished = false;
        std::string sProblem;
4676

Josh Lehan's avatar
Josh Lehan committed
4677
4678
        if (nAvail >= sizeof(nonce)) {
            vRecv >> nonce;
4679

Josh Lehan's avatar
Josh Lehan committed
4680
4681
4682
4683
4684
            // 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;
4685
                    int64_t pingUsecTime = pingUsecEnd - pfrom->nPingUsecStart;
Josh Lehan's avatar
Josh Lehan committed
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
                    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";
        }
4710

Josh Lehan's avatar
Josh Lehan committed
4711
        if (!(sProblem.empty())) {
4712
            LogPrint("net", "pong %s %s: %s, %x expected, %x received, %u bytes\n",
4713
4714
4715
                pfrom->addr.ToString(),
                pfrom->cleanSubVer,
                sProblem,
4716
4717
4718
                pfrom->nPingNonceSent,
                nonce,
                nAvail);
Josh Lehan's avatar
Josh Lehan committed
4719
4720
4721
4722
4723
        }
        if (bPingFinished) {
            pfrom->nPingNonceSent = 0;
        }
    }
4724
4725


s_nakamoto's avatar
s_nakamoto committed
4726
4727
4728
4729
4730
    else if (strCommand == "alert")
    {
        CAlert alert;
        vRecv >> alert;

Gavin Andresen's avatar
Gavin Andresen committed
4731
4732
        uint256 alertHash = alert.GetHash();
        if (pfrom->setKnown.count(alertHash) == 0)
s_nakamoto's avatar
s_nakamoto committed
4733
        {
Gavin Andresen's avatar
Gavin Andresen committed
4734
            if (alert.ProcessAlert())
4735
            {
Gavin Andresen's avatar
Gavin Andresen committed
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
                // 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
4751
                Misbehaving(pfrom->GetId(), 10);
4752
            }
s_nakamoto's avatar
s_nakamoto committed
4753
4754
4755
4756
        }
    }


4757
4758
4759
4760
4761
4762
4763
    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
4764
            Misbehaving(pfrom->GetId(), 100);
4765
4766
4767
4768
4769
        else
        {
            LOCK(pfrom->cs_filter);
            delete pfrom->pfilter;
            pfrom->pfilter = new CBloomFilter(filter);
4770
            pfrom->pfilter->UpdateEmptyFull();
4771
        }
4772
        pfrom->fRelayTxes = true;
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
    }


    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
4783
        if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE)
4784
        {
Pieter Wuille's avatar
Pieter Wuille committed
4785
            Misbehaving(pfrom->GetId(), 100);
4786
4787
4788
4789
4790
        } else {
            LOCK(pfrom->cs_filter);
            if (pfrom->pfilter)
                pfrom->pfilter->insert(vData);
            else
Pieter Wuille's avatar
Pieter Wuille committed
4791
                Misbehaving(pfrom->GetId(), 100);
4792
4793
4794
4795
4796
4797
4798
4799
        }
    }


    else if (strCommand == "filterclear")
    {
        LOCK(pfrom->cs_filter);
        delete pfrom->pfilter;
4800
        pfrom->pfilter = new CBloomFilter();
4801
        pfrom->fRelayTxes = true;
4802
4803
4804
    }


Gavin Andresen's avatar
Gavin Andresen committed
4805
4806
4807
4808
4809
    else if (strCommand == "reject")
    {
        if (fDebug)
        {
            string strMsg; unsigned char ccode; string strReason;
4810
            vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, 111);
Gavin Andresen's avatar
Gavin Andresen committed
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820

            ostringstream ss;
            ss << strMsg << " code " << itostr(ccode) << ": " << strReason;

            if (strMsg == "block" || strMsg == "tx")
            {
                uint256 hash;
                vRecv >> hash;
                ss << ": hash " << hash.ToString();
            }
4821
            LogPrint("net", "Reject %s\n", SanitizeString(ss.str()));
Gavin Andresen's avatar
Gavin Andresen committed
4822
4823
4824
        }
    }

s_nakamoto's avatar
s_nakamoto committed
4825
4826
    else
    {
4827
4828
4829
4830
        //probably one the extensions
        ProcessMessageDarksend(pfrom, strCommand, vRecv);
        ProcessMessageMasternode(pfrom, strCommand, vRecv);
        ProcessMessageInstantX(pfrom, strCommand, vRecv);
s_nakamoto's avatar
s_nakamoto committed
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
    }


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


    return true;
}

4843
// requires LOCK(cs_vRecvMsg)
4844
4845
4846
bool ProcessMessages(CNode* pfrom)
{
    //if (fDebug)
4847
    //    LogPrintf("ProcessMessages(%u messages)\n", pfrom->vRecvMsg.size());
s_nakamoto's avatar
s_nakamoto committed
4848

4849
4850
4851
4852
4853
4854
4855
4856
    //
    // Message format
    //  (4) message start
    //  (12) command
    //  (4) size
    //  (4) checksum
    //  (x) data
    //
4857
    bool fOk = true;
s_nakamoto's avatar
s_nakamoto committed
4858

4859
4860
    if (!pfrom->vRecvGetData.empty())
        ProcessGetData(pfrom);
4861

4862
4863
    // this maintains the order of responses
    if (!pfrom->vRecvGetData.empty()) return fOk;
4864

4865
    std::deque<CNetMessage>::iterator it = pfrom->vRecvMsg.begin();
4866
    while (!pfrom->fDisconnect && it != pfrom->vRecvMsg.end()) {
4867
        // Don't bother if send buffer is too full to respond anyway
4868
        if (pfrom->nSendSize >= SendBufferSize())
4869
4870
            break;

4871
4872
        // get next message
        CNetMessage& msg = *it;
4873
4874

        //if (fDebug)
4875
        //    LogPrintf("ProcessMessages(message %u msgsz, %u bytes, complete:%s)\n",
4876
4877
4878
        //            msg.hdr.nMessageSize, msg.vRecv.size(),
        //            msg.complete() ? "Y" : "N");

4879
        // end, if an incomplete message is found
4880
        if (!msg.complete())
4881
            break;
4882

4883
4884
4885
        // at this point, any failure means we can delete the current message
        it++;

4886
        // Scan for message start
4887
        if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
4888
            LogPrintf("\n\nPROCESSMESSAGE: INVALID MESSAGESTART\n\n");
4889
4890
            fOk = false;
            break;
4891
        }
s_nakamoto's avatar
s_nakamoto committed
4892

4893
        // Read header
4894
        CMessageHeader& hdr = msg.hdr;
4895
4896
        if (!hdr.IsValid())
        {
4897
            LogPrintf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand());
4898
4899
4900
4901
4902
4903
4904
4905
            continue;
        }
        string strCommand = hdr.GetCommand();

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

        // Checksum
4906
        CDataStream& vRecv = msg.vRecv;
Pieter Wuille's avatar
Pieter Wuille committed
4907
4908
4909
4910
        uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
        unsigned int nChecksum = 0;
        memcpy(&nChecksum, &hash, sizeof(nChecksum));
        if (nChecksum != hdr.nChecksum)
4911
        {
4912
            LogPrintf("ProcessMessages(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
4913
               strCommand, nMessageSize, nChecksum, hdr.nChecksum);
Pieter Wuille's avatar
Pieter Wuille committed
4914
            continue;
4915
4916
4917
4918
4919
4920
        }

        // Process message
        bool fRet = false;
        try
        {
4921
            fRet = ProcessMessage(pfrom, strCommand, vRecv);
Gavin Andresen's avatar
Gavin Andresen committed
4922
            boost::this_thread::interruption_point();
4923
4924
4925
        }
        catch (std::ios_base::failure& e)
        {
Gavin Andresen's avatar
Gavin Andresen committed
4926
            pfrom->PushMessage("reject", strCommand, REJECT_MALFORMED, string("error parsing message"));
4927
4928
            if (strstr(e.what(), "end of data"))
            {
4929
                // Allow exceptions from under-length message on vRecv
4930
                LogPrintf("ProcessMessages(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand, nMessageSize, e.what());
4931
4932
4933
            }
            else if (strstr(e.what(), "size too large"))
            {
4934
                // Allow exceptions from over-long size
4935
                LogPrintf("ProcessMessages(%s, %u bytes) : Exception '%s' caught\n", strCommand, nMessageSize, e.what());
4936
4937
4938
            }
            else
            {
4939
                PrintExceptionContinue(&e, "ProcessMessages()");
4940
4941
            }
        }
Gavin Andresen's avatar
Gavin Andresen committed
4942
4943
4944
        catch (boost::thread_interrupted) {
            throw;
        }
4945
        catch (std::exception& e) {
4946
            PrintExceptionContinue(&e, "ProcessMessages()");
4947
        } catch (...) {
4948
            PrintExceptionContinue(NULL, "ProcessMessages()");
4949
4950
4951
        }

        if (!fRet)
4952
            LogPrintf("ProcessMessage(%s, %u bytes) FAILED\n", strCommand, nMessageSize);
4953

4954
        break;
4955
4956
    }

4957
4958
4959
4960
    // In case the connection got shut down, its receive buffer was wiped
    if (!pfrom->fDisconnect)
        pfrom->vRecvMsg.erase(pfrom->vRecvMsg.begin(), it);

4961
    return fOk;
4962
}
s_nakamoto's avatar
s_nakamoto committed
4963
4964
4965
4966


bool SendMessages(CNode* pto, bool fSendTrickle)
{
4967
    {
s_nakamoto's avatar
s_nakamoto committed
4968
4969
4970
4971
        // Don't send anything until we get their version message
        if (pto->nVersion == 0)
            return true;

Josh Lehan's avatar
Josh Lehan committed
4972
4973
4974
4975
4976
4977
4978
4979
        //
        // Message: ping
        //
        bool pingSend = false;
        if (pto->fPingQueued) {
            // RPC ping request by user
            pingSend = true;
        }
4980
        if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSendMsg.empty()) {
Josh Lehan's avatar
Josh Lehan committed
4981
4982
4983
4984
            // Ping automatically sent as a keepalive
            pingSend = true;
        }
        if (pingSend) {
4985
            uint64_t nonce = 0;
Josh Lehan's avatar
Josh Lehan committed
4986
4987
4988
4989
4990
4991
4992
4993
            while (nonce == 0) {
                RAND_bytes((unsigned char*)&nonce, sizeof(nonce));
            }
            pto->nPingNonceSent = nonce;
            pto->fPingQueued = false;
            if (pto->nVersion > BIP0031_VERSION) {
                // Take timestamp as close as possible before transmitting ping
                pto->nPingUsecStart = GetTimeMicros();
Pieter Wuille's avatar
Pieter Wuille committed
4994
                pto->PushMessage("ping", nonce);
Josh Lehan's avatar
Josh Lehan committed
4995
4996
4997
            } else {
                // Peer is too old to support ping command with nonce, pong will never arrive, disable timing
                pto->nPingUsecStart = 0;
Jeff Garzik's avatar
Jeff Garzik committed
4998
                pto->PushMessage("ping");
Josh Lehan's avatar
Josh Lehan committed
4999
            }
Jeff Garzik's avatar
Jeff Garzik committed
5000
        }
s_nakamoto's avatar
s_nakamoto committed
5001

5002
5003
5004
5005
        TRY_LOCK(cs_main, lockMain); // Acquire cs_main for IsInitialBlockDownload() and CNodeState()
        if (!lockMain)
            return true;

s_nakamoto's avatar
s_nakamoto committed
5006
        // Address refresh broadcast
5007
        static int64_t nLastRebroadcast;
5008
        if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
s_nakamoto's avatar
s_nakamoto committed
5009
5010
        {
            {
5011
                LOCK(cs_vNodes);
5012
                BOOST_FOREACH(CNode* pnode, vNodes)
s_nakamoto's avatar
s_nakamoto committed
5013
5014
                {
                    // Periodically clear setAddrKnown to allow refresh broadcasts
5015
5016
                    if (nLastRebroadcast)
                        pnode->setAddrKnown.clear();
s_nakamoto's avatar
s_nakamoto committed
5017
5018

                    // Rebroadcast our address
Pieter Wuille's avatar
Pieter Wuille committed
5019
                    if (!fNoListen)
s_nakamoto's avatar
s_nakamoto committed
5020
                    {
5021
5022
5023
                        CAddress addr = GetLocalAddress(&pnode->addr);
                        if (addr.IsRoutable())
                            pnode->PushAddress(addr);
s_nakamoto's avatar
s_nakamoto committed
5024
                    }
s_nakamoto's avatar
s_nakamoto committed
5025
5026
                }
            }
5027
            nLastRebroadcast = GetTime();
s_nakamoto's avatar
s_nakamoto committed
5028
5029
5030
5031
5032
5033
5034
5035
5036
        }

        //
        // Message: addr
        //
        if (fSendTrickle)
        {
            vector<CAddress> vAddr;
            vAddr.reserve(pto->vAddrToSend.size());
5037
            BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend)
s_nakamoto's avatar
s_nakamoto committed
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
            {
                // 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);
        }

5056
5057
        CNodeState &state = *State(pto->GetId());
        if (state.fShouldBan) {
Pieter Wuille's avatar
Pieter Wuille committed
5058
            if (pto->addr.IsLocal())
5059
                LogPrintf("Warning: not banning local node %s!\n", pto->addr.ToString());
Pieter Wuille's avatar
Pieter Wuille committed
5060
5061
5062
5063
            else {
                pto->fDisconnect = true;
                CNode::Ban(pto->addr);
            }
5064
            state.fShouldBan = false;
Pieter Wuille's avatar
Pieter Wuille committed
5065
5066
        }

5067
5068
5069
5070
        BOOST_FOREACH(const CBlockReject& reject, state.rejects)
            pto->PushMessage("reject", (string)"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock);
        state.rejects.clear();

5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
        // Start block sync
        if (pto->fStartSync && !fImporting && !fReindex) {
            pto->fStartSync = false;
            PushGetBlocks(pto, chainActive.Tip(), uint256(0));
        }

        // 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())
        {
5082
            g_signals.Broadcast();
5083
        }
s_nakamoto's avatar
s_nakamoto committed
5084
5085
5086
5087
5088
5089
5090

        //
        // Message: inventory
        //
        vector<CInv> vInv;
        vector<CInv> vInvWait;
        {
5091
            LOCK(pto->cs_inventory);
s_nakamoto's avatar
s_nakamoto committed
5092
5093
            vInv.reserve(pto->vInventoryToSend.size());
            vInvWait.reserve(pto->vInventoryToSend.size());
5094
            BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
s_nakamoto's avatar
s_nakamoto committed
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
            {
                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)
5105
                        hashSalt = GetRandHash();
s_nakamoto's avatar
s_nakamoto committed
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
                    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);


5134
5135
5136
5137
5138
        // Detect stalled peers. Require that blocks are in flight, we haven't
        // received a (requested) block in one minute, and that all blocks are
        // in flight for over two minutes, since we first had a chance to
        // process an incoming block.
        int64_t nNow = GetTimeMicros();
vertoe's avatar
vertoe committed
5139
5140
        if (!pto->fDisconnect && state.nBlocksInFlight &&
            state.nLastBlockReceive < state.nLastBlockProcess - BLOCK_DOWNLOAD_TIMEOUT*1000000 &&
5141
5142
5143
5144
5145
            state.vBlocksInFlight.front().nTime < state.nLastBlockProcess - 2*BLOCK_DOWNLOAD_TIMEOUT*1000000) {
            LogPrintf("Peer %s is stalling block download, disconnecting\n", state.name.c_str());
            pto->fDisconnect = true;
        }

s_nakamoto's avatar
s_nakamoto committed
5146
        //
5147
        // Message: getdata (blocks)
s_nakamoto's avatar
s_nakamoto committed
5148
5149
        //
        vector<CInv> vGetData;
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
        while (!pto->fDisconnect && state.nBlocksToDownload && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
            uint256 hash = state.vBlocksToDownload.front();
            vGetData.push_back(CInv(MSG_BLOCK, hash));
            MarkBlockAsInFlight(pto->GetId(), hash);
            LogPrint("net", "Requesting block %s from %s\n", hash.ToString().c_str(), state.name.c_str());
            if (vGetData.size() >= 1000)
            {
                pto->PushMessage("getdata", vGetData);
                vGetData.clear();
            }
        }

        //
        // Message: getdata (non-blocks)
        //
        while (!pto->fDisconnect && !pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
s_nakamoto's avatar
s_nakamoto committed
5166
5167
        {
            const CInv& inv = (*pto->mapAskFor.begin()).second;
5168
            if (!AlreadyHave(inv))
s_nakamoto's avatar
s_nakamoto committed
5169
            {
5170
                if (fDebug)
5171
                    LogPrint("net", "sending getdata: %s\n", inv.ToString());
s_nakamoto's avatar
s_nakamoto committed
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
                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;
}






5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
class CMainCleanup
{
public:
    CMainCleanup() {}
    ~CMainCleanup() {
        // block headers
        std::map<uint256, CBlockIndex*>::iterator it1 = mapBlockIndex.begin();
        for (; it1 != mapBlockIndex.end(); it1++)
            delete (*it1).second;
        mapBlockIndex.clear();

        // orphan blocks
5205
        std::map<uint256, COrphanBlock*>::iterator it2 = mapOrphanBlocks.begin();
5206
5207
5208
5209
5210
5211
        for (; it2 != mapOrphanBlocks.end(); it2++)
            delete (*it2).second;
        mapOrphanBlocks.clear();

        // orphan transactions
        mapOrphanTransactions.clear();
5212
        mapOrphanTransactionsByPrev.clear();
5213
5214
    }
} instance_of_cmaincleanup;