]>
Commit | Line | Data |
---|---|---|
0a61b0df | 1 | // Copyright (c) 2009-2010 Satoshi Nakamoto |
88216419 | 2 | // Copyright (c) 2009-2012 The Bitcoin developers |
0a61b0df | 3 | // Distributed under the MIT/X11 software license, see the accompanying |
3a25a2b9 F |
4 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
5 | ||
f35c6c4f | 6 | #include "alert.h" |
eb5fff9e | 7 | #include "checkpoints.h" |
1512d5ce | 8 | #include "db.h" |
2d8a4829 | 9 | #include "txdb.h" |
40c2614e | 10 | #include "net.h" |
edd309e5 | 11 | #include "init.h" |
ed6d0b5f | 12 | #include "ui_interface.h" |
f9cae832 | 13 | #include "checkqueue.h" |
d237f62c | 14 | #include <boost/algorithm/string/replace.hpp> |
926e14b3 | 15 | #include <boost/filesystem.hpp> |
31f29312 | 16 | #include <boost/filesystem/fstream.hpp> |
0a61b0df | 17 | |
223b6f1b WL |
18 | using namespace std; |
19 | using namespace boost; | |
0a61b0df | 20 | |
21 | // | |
22 | // Global state | |
23 | // | |
24 | ||
64c7ee7e PW |
25 | CCriticalSection cs_setpwalletRegistered; |
26 | set<CWallet*> setpwalletRegistered; | |
27 | ||
0a61b0df | 28 | CCriticalSection cs_main; |
29 | ||
8e45ed66 | 30 | CTxMemPool mempool; |
0a61b0df | 31 | unsigned int nTransactionsUpdated = 0; |
0a61b0df | 32 | |
33 | map<uint256, CBlockIndex*> mapBlockIndex; | |
0fe8010a | 34 | std::vector<CBlockIndex*> vBlockIndexByHeight; |
5cbf7532 | 35 | uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"); |
99860de3 | 36 | static CBigNum bnProofOfWorkLimit(~uint256(0) >> 32); |
0a61b0df | 37 | CBlockIndex* pindexGenesisBlock = NULL; |
38 | int nBestHeight = -1; | |
1657c4bc PW |
39 | uint256 nBestChainWork = 0; |
40 | uint256 nBestInvalidWork = 0; | |
0a61b0df | 41 | uint256 hashBestChain = 0; |
42 | CBlockIndex* pindexBest = NULL; | |
857c61df | 43 | set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexValid; // may contain all CBlockIndex*'s that have validness >=BLOCK_VALID_TRANSACTIONS, and must contain those who aren't failed |
bde280b9 | 44 | int64 nTimeBestReceived = 0; |
f9cae832 | 45 | int nScriptCheckThreads = 0; |
66b02c93 | 46 | bool fImporting = false; |
7fea4846 | 47 | bool fReindex = false; |
8a28bb6d | 48 | bool fBenchmark = false; |
2d1fa42e | 49 | bool fTxIndex = false; |
1c83b0a3 | 50 | unsigned int nCoinCacheSize = 5000; |
0a61b0df | 51 | |
000dc551 GA |
52 | /** Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) */ |
53 | int64 CTransaction::nMinTxFee = 10000; // Override with -mintxfee | |
54 | /** Fees smaller than this (in satoshi) are considered zero fee (for relaying) */ | |
55 | int64 CTransaction::nMinRelayTxFee = 10000; | |
56 | ||
54413aab | 57 | CMedianFilter<int> cPeerBlockCounts(8, 0); // Amount of blocks that other nodes claim to have |
a8b95ce6 | 58 | |
0a61b0df | 59 | map<uint256, CBlock*> mapOrphanBlocks; |
60 | multimap<uint256, CBlock*> mapOrphanBlocksByPrev; | |
61 | ||
62 | map<uint256, CDataStream*> mapOrphanTransactions; | |
77b99cf7 | 63 | map<uint256, map<uint256, CDataStream*> > mapOrphanTransactionsByPrev; |
0a61b0df | 64 | |
7bf8b7c2 GA |
65 | // Constant stuff for coinbase transactions we create: |
66 | CScript COINBASE_FLAGS; | |
0a61b0df | 67 | |
2bc4fd60 LD |
68 | const string strMessageMagic = "Bitcoin Signed Message:\n"; |
69 | ||
c8c2fbe0 GA |
70 | double dHashesPerSec = 0.0; |
71 | int64 nHPSTimerStart = 0; | |
0a61b0df | 72 | |
73 | // Settings | |
bde280b9 | 74 | int64 nTransactionFee = 0; |
972060ce | 75 | |
8bb5edc1 | 76 | |
0a61b0df | 77 | |
64c7ee7e PW |
78 | ////////////////////////////////////////////////////////////////////////////// |
79 | // | |
80 | // dispatching functions | |
81 | // | |
82 | ||
d825e6a3 PW |
83 | // These functions dispatch to one or all registered wallets |
84 | ||
85 | ||
64c7ee7e PW |
86 | void RegisterWallet(CWallet* pwalletIn) |
87 | { | |
64c7ee7e | 88 | { |
f8dcd5ca | 89 | LOCK(cs_setpwalletRegistered); |
64c7ee7e PW |
90 | setpwalletRegistered.insert(pwalletIn); |
91 | } | |
92 | } | |
93 | ||
94 | void UnregisterWallet(CWallet* pwalletIn) | |
95 | { | |
64c7ee7e | 96 | { |
f8dcd5ca | 97 | LOCK(cs_setpwalletRegistered); |
64c7ee7e PW |
98 | setpwalletRegistered.erase(pwalletIn); |
99 | } | |
100 | } | |
101 | ||
d825e6a3 | 102 | // get the wallet transaction with the given hash (if it exists) |
64c7ee7e PW |
103 | bool static GetTransaction(const uint256& hashTx, CWalletTx& wtx) |
104 | { | |
105 | BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) | |
106 | if (pwallet->GetTransaction(hashTx,wtx)) | |
107 | return true; | |
108 | return false; | |
109 | } | |
110 | ||
d825e6a3 | 111 | // erases transaction with the given hash from all wallets |
64c7ee7e PW |
112 | void static EraseFromWallets(uint256 hash) |
113 | { | |
114 | BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) | |
115 | pwallet->EraseFromWallet(hash); | |
116 | } | |
117 | ||
d825e6a3 | 118 | // make sure all wallets know about the given transaction, in the given block |
64dd46fd | 119 | void SyncWithWallets(const uint256 &hash, const CTransaction& tx, const CBlock* pblock, bool fUpdate) |
64c7ee7e PW |
120 | { |
121 | BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) | |
64dd46fd | 122 | pwallet->AddToWalletIfInvolvingMe(hash, tx, pblock, fUpdate); |
64c7ee7e PW |
123 | } |
124 | ||
d825e6a3 | 125 | // notify wallets about a new best chain |
64c7ee7e PW |
126 | void static SetBestChain(const CBlockLocator& loc) |
127 | { | |
128 | BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) | |
129 | pwallet->SetBestChain(loc); | |
130 | } | |
131 | ||
d825e6a3 | 132 | // notify wallets about an updated transaction |
64c7ee7e PW |
133 | void static UpdatedTransaction(const uint256& hashTx) |
134 | { | |
135 | BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) | |
136 | pwallet->UpdatedTransaction(hashTx); | |
137 | } | |
138 | ||
d825e6a3 | 139 | // dump all wallets |
64c7ee7e PW |
140 | void static PrintWallets(const CBlock& block) |
141 | { | |
142 | BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) | |
143 | pwallet->PrintWallet(block); | |
144 | } | |
145 | ||
d825e6a3 | 146 | // notify wallets about an incoming inventory (for request counts) |
64c7ee7e PW |
147 | void static Inventory(const uint256& hash) |
148 | { | |
149 | BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) | |
150 | pwallet->Inventory(hash); | |
151 | } | |
152 | ||
d825e6a3 | 153 | // ask wallets to resend their transactions |
64c7ee7e PW |
154 | void static ResendWalletTransactions() |
155 | { | |
156 | BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) | |
157 | pwallet->ResendWalletTransactions(); | |
158 | } | |
159 | ||
160 | ||
161 | ||
162 | ||
163 | ||
164 | ||
165 | ||
450cbb09 PW |
166 | ////////////////////////////////////////////////////////////////////////////// |
167 | // | |
168 | // CCoinsView implementations | |
169 | // | |
170 | ||
f369d02c PW |
171 | bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) { return false; } |
172 | bool CCoinsView::SetCoins(const uint256 &txid, const CCoins &coins) { return false; } | |
173 | bool CCoinsView::HaveCoins(const uint256 &txid) { return false; } | |
450cbb09 PW |
174 | CBlockIndex *CCoinsView::GetBestBlock() { return NULL; } |
175 | bool CCoinsView::SetBestBlock(CBlockIndex *pindex) { return false; } | |
ae8bfd12 | 176 | bool CCoinsView::BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex) { return false; } |
beeb5761 | 177 | bool CCoinsView::GetStats(CCoinsStats &stats) { return false; } |
450cbb09 | 178 | |
13c51f20 | 179 | |
450cbb09 | 180 | CCoinsViewBacked::CCoinsViewBacked(CCoinsView &viewIn) : base(&viewIn) { } |
f369d02c PW |
181 | bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) { return base->GetCoins(txid, coins); } |
182 | bool CCoinsViewBacked::SetCoins(const uint256 &txid, const CCoins &coins) { return base->SetCoins(txid, coins); } | |
183 | bool CCoinsViewBacked::HaveCoins(const uint256 &txid) { return base->HaveCoins(txid); } | |
450cbb09 PW |
184 | CBlockIndex *CCoinsViewBacked::GetBestBlock() { return base->GetBestBlock(); } |
185 | bool CCoinsViewBacked::SetBestBlock(CBlockIndex *pindex) { return base->SetBestBlock(pindex); } | |
186 | void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; } | |
ae8bfd12 | 187 | bool CCoinsViewBacked::BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex) { return base->BatchWrite(mapCoins, pindex); } |
beeb5761 | 188 | bool CCoinsViewBacked::GetStats(CCoinsStats &stats) { return base->GetStats(stats); } |
450cbb09 PW |
189 | |
190 | CCoinsViewCache::CCoinsViewCache(CCoinsView &baseIn, bool fDummy) : CCoinsViewBacked(baseIn), pindexTip(NULL) { } | |
191 | ||
f369d02c | 192 | bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) { |
450cbb09 PW |
193 | if (cacheCoins.count(txid)) { |
194 | coins = cacheCoins[txid]; | |
195 | return true; | |
196 | } | |
197 | if (base->GetCoins(txid, coins)) { | |
198 | cacheCoins[txid] = coins; | |
199 | return true; | |
200 | } | |
201 | return false; | |
202 | } | |
203 | ||
f369d02c PW |
204 | std::map<uint256,CCoins>::iterator CCoinsViewCache::FetchCoins(const uint256 &txid) { |
205 | std::map<uint256,CCoins>::iterator it = cacheCoins.lower_bound(txid); | |
206 | if (it != cacheCoins.end() && it->first == txid) | |
13c51f20 PW |
207 | return it; |
208 | CCoins tmp; | |
209 | if (!base->GetCoins(txid,tmp)) | |
f369d02c PW |
210 | return cacheCoins.end(); |
211 | std::map<uint256,CCoins>::iterator ret = cacheCoins.insert(it, std::make_pair(txid, CCoins())); | |
212 | tmp.swap(ret->second); | |
213 | return ret; | |
13c51f20 PW |
214 | } |
215 | ||
f369d02c | 216 | CCoins &CCoinsViewCache::GetCoins(const uint256 &txid) { |
13c51f20 PW |
217 | std::map<uint256,CCoins>::iterator it = FetchCoins(txid); |
218 | assert(it != cacheCoins.end()); | |
219 | return it->second; | |
220 | } | |
221 | ||
f369d02c | 222 | bool CCoinsViewCache::SetCoins(const uint256 &txid, const CCoins &coins) { |
450cbb09 PW |
223 | cacheCoins[txid] = coins; |
224 | return true; | |
225 | } | |
226 | ||
f369d02c | 227 | bool CCoinsViewCache::HaveCoins(const uint256 &txid) { |
13c51f20 | 228 | return FetchCoins(txid) != cacheCoins.end(); |
450cbb09 PW |
229 | } |
230 | ||
231 | CBlockIndex *CCoinsViewCache::GetBestBlock() { | |
232 | if (pindexTip == NULL) | |
233 | pindexTip = base->GetBestBlock(); | |
234 | return pindexTip; | |
235 | } | |
236 | ||
237 | bool CCoinsViewCache::SetBestBlock(CBlockIndex *pindex) { | |
238 | pindexTip = pindex; | |
239 | return true; | |
240 | } | |
241 | ||
ae8bfd12 PW |
242 | bool CCoinsViewCache::BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockIndex *pindex) { |
243 | for (std::map<uint256, CCoins>::const_iterator it = mapCoins.begin(); it != mapCoins.end(); it++) | |
244 | cacheCoins[it->first] = it->second; | |
245 | pindexTip = pindex; | |
450cbb09 PW |
246 | return true; |
247 | } | |
248 | ||
ae8bfd12 PW |
249 | bool CCoinsViewCache::Flush() { |
250 | bool fOk = base->BatchWrite(cacheCoins, pindexTip); | |
251 | if (fOk) | |
252 | cacheCoins.clear(); | |
253 | return fOk; | |
254 | } | |
255 | ||
256 | unsigned int CCoinsViewCache::GetCacheSize() { | |
257 | return cacheCoins.size(); | |
258 | } | |
259 | ||
450cbb09 PW |
260 | /** CCoinsView that brings transactions from a memorypool into view. |
261 | It does not check for spendings by memory pool transactions. */ | |
262 | CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView &baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { } | |
263 | ||
f369d02c | 264 | bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) { |
450cbb09 PW |
265 | if (base->GetCoins(txid, coins)) |
266 | return true; | |
267 | if (mempool.exists(txid)) { | |
268 | const CTransaction &tx = mempool.lookup(txid); | |
269 | coins = CCoins(tx, MEMPOOL_HEIGHT); | |
270 | return true; | |
271 | } | |
272 | return false; | |
273 | } | |
274 | ||
f369d02c | 275 | bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) { |
450cbb09 PW |
276 | return mempool.exists(txid) || base->HaveCoins(txid); |
277 | } | |
278 | ||
ae8bfd12 | 279 | CCoinsViewCache *pcoinsTip = NULL; |
d979e6e3 | 280 | CBlockTreeDB *pblocktree = NULL; |
450cbb09 | 281 | |
0a61b0df | 282 | ////////////////////////////////////////////////////////////////////////////// |
283 | // | |
284 | // mapOrphanTransactions | |
285 | // | |
286 | ||
77b99cf7 | 287 | bool AddOrphanTx(const CDataStream& vMsg) |
0a61b0df | 288 | { |
289 | CTransaction tx; | |
290 | CDataStream(vMsg) >> tx; | |
291 | uint256 hash = tx.GetHash(); | |
292 | if (mapOrphanTransactions.count(hash)) | |
77b99cf7 GA |
293 | return false; |
294 | ||
295 | CDataStream* pvMsg = new CDataStream(vMsg); | |
142e6041 | 296 | |
77b99cf7 GA |
297 | // Ignore big transactions, to avoid a |
298 | // send-big-orphans memory exhaustion attack. If a peer has a legitimate | |
299 | // large transaction with a missing parent then we assume | |
300 | // it will rebroadcast it later, after the parent transaction(s) | |
301 | // have been mined or received. | |
302 | // 10,000 orphans, each of which is at most 5,000 bytes big is | |
303 | // at most 500 megabytes of orphans: | |
304 | if (pvMsg->size() > 5000) | |
305 | { | |
1c06aa98 | 306 | printf("ignoring large orphan tx (size: %"PRIszu", hash: %s)\n", pvMsg->size(), hash.ToString().c_str()); |
c283b3c5 | 307 | delete pvMsg; |
77b99cf7 GA |
308 | return false; |
309 | } | |
142e6041 | 310 | |
77b99cf7 | 311 | mapOrphanTransactions[hash] = pvMsg; |
223b6f1b | 312 | BOOST_FOREACH(const CTxIn& txin, tx.vin) |
77b99cf7 GA |
313 | mapOrphanTransactionsByPrev[txin.prevout.hash].insert(make_pair(hash, pvMsg)); |
314 | ||
1c06aa98 | 315 | printf("stored orphan tx %s (mapsz %"PRIszu")\n", hash.ToString().c_str(), |
77b99cf7 GA |
316 | mapOrphanTransactions.size()); |
317 | return true; | |
0a61b0df | 318 | } |
319 | ||
64c7ee7e | 320 | void static EraseOrphanTx(uint256 hash) |
0a61b0df | 321 | { |
322 | if (!mapOrphanTransactions.count(hash)) | |
323 | return; | |
324 | const CDataStream* pvMsg = mapOrphanTransactions[hash]; | |
325 | CTransaction tx; | |
326 | CDataStream(*pvMsg) >> tx; | |
223b6f1b | 327 | BOOST_FOREACH(const CTxIn& txin, tx.vin) |
0a61b0df | 328 | { |
77b99cf7 GA |
329 | mapOrphanTransactionsByPrev[txin.prevout.hash].erase(hash); |
330 | if (mapOrphanTransactionsByPrev[txin.prevout.hash].empty()) | |
331 | mapOrphanTransactionsByPrev.erase(txin.prevout.hash); | |
0a61b0df | 332 | } |
333 | delete pvMsg; | |
334 | mapOrphanTransactions.erase(hash); | |
335 | } | |
336 | ||
7bd9c3a3 | 337 | unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) |
142e6041 | 338 | { |
7bd9c3a3 | 339 | unsigned int nEvicted = 0; |
142e6041 GA |
340 | while (mapOrphanTransactions.size() > nMaxOrphans) |
341 | { | |
342 | // Evict a random orphan: | |
f718aedd | 343 | uint256 randomhash = GetRandHash(); |
142e6041 GA |
344 | map<uint256, CDataStream*>::iterator it = mapOrphanTransactions.lower_bound(randomhash); |
345 | if (it == mapOrphanTransactions.end()) | |
346 | it = mapOrphanTransactions.begin(); | |
347 | EraseOrphanTx(it->first); | |
348 | ++nEvicted; | |
349 | } | |
350 | return nEvicted; | |
351 | } | |
0a61b0df | 352 | |
353 | ||
354 | ||
355 | ||
356 | ||
357 | ||
358 | ||
359 | ////////////////////////////////////////////////////////////////////////////// | |
360 | // | |
000dc551 | 361 | // CTransaction / CTxOut |
0a61b0df | 362 | // |
363 | ||
000dc551 GA |
364 | bool CTxOut::IsDust() const |
365 | { | |
366 | // "Dust" is defined in terms of CTransaction::nMinRelayTxFee, | |
367 | // which has units satoshis-per-kilobyte. | |
368 | // If you'd pay more than 1/3 in fees | |
369 | // to spend something, then we consider it dust. | |
370 | // A typical txout is 33 bytes big, and will | |
371 | // need a CTxIn of at least 148 bytes to spend, | |
372 | // so dust is a txout less than 54 uBTC | |
373 | // (5430 satoshis) with default nMinRelayTxFee | |
374 | return ((nValue*1000)/(3*((int)GetSerializeSize(SER_DISK,0)+148)) < CTransaction::nMinRelayTxFee); | |
375 | } | |
376 | ||
e679ec96 GA |
377 | bool CTransaction::IsStandard() const |
378 | { | |
dae3e10a GA |
379 | if (nVersion > CTransaction::CURRENT_VERSION) |
380 | return false; | |
381 | ||
6f873075 GA |
382 | if (!IsFinal()) |
383 | return false; | |
384 | ||
41e1a0d7 GA |
385 | // Extremely large transactions with lots of inputs can cost the network |
386 | // almost as much to process as they cost the sender in fees, because | |
387 | // computing signature hashes is O(ninputs*txsize). Limiting transactions | |
388 | // to MAX_STANDARD_TX_SIZE mitigates CPU exhaustion attacks. | |
389 | unsigned int sz = this->GetSerializeSize(SER_NETWORK, CTransaction::CURRENT_VERSION); | |
390 | if (sz >= MAX_STANDARD_TX_SIZE) | |
391 | return false; | |
392 | ||
e679ec96 GA |
393 | BOOST_FOREACH(const CTxIn& txin, vin) |
394 | { | |
2a45a494 | 395 | // Biggest 'standard' txin is a 3-signature 3-of-3 CHECKMULTISIG |
922e8e29 | 396 | // pay-to-script-hash, which is 3 ~80-byte signatures, 3 |
e679ec96 | 397 | // ~65-byte public keys, plus a few script ops. |
2a45a494 | 398 | if (txin.scriptSig.size() > 500) |
922e8e29 | 399 | return false; |
e679ec96 | 400 | if (!txin.scriptSig.IsPushOnly()) |
922e8e29 | 401 | return false; |
e679ec96 | 402 | } |
65ce2156 | 403 | BOOST_FOREACH(const CTxOut& txout, vout) { |
e679ec96 | 404 | if (!::IsStandard(txout.scriptPubKey)) |
922e8e29 | 405 | return false; |
8de9bb53 | 406 | if (txout.IsDust()) |
65ce2156 PW |
407 | return false; |
408 | } | |
e679ec96 GA |
409 | return true; |
410 | } | |
411 | ||
412 | // | |
413 | // Check transaction inputs, and make sure any | |
922e8e29 | 414 | // pay-to-script-hash transactions are evaluating IsStandard scripts |
e679ec96 GA |
415 | // |
416 | // Why bother? To avoid denial-of-service attacks; an attacker | |
922e8e29 GA |
417 | // can submit a standard HASH... OP_EQUAL transaction, |
418 | // which will get accepted into blocks. The redemption | |
419 | // script can be anything; an attacker could use a very | |
e679ec96 GA |
420 | // expensive-to-check-upon-redemption script like: |
421 | // DUP CHECKSIG DROP ... repeated 100 times... OP_1 | |
422 | // | |
13c51f20 | 423 | bool CTransaction::AreInputsStandard(CCoinsViewCache& mapInputs) const |
e679ec96 | 424 | { |
8d7849b6 | 425 | if (IsCoinBase()) |
575bdcde | 426 | return true; // Coinbases don't use vin normally |
8d7849b6 | 427 | |
c376ac35 | 428 | for (unsigned int i = 0; i < vin.size(); i++) |
e679ec96 | 429 | { |
8d7849b6 | 430 | const CTxOut& prev = GetOutputFor(vin[i], mapInputs); |
e679ec96 GA |
431 | |
432 | vector<vector<unsigned char> > vSolutions; | |
2a45a494 GA |
433 | txnouttype whichType; |
434 | // get the scriptPubKey corresponding to this input: | |
8d7849b6 | 435 | const CScript& prevScript = prev.scriptPubKey; |
2a45a494 | 436 | if (!Solver(prevScript, whichType, vSolutions)) |
922e8e29 | 437 | return false; |
39f0d968 | 438 | int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions); |
c0a0a93d JG |
439 | if (nArgsExpected < 0) |
440 | return false; | |
39f0d968 GA |
441 | |
442 | // Transactions with extra stuff in their scriptSigs are | |
443 | // non-standard. Note that this EvalScript() call will | |
444 | // be quick, because if there are any operations | |
445 | // beside "push data" in the scriptSig the | |
446 | // IsStandard() call returns false | |
447 | vector<vector<unsigned char> > stack; | |
58bc86e3 | 448 | if (!EvalScript(stack, vin[i].scriptSig, *this, i, false, 0)) |
39f0d968 GA |
449 | return false; |
450 | ||
e679ec96 GA |
451 | if (whichType == TX_SCRIPTHASH) |
452 | { | |
922e8e29 | 453 | if (stack.empty()) |
e679ec96 | 454 | return false; |
2a45a494 | 455 | CScript subscript(stack.back().begin(), stack.back().end()); |
39f0d968 GA |
456 | vector<vector<unsigned char> > vSolutions2; |
457 | txnouttype whichType2; | |
458 | if (!Solver(subscript, whichType2, vSolutions2)) | |
922e8e29 | 459 | return false; |
39f0d968 GA |
460 | if (whichType2 == TX_SCRIPTHASH) |
461 | return false; | |
c0a0a93d JG |
462 | |
463 | int tmpExpected; | |
464 | tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2); | |
465 | if (tmpExpected < 0) | |
466 | return false; | |
467 | nArgsExpected += tmpExpected; | |
e679ec96 | 468 | } |
39f0d968 | 469 | |
c0a0a93d | 470 | if (stack.size() != (unsigned int)nArgsExpected) |
39f0d968 | 471 | return false; |
e679ec96 GA |
472 | } |
473 | ||
474 | return true; | |
475 | } | |
476 | ||
69e07747 | 477 | unsigned int CTransaction::GetLegacySigOpCount() const |
922e8e29 | 478 | { |
7bd9c3a3 | 479 | unsigned int nSigOps = 0; |
922e8e29 GA |
480 | BOOST_FOREACH(const CTxIn& txin, vin) |
481 | { | |
482 | nSigOps += txin.scriptSig.GetSigOpCount(false); | |
483 | } | |
484 | BOOST_FOREACH(const CTxOut& txout, vout) | |
485 | { | |
486 | nSigOps += txout.scriptPubKey.GetSigOpCount(false); | |
487 | } | |
488 | return nSigOps; | |
489 | } | |
0a61b0df | 490 | |
491 | ||
492 | int CMerkleTx::SetMerkleBranch(const CBlock* pblock) | |
493 | { | |
c2b72ba2 PW |
494 | CBlock blockTmp; |
495 | ||
496 | if (pblock == NULL) { | |
497 | CCoins coins; | |
498 | if (pcoinsTip->GetCoins(GetHash(), coins)) { | |
499 | CBlockIndex *pindex = FindBlockByHeight(coins.nHeight); | |
500 | if (pindex) { | |
501 | if (!blockTmp.ReadFromDisk(pindex)) | |
502 | return 0; | |
503 | pblock = &blockTmp; | |
450cbb09 | 504 | } |
0a61b0df | 505 | } |
c2b72ba2 | 506 | } |
0a61b0df | 507 | |
c2b72ba2 | 508 | if (pblock) { |
0a61b0df | 509 | // Update the tx's hashBlock |
510 | hashBlock = pblock->GetHash(); | |
511 | ||
512 | // Locate the transaction | |
1d8c7a95 | 513 | for (nIndex = 0; nIndex < (int)pblock->vtx.size(); nIndex++) |
0a61b0df | 514 | if (pblock->vtx[nIndex] == *(CTransaction*)this) |
515 | break; | |
1d8c7a95 | 516 | if (nIndex == (int)pblock->vtx.size()) |
0a61b0df | 517 | { |
518 | vMerkleBranch.clear(); | |
519 | nIndex = -1; | |
520 | printf("ERROR: SetMerkleBranch() : couldn't find tx in block\n"); | |
521 | return 0; | |
522 | } | |
523 | ||
524 | // Fill in merkle branch | |
525 | vMerkleBranch = pblock->GetMerkleBranch(nIndex); | |
526 | } | |
527 | ||
528 | // Is the tx in a block that's in the main chain | |
529 | map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); | |
530 | if (mi == mapBlockIndex.end()) | |
531 | return 0; | |
532 | CBlockIndex* pindex = (*mi).second; | |
533 | if (!pindex || !pindex->IsInMainChain()) | |
534 | return 0; | |
535 | ||
536 | return pindexBest->nHeight - pindex->nHeight + 1; | |
537 | } | |
538 | ||
539 | ||
540 | ||
0a61b0df | 541 | |
542 | ||
543 | ||
544 | ||
ef3988ca | 545 | bool CTransaction::CheckTransaction(CValidationState &state) const |
a790fa46 | 546 | { |
547 | // Basic checks that don't depend on any context | |
d0d9486f | 548 | if (vin.empty()) |
ef3988ca | 549 | return state.DoS(10, error("CTransaction::CheckTransaction() : vin empty")); |
d0d9486f | 550 | if (vout.empty()) |
ef3988ca | 551 | return state.DoS(10, error("CTransaction::CheckTransaction() : vout empty")); |
a790fa46 | 552 | // Size limits |
6b6aaa16 | 553 | if (::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) |
ef3988ca | 554 | return state.DoS(100, error("CTransaction::CheckTransaction() : size limits failed")); |
a790fa46 | 555 | |
556 | // Check for negative or overflow output values | |
bde280b9 | 557 | int64 nValueOut = 0; |
223b6f1b | 558 | BOOST_FOREACH(const CTxOut& txout, vout) |
a790fa46 | 559 | { |
560 | if (txout.nValue < 0) | |
ef3988ca | 561 | return state.DoS(100, error("CTransaction::CheckTransaction() : txout.nValue negative")); |
a790fa46 | 562 | if (txout.nValue > MAX_MONEY) |
ef3988ca | 563 | return state.DoS(100, error("CTransaction::CheckTransaction() : txout.nValue too high")); |
a790fa46 | 564 | nValueOut += txout.nValue; |
565 | if (!MoneyRange(nValueOut)) | |
ef3988ca | 566 | return state.DoS(100, error("CTransaction::CheckTransaction() : txout total out of range")); |
a790fa46 | 567 | } |
568 | ||
33208fb5 MC |
569 | // Check for duplicate inputs |
570 | set<COutPoint> vInOutPoints; | |
571 | BOOST_FOREACH(const CTxIn& txin, vin) | |
572 | { | |
573 | if (vInOutPoints.count(txin.prevout)) | |
ef3988ca | 574 | return state.DoS(100, error("CTransaction::CheckTransaction() : duplicate inputs")); |
33208fb5 MC |
575 | vInOutPoints.insert(txin.prevout); |
576 | } | |
577 | ||
a790fa46 | 578 | if (IsCoinBase()) |
579 | { | |
580 | if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100) | |
ef3988ca | 581 | return state.DoS(100, error("CTransaction::CheckTransaction() : coinbase script size")); |
a790fa46 | 582 | } |
583 | else | |
584 | { | |
223b6f1b | 585 | BOOST_FOREACH(const CTxIn& txin, vin) |
a790fa46 | 586 | if (txin.prevout.IsNull()) |
ef3988ca | 587 | return state.DoS(10, error("CTransaction::CheckTransaction() : prevout is null")); |
a790fa46 | 588 | } |
589 | ||
590 | return true; | |
591 | } | |
592 | ||
76970091 JG |
593 | int64 CTransaction::GetMinFee(unsigned int nBlockSize, bool fAllowFree, |
594 | enum GetMinFee_mode mode) const | |
595 | { | |
000dc551 GA |
596 | // Base fee is either nMinTxFee or nMinRelayTxFee |
597 | int64 nBaseFee = (mode == GMF_RELAY) ? nMinRelayTxFee : nMinTxFee; | |
76970091 JG |
598 | |
599 | unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION); | |
600 | unsigned int nNewBlockSize = nBlockSize + nBytes; | |
601 | int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee; | |
602 | ||
603 | if (fAllowFree) | |
604 | { | |
605 | if (nBlockSize == 1) | |
606 | { | |
607 | // Transactions under 10K are free | |
608 | // (about 4500 BTC if made of 50 BTC inputs) | |
609 | if (nBytes < 10000) | |
610 | nMinFee = 0; | |
611 | } | |
612 | else | |
613 | { | |
614 | // Free transaction area | |
615 | if (nNewBlockSize < 27000) | |
616 | nMinFee = 0; | |
617 | } | |
618 | } | |
619 | ||
000dc551 | 620 | // To limit dust spam, require base fee if any output is less than 0.01 |
76970091 JG |
621 | if (nMinFee < nBaseFee) |
622 | { | |
623 | BOOST_FOREACH(const CTxOut& txout, vout) | |
624 | if (txout.nValue < CENT) | |
625 | nMinFee = nBaseFee; | |
626 | } | |
627 | ||
628 | // Raise the price as the block approaches full | |
629 | if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2) | |
630 | { | |
631 | if (nNewBlockSize >= MAX_BLOCK_SIZE_GEN) | |
632 | return MAX_MONEY; | |
633 | nMinFee *= MAX_BLOCK_SIZE_GEN / (MAX_BLOCK_SIZE_GEN - nNewBlockSize); | |
634 | } | |
635 | ||
636 | if (!MoneyRange(nMinFee)) | |
637 | nMinFee = MAX_MONEY; | |
638 | return nMinFee; | |
639 | } | |
640 | ||
450cbb09 PW |
641 | void CTxMemPool::pruneSpent(const uint256 &hashTx, CCoins &coins) |
642 | { | |
643 | LOCK(cs); | |
644 | ||
645 | std::map<COutPoint, CInPoint>::iterator it = mapNextTx.lower_bound(COutPoint(hashTx, 0)); | |
646 | ||
647 | // iterate over all COutPoints in mapNextTx whose hash equals the provided hashTx | |
648 | while (it != mapNextTx.end() && it->first.hash == hashTx) { | |
649 | coins.Spend(it->first.n); // and remove those outputs from coins | |
650 | it++; | |
651 | } | |
652 | } | |
76970091 | 653 | |
ef3988ca | 654 | bool CTxMemPool::accept(CValidationState &state, CTransaction &tx, bool fCheckInputs, bool fLimitFree, |
d01903e7 | 655 | bool* pfMissingInputs) |
0a61b0df | 656 | { |
657 | if (pfMissingInputs) | |
658 | *pfMissingInputs = false; | |
659 | ||
ef3988ca | 660 | if (!tx.CheckTransaction(state)) |
d01903e7 | 661 | return error("CTxMemPool::accept() : CheckTransaction failed"); |
a790fa46 | 662 | |
0a61b0df | 663 | // Coinbase is only valid in a block, not as a loose transaction |
d01903e7 | 664 | if (tx.IsCoinBase()) |
ef3988ca | 665 | return state.DoS(100, error("CTxMemPool::accept() : coinbase as individual tx")); |
0a61b0df | 666 | |
0a61b0df | 667 | // To help v0.1.5 clients who would see it as a negative number |
d01903e7 JG |
668 | if ((int64)tx.nLockTime > std::numeric_limits<int>::max()) |
669 | return error("CTxMemPool::accept() : not accepting nLockTime beyond 2038 yet"); | |
f1e1fb4b | 670 | |
5ec05f0a | 671 | // Rather not work on nonstandard transactions (unless -testnet) |
d01903e7 JG |
672 | if (!fTestNet && !tx.IsStandard()) |
673 | return error("CTxMemPool::accept() : nonstandard transaction type"); | |
97ee01ad | 674 | |
450cbb09 | 675 | // is it already in the memory pool? |
d01903e7 | 676 | uint256 hash = tx.GetHash(); |
f8dcd5ca | 677 | { |
d01903e7 JG |
678 | LOCK(cs); |
679 | if (mapTx.count(hash)) | |
0a61b0df | 680 | return false; |
f8dcd5ca | 681 | } |
0a61b0df | 682 | |
683 | // Check for conflicts with in-memory transactions | |
684 | CTransaction* ptxOld = NULL; | |
c23617fe | 685 | for (unsigned int i = 0; i < tx.vin.size(); i++) |
0a61b0df | 686 | { |
d01903e7 | 687 | COutPoint outpoint = tx.vin[i].prevout; |
0a61b0df | 688 | if (mapNextTx.count(outpoint)) |
689 | { | |
690 | // Disable replacement feature for now | |
691 | return false; | |
692 | ||
693 | // Allow replacing with a newer version of the same transaction | |
694 | if (i != 0) | |
695 | return false; | |
696 | ptxOld = mapNextTx[outpoint].ptx; | |
683bcb91 | 697 | if (ptxOld->IsFinal()) |
698 | return false; | |
d01903e7 | 699 | if (!tx.IsNewerThan(*ptxOld)) |
0a61b0df | 700 | return false; |
c23617fe | 701 | for (unsigned int i = 0; i < tx.vin.size(); i++) |
0a61b0df | 702 | { |
d01903e7 | 703 | COutPoint outpoint = tx.vin[i].prevout; |
0a61b0df | 704 | if (!mapNextTx.count(outpoint) || mapNextTx[outpoint].ptx != ptxOld) |
705 | return false; | |
706 | } | |
707 | break; | |
708 | } | |
709 | } | |
710 | ||
97ee01ad | 711 | if (fCheckInputs) |
0a61b0df | 712 | { |
4afc0b54 PW |
713 | CCoinsView dummy; |
714 | CCoinsViewCache view(dummy); | |
715 | ||
716 | { | |
717 | LOCK(cs); | |
718 | CCoinsViewMemPool viewMemPool(*pcoinsTip, *this); | |
719 | view.SetBackend(viewMemPool); | |
450cbb09 PW |
720 | |
721 | // do we already have it? | |
722 | if (view.HaveCoins(hash)) | |
33a53bc1 | 723 | return false; |
450cbb09 PW |
724 | |
725 | // do all inputs exist? | |
c2ed184f PW |
726 | // Note that this does not check for the presence of actual outputs (see the next check for that), |
727 | // only helps filling in pfMissingInputs (to determine missing vs spent). | |
450cbb09 PW |
728 | BOOST_FOREACH(const CTxIn txin, tx.vin) { |
729 | if (!view.HaveCoins(txin.prevout.hash)) { | |
730 | if (pfMissingInputs) | |
731 | *pfMissingInputs = true; | |
732 | return false; | |
733 | } | |
e679ec96 GA |
734 | } |
735 | ||
c2ed184f | 736 | // are the actual inputs available? |
13c51f20 | 737 | if (!tx.HaveInputs(view)) |
ef3988ca | 738 | return state.Invalid(error("CTxMemPool::accept() : inputs already spent")); |
13e5cce4 | 739 | |
4afc0b54 PW |
740 | // Bring the best block into scope |
741 | view.GetBestBlock(); | |
742 | ||
743 | // we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool | |
744 | view.SetBackend(dummy); | |
745 | } | |
13c51f20 | 746 | |
922e8e29 | 747 | // Check for non-standard pay-to-script-hash in inputs |
450cbb09 | 748 | if (!tx.AreInputsStandard(view) && !fTestNet) |
d01903e7 | 749 | return error("CTxMemPool::accept() : nonstandard transaction input"); |
e679ec96 | 750 | |
137d0685 GA |
751 | // Note: if you modify this code to accept non-standard transactions, then |
752 | // you should add code here to check that the transaction does a | |
753 | // reasonable number of ECDSA signature verifications. | |
754 | ||
450cbb09 | 755 | int64 nFees = tx.GetValueIn(view)-tx.GetValueOut(); |
c23617fe | 756 | unsigned int nSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); |
8d7849b6 GA |
757 | |
758 | // Don't accept it if it can't get into a block | |
17f8d6e4 | 759 | int64 txMinFee = tx.GetMinFee(1000, true, GMF_RELAY); |
ce99358f | 760 | if (fLimitFree && nFees < txMinFee) |
17f8d6e4 | 761 | return error("CTxMemPool::accept() : not enough fees %s, %"PRI64d" < %"PRI64d, |
b1d3e95a | 762 | hash.ToString().c_str(), |
17f8d6e4 | 763 | nFees, txMinFee); |
922e8e29 | 764 | |
5de8b54c | 765 | // Continuously rate-limit free transactions |
88abf703 | 766 | // This mitigates 'penny-flooding' -- sending thousands of free transactions just to |
b49f1398 | 767 | // be annoying or make others' transactions take longer to confirm. |
000dc551 | 768 | if (fLimitFree && nFees < CTransaction::nMinRelayTxFee) |
97ee01ad | 769 | { |
5de8b54c | 770 | static double dFreeCount; |
bde280b9 WL |
771 | static int64 nLastTime; |
772 | int64 nNow = GetTime(); | |
88abf703 | 773 | |
ce99358f GA |
774 | LOCK(cs); |
775 | ||
776 | // Use an exponentially decaying ~10-minute window: | |
777 | dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime)); | |
778 | nLastTime = nNow; | |
779 | // -limitfreerelay unit is thousand-bytes-per-minute | |
780 | // At default rate it would take over a month to fill 1GB | |
9c9f5c13 | 781 | if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000) |
ce99358f GA |
782 | return error("CTxMemPool::accept() : free transaction rejected by rate limiter"); |
783 | if (fDebug) | |
784 | printf("Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize); | |
785 | dFreeCount += nSize; | |
97ee01ad | 786 | } |
8d7849b6 GA |
787 | |
788 | // Check against previous transactions | |
789 | // This is done last to help prevent CPU exhaustion denial-of-service attacks. | |
20d0810f | 790 | if (!tx.CheckInputs(state, view, true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC)) |
8d7849b6 | 791 | { |
1c06aa98 | 792 | return error("CTxMemPool::accept() : ConnectInputs failed %s", hash.ToString().c_str()); |
8d7849b6 | 793 | } |
0a61b0df | 794 | } |
795 | ||
796 | // Store transaction in memory | |
0a61b0df | 797 | { |
d01903e7 | 798 | LOCK(cs); |
0a61b0df | 799 | if (ptxOld) |
800 | { | |
d01903e7 JG |
801 | printf("CTxMemPool::accept() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str()); |
802 | remove(*ptxOld); | |
0a61b0df | 803 | } |
f77654a0 | 804 | addUnchecked(hash, tx); |
0a61b0df | 805 | } |
806 | ||
807 | ///// are we sure this is ok when loading transactions or restoring block txes | |
808 | // If updated, erase old tx from wallet | |
809 | if (ptxOld) | |
64c7ee7e | 810 | EraseFromWallets(ptxOld->GetHash()); |
35c12d17 | 811 | SyncWithWallets(hash, tx, NULL, true); |
0a61b0df | 812 | |
d210f4f5 | 813 | printf("CTxMemPool::accept() : accepted %s (poolsz %"PRIszu")\n", |
1c06aa98 | 814 | hash.ToString().c_str(), |
133dce6a | 815 | mapTx.size()); |
0a61b0df | 816 | return true; |
817 | } | |
818 | ||
ef3988ca | 819 | bool CTransaction::AcceptToMemoryPool(CValidationState &state, bool fCheckInputs, bool fLimitFree, bool* pfMissingInputs) |
d01903e7 | 820 | { |
421218d3 PW |
821 | try { |
822 | return mempool.accept(state, *this, fCheckInputs, fLimitFree, pfMissingInputs); | |
823 | } catch(std::runtime_error &e) { | |
824 | return state.Abort(_("System error: ") + e.what()); | |
825 | } | |
d01903e7 | 826 | } |
340f0876 | 827 | |
f77654a0 | 828 | bool CTxMemPool::addUnchecked(const uint256& hash, CTransaction &tx) |
0a61b0df | 829 | { |
830 | // Add to memory pool without checking anything. Don't call this directly, | |
d01903e7 | 831 | // call CTxMemPool::accept to properly check the transaction first. |
0a61b0df | 832 | { |
8e45ed66 | 833 | mapTx[hash] = tx; |
c23617fe | 834 | for (unsigned int i = 0; i < tx.vin.size(); i++) |
8e45ed66 | 835 | mapNextTx[tx.vin[i].prevout] = CInPoint(&mapTx[hash], i); |
0a61b0df | 836 | nTransactionsUpdated++; |
837 | } | |
838 | return true; | |
839 | } | |
840 | ||
841 | ||
231b3999 | 842 | bool CTxMemPool::remove(const CTransaction &tx, bool fRecursive) |
0a61b0df | 843 | { |
844 | // Remove transaction from memory pool | |
0a61b0df | 845 | { |
8e45ed66 JG |
846 | LOCK(cs); |
847 | uint256 hash = tx.GetHash(); | |
848 | if (mapTx.count(hash)) | |
74f28bf1 | 849 | { |
231b3999 PW |
850 | if (fRecursive) { |
851 | for (unsigned int i = 0; i < tx.vout.size(); i++) { | |
852 | std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(hash, i)); | |
853 | if (it != mapNextTx.end()) | |
854 | remove(*it->second.ptx, true); | |
855 | } | |
856 | } | |
8e45ed66 | 857 | BOOST_FOREACH(const CTxIn& txin, tx.vin) |
74f28bf1 | 858 | mapNextTx.erase(txin.prevout); |
8e45ed66 | 859 | mapTx.erase(hash); |
74f28bf1 | 860 | nTransactionsUpdated++; |
74f28bf1 | 861 | } |
0a61b0df | 862 | } |
863 | return true; | |
864 | } | |
865 | ||
231b3999 PW |
866 | bool CTxMemPool::removeConflicts(const CTransaction &tx) |
867 | { | |
868 | // Remove transactions which depend on inputs of tx, recursively | |
869 | LOCK(cs); | |
870 | BOOST_FOREACH(const CTxIn &txin, tx.vin) { | |
871 | std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(txin.prevout); | |
872 | if (it != mapNextTx.end()) { | |
873 | const CTransaction &txConflict = *it->second.ptx; | |
874 | if (txConflict != tx) | |
875 | remove(txConflict, true); | |
876 | } | |
877 | } | |
878 | return true; | |
879 | } | |
880 | ||
bdab0cf5 | 881 | void CTxMemPool::clear() |
639b61d7 LD |
882 | { |
883 | LOCK(cs); | |
884 | mapTx.clear(); | |
885 | mapNextTx.clear(); | |
886 | ++nTransactionsUpdated; | |
887 | } | |
888 | ||
25d5c195 JG |
889 | void CTxMemPool::queryHashes(std::vector<uint256>& vtxid) |
890 | { | |
891 | vtxid.clear(); | |
0a61b0df | 892 | |
25d5c195 JG |
893 | LOCK(cs); |
894 | vtxid.reserve(mapTx.size()); | |
895 | for (map<uint256, CTransaction>::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) | |
896 | vtxid.push_back((*mi).first); | |
897 | } | |
0a61b0df | 898 | |
899 | ||
900 | ||
901 | ||
30ab2c9c | 902 | int CMerkleTx::GetDepthInMainChain(CBlockIndex* &pindexRet) const |
0a61b0df | 903 | { |
904 | if (hashBlock == 0 || nIndex == -1) | |
905 | return 0; | |
906 | ||
907 | // Find the block it claims to be in | |
908 | map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); | |
909 | if (mi == mapBlockIndex.end()) | |
910 | return 0; | |
911 | CBlockIndex* pindex = (*mi).second; | |
912 | if (!pindex || !pindex->IsInMainChain()) | |
913 | return 0; | |
914 | ||
915 | // Make sure the merkle branch connects to this block | |
916 | if (!fMerkleVerified) | |
917 | { | |
918 | if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot) | |
919 | return 0; | |
920 | fMerkleVerified = true; | |
921 | } | |
922 | ||
30ab2c9c | 923 | pindexRet = pindex; |
0a61b0df | 924 | return pindexBest->nHeight - pindex->nHeight + 1; |
925 | } | |
926 | ||
927 | ||
928 | int CMerkleTx::GetBlocksToMaturity() const | |
929 | { | |
930 | if (!IsCoinBase()) | |
931 | return 0; | |
932 | return max(0, (COINBASE_MATURITY+20) - GetDepthInMainChain()); | |
933 | } | |
934 | ||
935 | ||
ce99358f | 936 | bool CMerkleTx::AcceptToMemoryPool(bool fCheckInputs, bool fLimitFree) |
0a61b0df | 937 | { |
ef3988ca PW |
938 | CValidationState state; |
939 | return CTransaction::AcceptToMemoryPool(state, fCheckInputs, fLimitFree); | |
0a61b0df | 940 | } |
941 | ||
942 | ||
943 | ||
ae8bfd12 | 944 | bool CWalletTx::AcceptWalletTransaction(bool fCheckInputs) |
0a61b0df | 945 | { |
0a61b0df | 946 | { |
235507ae | 947 | LOCK(mempool.cs); |
f1e1fb4b | 948 | // Add previous supporting transactions first |
223b6f1b | 949 | BOOST_FOREACH(CMerkleTx& tx, vtxPrev) |
0a61b0df | 950 | { |
951 | if (!tx.IsCoinBase()) | |
952 | { | |
953 | uint256 hash = tx.GetHash(); | |
ae8bfd12 | 954 | if (!mempool.exists(hash) && pcoinsTip->HaveCoins(hash)) |
ce99358f | 955 | tx.AcceptToMemoryPool(fCheckInputs, false); |
0a61b0df | 956 | } |
957 | } | |
ce99358f | 958 | return AcceptToMemoryPool(fCheckInputs, false); |
0a61b0df | 959 | } |
f1e1fb4b | 960 | return false; |
0a61b0df | 961 | } |
962 | ||
395c1f44 | 963 | |
c73ba23e | 964 | // Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock |
450cbb09 | 965 | bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow) |
c73ba23e | 966 | { |
450cbb09 | 967 | CBlockIndex *pindexSlow = NULL; |
c73ba23e PW |
968 | { |
969 | LOCK(cs_main); | |
970 | { | |
971 | LOCK(mempool.cs); | |
972 | if (mempool.exists(hash)) | |
973 | { | |
450cbb09 | 974 | txOut = mempool.lookup(hash); |
c73ba23e PW |
975 | return true; |
976 | } | |
977 | } | |
450cbb09 | 978 | |
2d1fa42e PW |
979 | if (fTxIndex) { |
980 | CDiskTxPos postx; | |
981 | if (pblocktree->ReadTxIndex(hash, postx)) { | |
982 | CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION); | |
983 | CBlockHeader header; | |
984 | try { | |
985 | file >> header; | |
986 | fseek(file, postx.nTxOffset, SEEK_CUR); | |
987 | file >> txOut; | |
988 | } catch (std::exception &e) { | |
989 | return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__); | |
990 | } | |
991 | hashBlock = header.GetHash(); | |
992 | if (txOut.GetHash() != hash) | |
993 | return error("%s() : txid mismatch", __PRETTY_FUNCTION__); | |
994 | return true; | |
995 | } | |
996 | } | |
997 | ||
450cbb09 PW |
998 | if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it |
999 | int nHeight = -1; | |
1000 | { | |
ae8bfd12 | 1001 | CCoinsViewCache &view = *pcoinsTip; |
450cbb09 PW |
1002 | CCoins coins; |
1003 | if (view.GetCoins(hash, coins)) | |
1004 | nHeight = coins.nHeight; | |
1005 | } | |
1006 | if (nHeight > 0) | |
1007 | pindexSlow = FindBlockByHeight(nHeight); | |
c73ba23e PW |
1008 | } |
1009 | } | |
0a61b0df | 1010 | |
450cbb09 PW |
1011 | if (pindexSlow) { |
1012 | CBlock block; | |
1013 | if (block.ReadFromDisk(pindexSlow)) { | |
1014 | BOOST_FOREACH(const CTransaction &tx, block.vtx) { | |
1015 | if (tx.GetHash() == hash) { | |
1016 | txOut = tx; | |
1017 | hashBlock = pindexSlow->GetBlockHash(); | |
1018 | return true; | |
1019 | } | |
1020 | } | |
1021 | } | |
1022 | } | |
0a61b0df | 1023 | |
450cbb09 PW |
1024 | return false; |
1025 | } | |
0a61b0df | 1026 | |
1027 | ||
1028 | ||
1029 | ||
1030 | ||
1031 | ||
1032 | ////////////////////////////////////////////////////////////////////////////// | |
1033 | // | |
1034 | // CBlock and CBlockIndex | |
1035 | // | |
1036 | ||
1be06419 LD |
1037 | static CBlockIndex* pblockindexFBBHLast; |
1038 | CBlockIndex* FindBlockByHeight(int nHeight) | |
1039 | { | |
0fe8010a PW |
1040 | if (nHeight >= (int)vBlockIndexByHeight.size()) |
1041 | return NULL; | |
1042 | return vBlockIndexByHeight[nHeight]; | |
1be06419 LD |
1043 | } |
1044 | ||
e754cf41 | 1045 | bool CBlock::ReadFromDisk(const CBlockIndex* pindex) |
0a61b0df | 1046 | { |
e754cf41 | 1047 | if (!ReadFromDisk(pindex->GetBlockPos())) |
0a61b0df | 1048 | return false; |
1049 | if (GetHash() != pindex->GetBlockHash()) | |
1050 | return error("CBlock::ReadFromDisk() : GetHash() doesn't match index"); | |
1051 | return true; | |
1052 | } | |
1053 | ||
e754cf41 | 1054 | uint256 static GetOrphanRoot(const CBlockHeader* pblock) |
0a61b0df | 1055 | { |
1056 | // Work back to the first block in the orphan chain | |
1057 | while (mapOrphanBlocks.count(pblock->hashPrevBlock)) | |
1058 | pblock = mapOrphanBlocks[pblock->hashPrevBlock]; | |
1059 | return pblock->GetHash(); | |
1060 | } | |
1061 | ||
bde280b9 | 1062 | int64 static GetBlockValue(int nHeight, int64 nFees) |
0a61b0df | 1063 | { |
bde280b9 | 1064 | int64 nSubsidy = 50 * COIN; |
0a61b0df | 1065 | |
5f2e4b05 | 1066 | // Subsidy is cut in half every 210000 blocks, which will occur approximately every 4 years |
0a61b0df | 1067 | nSubsidy >>= (nHeight / 210000); |
1068 | ||
1069 | return nSubsidy + nFees; | |
1070 | } | |
1071 | ||
bde280b9 WL |
1072 | static const int64 nTargetTimespan = 14 * 24 * 60 * 60; // two weeks |
1073 | static const int64 nTargetSpacing = 10 * 60; | |
1074 | static const int64 nInterval = nTargetTimespan / nTargetSpacing; | |
10fd7f66 GA |
1075 | |
1076 | // | |
1077 | // minimum amount of work that could possibly be required nTime after | |
1078 | // minimum work required was nBase | |
1079 | // | |
bde280b9 | 1080 | unsigned int ComputeMinWork(unsigned int nBase, int64 nTime) |
10fd7f66 | 1081 | { |
c52296a7 GA |
1082 | // Testnet has min-difficulty blocks |
1083 | // after nTargetSpacing*2 time between blocks: | |
1084 | if (fTestNet && nTime > nTargetSpacing*2) | |
1085 | return bnProofOfWorkLimit.GetCompact(); | |
1086 | ||
10fd7f66 GA |
1087 | CBigNum bnResult; |
1088 | bnResult.SetCompact(nBase); | |
1089 | while (nTime > 0 && bnResult < bnProofOfWorkLimit) | |
1090 | { | |
1091 | // Maximum 400% adjustment... | |
1092 | bnResult *= 4; | |
1093 | // ... in best-case exactly 4-times-normal target time | |
1094 | nTime -= nTargetTimespan*4; | |
1095 | } | |
1096 | if (bnResult > bnProofOfWorkLimit) | |
1097 | bnResult = bnProofOfWorkLimit; | |
1098 | return bnResult.GetCompact(); | |
1099 | } | |
1100 | ||
e754cf41 | 1101 | unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock) |
0a61b0df | 1102 | { |
c52296a7 | 1103 | unsigned int nProofOfWorkLimit = bnProofOfWorkLimit.GetCompact(); |
0a61b0df | 1104 | |
1105 | // Genesis block | |
1106 | if (pindexLast == NULL) | |
c52296a7 | 1107 | return nProofOfWorkLimit; |
0a61b0df | 1108 | |
1109 | // Only change once per interval | |
1110 | if ((pindexLast->nHeight+1) % nInterval != 0) | |
c52296a7 | 1111 | { |
248bceb3 GA |
1112 | // Special difficulty rule for testnet: |
1113 | if (fTestNet) | |
c52296a7 GA |
1114 | { |
1115 | // If the new block's timestamp is more than 2* 10 minutes | |
1116 | // then allow mining of a min-difficulty block. | |
248bceb3 | 1117 | if (pblock->nTime > pindexLast->nTime + nTargetSpacing*2) |
c52296a7 GA |
1118 | return nProofOfWorkLimit; |
1119 | else | |
1120 | { | |
1121 | // Return the last non-special-min-difficulty-rules-block | |
1122 | const CBlockIndex* pindex = pindexLast; | |
1123 | while (pindex->pprev && pindex->nHeight % nInterval != 0 && pindex->nBits == nProofOfWorkLimit) | |
1124 | pindex = pindex->pprev; | |
1125 | return pindex->nBits; | |
1126 | } | |
1127 | } | |
1128 | ||
0a61b0df | 1129 | return pindexLast->nBits; |
c52296a7 | 1130 | } |
0a61b0df | 1131 | |
1132 | // Go back by what we want to be 14 days worth of blocks | |
1133 | const CBlockIndex* pindexFirst = pindexLast; | |
1134 | for (int i = 0; pindexFirst && i < nInterval-1; i++) | |
1135 | pindexFirst = pindexFirst->pprev; | |
1136 | assert(pindexFirst); | |
1137 | ||
1138 | // Limit adjustment step | |
bde280b9 | 1139 | int64 nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime(); |
0a61b0df | 1140 | printf(" nActualTimespan = %"PRI64d" before bounds\n", nActualTimespan); |
1141 | if (nActualTimespan < nTargetTimespan/4) | |
1142 | nActualTimespan = nTargetTimespan/4; | |
1143 | if (nActualTimespan > nTargetTimespan*4) | |
1144 | nActualTimespan = nTargetTimespan*4; | |
1145 | ||
1146 | // Retarget | |
1147 | CBigNum bnNew; | |
1148 | bnNew.SetCompact(pindexLast->nBits); | |
1149 | bnNew *= nActualTimespan; | |
1150 | bnNew /= nTargetTimespan; | |
1151 | ||
1152 | if (bnNew > bnProofOfWorkLimit) | |
1153 | bnNew = bnProofOfWorkLimit; | |
1154 | ||
1155 | /// debug print | |
1156 | printf("GetNextWorkRequired RETARGET\n"); | |
1157 | printf("nTargetTimespan = %"PRI64d" nActualTimespan = %"PRI64d"\n", nTargetTimespan, nActualTimespan); | |
1158 | printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str()); | |
1159 | printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str()); | |
1160 | ||
1161 | return bnNew.GetCompact(); | |
1162 | } | |
1163 | ||
1164 | bool CheckProofOfWork(uint256 hash, unsigned int nBits) | |
1165 | { | |
1166 | CBigNum bnTarget; | |
1167 | bnTarget.SetCompact(nBits); | |
1168 | ||
1169 | // Check range | |
1170 | if (bnTarget <= 0 || bnTarget > bnProofOfWorkLimit) | |
1171 | return error("CheckProofOfWork() : nBits below minimum work"); | |
1172 | ||
1173 | // Check proof of work matches claimed amount | |
1174 | if (hash > bnTarget.getuint256()) | |
1175 | return error("CheckProofOfWork() : hash doesn't match nBits"); | |
1176 | ||
1177 | return true; | |
1178 | } | |
1179 | ||
c5aa1b13 | 1180 | // Return maximum amount of blocks that other nodes claim to have |
d33cc2b5 | 1181 | int GetNumBlocksOfPeers() |
c5aa1b13 | 1182 | { |
eb5fff9e | 1183 | return std::max(cPeerBlockCounts.median(), Checkpoints::GetTotalBlocksEstimate()); |
c5aa1b13 WL |
1184 | } |
1185 | ||
0a61b0df | 1186 | bool IsInitialBlockDownload() |
1187 | { | |
69e07747 | 1188 | if (pindexBest == NULL || fImporting || fReindex || nBestHeight < Checkpoints::GetTotalBlocksEstimate()) |
0a61b0df | 1189 | return true; |
bde280b9 | 1190 | static int64 nLastUpdate; |
0a61b0df | 1191 | static CBlockIndex* pindexLastBest; |
1192 | if (pindexBest != pindexLastBest) | |
1193 | { | |
1194 | pindexLastBest = pindexBest; | |
1195 | nLastUpdate = GetTime(); | |
1196 | } | |
1197 | return (GetTime() - nLastUpdate < 10 && | |
1198 | pindexBest->GetBlockTime() < GetTime() - 24 * 60 * 60); | |
1199 | } | |
1200 | ||
64c7ee7e | 1201 | void static InvalidChainFound(CBlockIndex* pindexNew) |
0a61b0df | 1202 | { |
1657c4bc | 1203 | if (pindexNew->nChainWork > nBestInvalidWork) |
0a61b0df | 1204 | { |
1657c4bc PW |
1205 | nBestInvalidWork = pindexNew->nChainWork; |
1206 | pblocktree->WriteBestInvalidWork(CBigNum(nBestInvalidWork)); | |
ab1b288f | 1207 | uiInterface.NotifyBlocksChanged(); |
0a61b0df | 1208 | } |
1657c4bc | 1209 | printf("InvalidChainFound: invalid block=%s height=%d log2_work=%.8g date=%s\n", |
1c06aa98 | 1210 | pindexNew->GetBlockHash().ToString().c_str(), pindexNew->nHeight, |
1657c4bc | 1211 | log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", |
e69a7979 | 1212 | pindexNew->GetBlockTime()).c_str()); |
1657c4bc PW |
1213 | printf("InvalidChainFound: current best=%s height=%d log2_work=%.8g date=%s\n", |
1214 | hashBestChain.ToString().c_str(), nBestHeight, log(nBestChainWork.getdouble())/log(2.0), | |
3f964b3c | 1215 | DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexBest->GetBlockTime()).c_str()); |
1657c4bc | 1216 | if (pindexBest && nBestInvalidWork > nBestChainWork + (pindexBest->GetBlockWork() * 6).getuint256()) |
e6bc9c35 | 1217 | printf("InvalidChainFound: Warning: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.\n"); |
0a61b0df | 1218 | } |
1219 | ||
857c61df PW |
1220 | void static InvalidBlockFound(CBlockIndex *pindex) { |
1221 | pindex->nStatus |= BLOCK_FAILED_VALID; | |
d979e6e3 | 1222 | pblocktree->WriteBlockIndex(CDiskBlockIndex(pindex)); |
857c61df PW |
1223 | setBlockIndexValid.erase(pindex); |
1224 | InvalidChainFound(pindex); | |
0fe8010a | 1225 | if (pindex->GetNextInMainChain()) { |
ef3988ca PW |
1226 | CValidationState stateDummy; |
1227 | ConnectBestBlock(stateDummy); // reorganise away from the failed block | |
1228 | } | |
857c61df PW |
1229 | } |
1230 | ||
ef3988ca | 1231 | bool ConnectBestBlock(CValidationState &state) { |
857c61df PW |
1232 | do { |
1233 | CBlockIndex *pindexNewBest; | |
1234 | ||
1235 | { | |
1236 | std::set<CBlockIndex*,CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexValid.rbegin(); | |
1237 | if (it == setBlockIndexValid.rend()) | |
1238 | return true; | |
1239 | pindexNewBest = *it; | |
1240 | } | |
1241 | ||
1657c4bc | 1242 | if (pindexNewBest == pindexBest || (pindexBest && pindexNewBest->nChainWork == pindexBest->nChainWork)) |
857c61df PW |
1243 | return true; // nothing to do |
1244 | ||
1245 | // check ancestry | |
1246 | CBlockIndex *pindexTest = pindexNewBest; | |
1247 | std::vector<CBlockIndex*> vAttach; | |
1248 | do { | |
1249 | if (pindexTest->nStatus & BLOCK_FAILED_MASK) { | |
1250 | // mark descendants failed | |
857c61df PW |
1251 | CBlockIndex *pindexFailed = pindexNewBest; |
1252 | while (pindexTest != pindexFailed) { | |
1253 | pindexFailed->nStatus |= BLOCK_FAILED_CHILD; | |
1254 | setBlockIndexValid.erase(pindexFailed); | |
d979e6e3 | 1255 | pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexFailed)); |
857c61df PW |
1256 | pindexFailed = pindexFailed->pprev; |
1257 | } | |
1258 | InvalidChainFound(pindexNewBest); | |
1259 | break; | |
1260 | } | |
1261 | ||
1657c4bc | 1262 | if (pindexBest == NULL || pindexTest->nChainWork > pindexBest->nChainWork) |
857c61df PW |
1263 | vAttach.push_back(pindexTest); |
1264 | ||
0fe8010a | 1265 | if (pindexTest->pprev == NULL || pindexTest->GetNextInMainChain()) { |
857c61df | 1266 | reverse(vAttach.begin(), vAttach.end()); |
3fb9b99c | 1267 | BOOST_FOREACH(CBlockIndex *pindexSwitch, vAttach) { |
b31499ec | 1268 | boost::this_thread::interruption_point(); |
421218d3 PW |
1269 | try { |
1270 | if (!SetBestChain(state, pindexSwitch)) | |
1271 | return false; | |
1272 | } catch(std::runtime_error &e) { | |
1273 | return state.Abort(_("System error: ") + e.what()); | |
1274 | } | |
3fb9b99c | 1275 | } |
857c61df PW |
1276 | return true; |
1277 | } | |
1278 | pindexTest = pindexTest->pprev; | |
1279 | } while(true); | |
1280 | } while(true); | |
1281 | } | |
1282 | ||
e754cf41 | 1283 | void CBlockHeader::UpdateTime(const CBlockIndex* pindexPrev) |
0f8cb5db GA |
1284 | { |
1285 | nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); | |
1286 | ||
1287 | // Updating time can change work required on testnet: | |
1288 | if (fTestNet) | |
1289 | nBits = GetNextWorkRequired(pindexPrev, this); | |
1290 | } | |
1291 | ||
0a61b0df | 1292 | |
1293 | ||
1294 | ||
1295 | ||
1296 | ||
1297 | ||
1298 | ||
1299 | ||
1300 | ||
1301 | ||
13c51f20 | 1302 | const CTxOut &CTransaction::GetOutputFor(const CTxIn& input, CCoinsViewCache& view) |
e679ec96 | 1303 | { |
13c51f20 PW |
1304 | const CCoins &coins = view.GetCoins(input.prevout.hash); |
1305 | assert(coins.IsAvailable(input.prevout.n)); | |
1306 | return coins.vout[input.prevout.n]; | |
8d7849b6 GA |
1307 | } |
1308 | ||
13c51f20 | 1309 | int64 CTransaction::GetValueIn(CCoinsViewCache& inputs) const |
8d7849b6 GA |
1310 | { |
1311 | if (IsCoinBase()) | |
1312 | return 0; | |
1313 | ||
1314 | int64 nResult = 0; | |
c376ac35 | 1315 | for (unsigned int i = 0; i < vin.size(); i++) |
8d7849b6 | 1316 | nResult += GetOutputFor(vin[i], inputs).nValue; |
8d7849b6 | 1317 | |
450cbb09 | 1318 | return nResult; |
8d7849b6 GA |
1319 | } |
1320 | ||
13c51f20 | 1321 | unsigned int CTransaction::GetP2SHSigOpCount(CCoinsViewCache& inputs) const |
8d7849b6 GA |
1322 | { |
1323 | if (IsCoinBase()) | |
1324 | return 0; | |
1325 | ||
7bd9c3a3 | 1326 | unsigned int nSigOps = 0; |
c376ac35 | 1327 | for (unsigned int i = 0; i < vin.size(); i++) |
8d7849b6 | 1328 | { |
13c51f20 | 1329 | const CTxOut &prevout = GetOutputFor(vin[i], inputs); |
137d0685 GA |
1330 | if (prevout.scriptPubKey.IsPayToScriptHash()) |
1331 | nSigOps += prevout.scriptPubKey.GetSigOpCount(vin[i].scriptSig); | |
8d7849b6 GA |
1332 | } |
1333 | return nSigOps; | |
1334 | } | |
1335 | ||
2ec349bc | 1336 | void CTransaction::UpdateCoins(CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight, const uint256 &txhash) const |
450cbb09 | 1337 | { |
450cbb09 PW |
1338 | // mark inputs spent |
1339 | if (!IsCoinBase()) { | |
1340 | BOOST_FOREACH(const CTxIn &txin, vin) { | |
13c51f20 | 1341 | CCoins &coins = inputs.GetCoins(txin.prevout.hash); |
450cbb09 | 1342 | CTxInUndo undo; |
ef3988ca | 1343 | assert(coins.Spend(txin.prevout, undo)); |
450cbb09 | 1344 | txundo.vprevout.push_back(undo); |
450cbb09 PW |
1345 | } |
1346 | } | |
1347 | ||
1348 | // add outputs | |
ef3988ca | 1349 | assert(inputs.SetCoins(txhash, CCoins(*this, nHeight))); |
450cbb09 PW |
1350 | } |
1351 | ||
13c51f20 | 1352 | bool CTransaction::HaveInputs(CCoinsViewCache &inputs) const |
450cbb09 | 1353 | { |
729b1806 | 1354 | if (!IsCoinBase()) { |
450cbb09 PW |
1355 | // first check whether information about the prevout hash is available |
1356 | for (unsigned int i = 0; i < vin.size(); i++) { | |
1357 | const COutPoint &prevout = vin[i].prevout; | |
1358 | if (!inputs.HaveCoins(prevout.hash)) | |
1359 | return false; | |
1360 | } | |
1361 | ||
1362 | // then check whether the actual outputs are available | |
1363 | for (unsigned int i = 0; i < vin.size(); i++) { | |
1364 | const COutPoint &prevout = vin[i].prevout; | |
13c51f20 | 1365 | const CCoins &coins = inputs.GetCoins(prevout.hash); |
450cbb09 PW |
1366 | if (!coins.IsAvailable(prevout.n)) |
1367 | return false; | |
1368 | } | |
1369 | } | |
1370 | return true; | |
1371 | } | |
1372 | ||
2800ce73 PW |
1373 | bool CScriptCheck::operator()() const { |
1374 | const CScript &scriptSig = ptxTo->vin[nIn].scriptSig; | |
1375 | if (!VerifyScript(scriptSig, scriptPubKey, *ptxTo, nIn, nFlags, nHashType)) | |
1c06aa98 | 1376 | return error("CScriptCheck() : %s VerifySignature failed", ptxTo->GetHash().ToString().c_str()); |
2800ce73 PW |
1377 | return true; |
1378 | } | |
1379 | ||
f1136200 PW |
1380 | bool VerifySignature(const CCoins& txFrom, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType) |
1381 | { | |
2800ce73 | 1382 | return CScriptCheck(txFrom, txTo, nIn, flags, nHashType)(); |
f1136200 PW |
1383 | } |
1384 | ||
ef3988ca | 1385 | bool CTransaction::CheckInputs(CValidationState &state, CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, std::vector<CScriptCheck> *pvChecks) const |
0a61b0df | 1386 | { |
0a61b0df | 1387 | if (!IsCoinBase()) |
1388 | { | |
f9cae832 PW |
1389 | if (pvChecks) |
1390 | pvChecks->reserve(vin.size()); | |
1391 | ||
13c51f20 PW |
1392 | // This doesn't trigger the DoS code on purpose; if it did, it would make it easier |
1393 | // for an attacker to attempt to split the network. | |
1394 | if (!HaveInputs(inputs)) | |
1c06aa98 | 1395 | return state.Invalid(error("CheckInputs() : %s inputs unavailable", GetHash().ToString().c_str())); |
13c51f20 | 1396 | |
56424040 PW |
1397 | // While checking, GetBestBlock() refers to the parent block. |
1398 | // This is also true for mempool checks. | |
13e5cce4 | 1399 | int nSpendHeight = inputs.GetBestBlock()->nHeight + 1; |
bde280b9 | 1400 | int64 nValueIn = 0; |
8d7849b6 | 1401 | int64 nFees = 0; |
c376ac35 | 1402 | for (unsigned int i = 0; i < vin.size(); i++) |
0a61b0df | 1403 | { |
450cbb09 | 1404 | const COutPoint &prevout = vin[i].prevout; |
13c51f20 | 1405 | const CCoins &coins = inputs.GetCoins(prevout.hash); |
0a61b0df | 1406 | |
1407 | // If prev is coinbase, check that it's matured | |
450cbb09 | 1408 | if (coins.IsCoinBase()) { |
56424040 | 1409 | if (nSpendHeight - coins.nHeight < COINBASE_MATURITY) |
ef3988ca | 1410 | return state.Invalid(error("CheckInputs() : tried to spend coinbase at depth %d", nSpendHeight - coins.nHeight)); |
450cbb09 | 1411 | } |
0a61b0df | 1412 | |
4add41a2 | 1413 | // Check for negative or overflow input values |
450cbb09 PW |
1414 | nValueIn += coins.vout[prevout.n].nValue; |
1415 | if (!MoneyRange(coins.vout[prevout.n].nValue) || !MoneyRange(nValueIn)) | |
ef3988ca | 1416 | return state.DoS(100, error("CheckInputs() : txin values out of range")); |
4add41a2 GA |
1417 | |
1418 | } | |
450cbb09 PW |
1419 | |
1420 | if (nValueIn < GetValueOut()) | |
1c06aa98 | 1421 | return state.DoS(100, error("CheckInputs() : %s value in < value out", GetHash().ToString().c_str())); |
450cbb09 PW |
1422 | |
1423 | // Tally transaction fees | |
1424 | int64 nTxFee = nValueIn - GetValueOut(); | |
1425 | if (nTxFee < 0) | |
1c06aa98 | 1426 | return state.DoS(100, error("CheckInputs() : %s nTxFee < 0", GetHash().ToString().c_str())); |
450cbb09 PW |
1427 | nFees += nTxFee; |
1428 | if (!MoneyRange(nFees)) | |
ef3988ca | 1429 | return state.DoS(100, error("CheckInputs() : nFees out of range")); |
450cbb09 | 1430 | |
4add41a2 GA |
1431 | // The first loop above does all the inexpensive checks. |
1432 | // Only if ALL inputs pass do we perform expensive ECDSA signature checks. | |
1433 | // Helps prevent CPU exhaustion attacks. | |
4add41a2 | 1434 | |
450cbb09 | 1435 | // Skip ECDSA signature verification when connecting blocks |
729b1806 | 1436 | // before the last block chain checkpoint. This is safe because block merkle hashes are |
450cbb09 | 1437 | // still computed and checked, and any change will be caught at the next checkpoint. |
1d70f4bd | 1438 | if (fScriptChecks) { |
450cbb09 PW |
1439 | for (unsigned int i = 0; i < vin.size(); i++) { |
1440 | const COutPoint &prevout = vin[i].prevout; | |
13c51f20 | 1441 | const CCoins &coins = inputs.GetCoins(prevout.hash); |
8d7849b6 | 1442 | |
b14bd4df | 1443 | // Verify signature |
f9cae832 PW |
1444 | CScriptCheck check(coins, *this, i, flags, 0); |
1445 | if (pvChecks) { | |
1446 | pvChecks->push_back(CScriptCheck()); | |
1447 | check.swap(pvChecks->back()); | |
97e7901a PW |
1448 | } else if (!check()) { |
1449 | if (flags & SCRIPT_VERIFY_STRICTENC) { | |
1450 | // For now, check whether the failure was caused by non-canonical | |
1451 | // encodings or not; if so, don't trigger DoS protection. | |
1452 | CScriptCheck check(coins, *this, i, flags & (~SCRIPT_VERIFY_STRICTENC), 0); | |
1453 | if (check()) | |
1454 | return state.Invalid(); | |
1455 | } | |
ef3988ca | 1456 | return state.DoS(100,false); |
97e7901a | 1457 | } |
2a45a494 | 1458 | } |
0a61b0df | 1459 | } |
0a61b0df | 1460 | } |
1461 | ||
0a61b0df | 1462 | return true; |
1463 | } | |
1464 | ||
1465 | ||
0a61b0df | 1466 | |
1467 | ||
ef3988ca | 1468 | bool CBlock::DisconnectBlock(CValidationState &state, CBlockIndex *pindex, CCoinsViewCache &view, bool *pfClean) |
0a61b0df | 1469 | { |
450cbb09 | 1470 | assert(pindex == view.GetBestBlock()); |
0a61b0df | 1471 | |
2cbd71da PW |
1472 | if (pfClean) |
1473 | *pfClean = false; | |
1474 | ||
1475 | bool fClean = true; | |
1476 | ||
450cbb09 | 1477 | CBlockUndo blockUndo; |
8539361e PW |
1478 | CDiskBlockPos pos = pindex->GetUndoPos(); |
1479 | if (pos.IsNull()) | |
1480 | return error("DisconnectBlock() : no undo data available"); | |
1481 | if (!blockUndo.ReadFromDisk(pos, pindex->pprev->GetBlockHash())) | |
1482 | return error("DisconnectBlock() : failure reading undo data"); | |
0a61b0df | 1483 | |
2cbd71da PW |
1484 | if (blockUndo.vtxundo.size() + 1 != vtx.size()) |
1485 | return error("DisconnectBlock() : block and undo data inconsistent"); | |
450cbb09 PW |
1486 | |
1487 | // undo transactions in reverse order | |
1488 | for (int i = vtx.size() - 1; i >= 0; i--) { | |
1489 | const CTransaction &tx = vtx[i]; | |
1490 | uint256 hash = tx.GetHash(); | |
1491 | ||
1492 | // check that all outputs are available | |
2cbd71da PW |
1493 | if (!view.HaveCoins(hash)) { |
1494 | fClean = fClean && error("DisconnectBlock() : outputs still spent? database corrupted"); | |
1495 | view.SetCoins(hash, CCoins()); | |
1496 | } | |
13c51f20 | 1497 | CCoins &outs = view.GetCoins(hash); |
450cbb09 PW |
1498 | |
1499 | CCoins outsBlock = CCoins(tx, pindex->nHeight); | |
1500 | if (outs != outsBlock) | |
2cbd71da | 1501 | fClean = fClean && error("DisconnectBlock() : added transaction mismatch? database corrupted"); |
450cbb09 PW |
1502 | |
1503 | // remove outputs | |
13c51f20 | 1504 | outs = CCoins(); |
450cbb09 PW |
1505 | |
1506 | // restore inputs | |
1507 | if (i > 0) { // not coinbases | |
1508 | const CTxUndo &txundo = blockUndo.vtxundo[i-1]; | |
2cbd71da PW |
1509 | if (txundo.vprevout.size() != tx.vin.size()) |
1510 | return error("DisconnectBlock() : transaction and undo data inconsistent"); | |
450cbb09 PW |
1511 | for (unsigned int j = tx.vin.size(); j-- > 0;) { |
1512 | const COutPoint &out = tx.vin[j].prevout; | |
1513 | const CTxInUndo &undo = txundo.vprevout[j]; | |
1514 | CCoins coins; | |
1515 | view.GetCoins(out.hash, coins); // this can fail if the prevout was already entirely spent | |
2cbd71da PW |
1516 | if (undo.nHeight != 0) { |
1517 | // undo data contains height: this is the last output of the prevout tx being spent | |
1518 | if (!coins.IsPruned()) | |
1519 | fClean = fClean && error("DisconnectBlock() : undo data overwriting existing transaction"); | |
1520 | coins = CCoins(); | |
450cbb09 PW |
1521 | coins.fCoinBase = undo.fCoinBase; |
1522 | coins.nHeight = undo.nHeight; | |
1523 | coins.nVersion = undo.nVersion; | |
1524 | } else { | |
2cbd71da PW |
1525 | if (coins.IsPruned()) |
1526 | fClean = fClean && error("DisconnectBlock() : undo data adding output to missing transaction"); | |
450cbb09 PW |
1527 | } |
1528 | if (coins.IsAvailable(out.n)) | |
2cbd71da | 1529 | fClean = fClean && error("DisconnectBlock() : undo data overwriting existing output"); |
450cbb09 PW |
1530 | if (coins.vout.size() < out.n+1) |
1531 | coins.vout.resize(out.n+1); | |
1532 | coins.vout[out.n] = undo.txout; | |
1533 | if (!view.SetCoins(out.hash, coins)) | |
1534 | return error("DisconnectBlock() : cannot restore coin inputs"); | |
1535 | } | |
1536 | } | |
1537 | } | |
1538 | ||
1539 | // move best block pointer to prevout block | |
1540 | view.SetBestBlock(pindex->pprev); | |
1541 | ||
2cbd71da PW |
1542 | if (pfClean) { |
1543 | *pfClean = fClean; | |
1544 | return true; | |
1545 | } else { | |
1546 | return fClean; | |
1547 | } | |
0a61b0df | 1548 | } |
1549 | ||
1eb57879 | 1550 | void static FlushBlockFile(bool fFinalize = false) |
44d40f26 PW |
1551 | { |
1552 | LOCK(cs_LastBlockFile); | |
1553 | ||
a8a4b967 | 1554 | CDiskBlockPos posOld(nLastBlockFile, 0); |
44d40f26 PW |
1555 | |
1556 | FILE *fileOld = OpenBlockFile(posOld); | |
b19388dd | 1557 | if (fileOld) { |
1eb57879 PW |
1558 | if (fFinalize) |
1559 | TruncateFile(fileOld, infoLastBlockFile.nSize); | |
b19388dd PK |
1560 | FileCommit(fileOld); |
1561 | fclose(fileOld); | |
1562 | } | |
44d40f26 PW |
1563 | |
1564 | fileOld = OpenUndoFile(posOld); | |
b19388dd | 1565 | if (fileOld) { |
1eb57879 PW |
1566 | if (fFinalize) |
1567 | TruncateFile(fileOld, infoLastBlockFile.nUndoSize); | |
b19388dd PK |
1568 | FileCommit(fileOld); |
1569 | fclose(fileOld); | |
1570 | } | |
44d40f26 PW |
1571 | } |
1572 | ||
ef3988ca | 1573 | bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize); |
5382bcf8 | 1574 | |
f9cae832 PW |
1575 | static CCheckQueue<CScriptCheck> scriptcheckqueue(128); |
1576 | ||
21eb5ada | 1577 | void ThreadScriptCheck() { |
f9cae832 PW |
1578 | RenameThread("bitcoin-scriptch"); |
1579 | scriptcheckqueue.Thread(); | |
f9cae832 PW |
1580 | } |
1581 | ||
ef3988ca | 1582 | bool CBlock::ConnectBlock(CValidationState &state, CBlockIndex* pindex, CCoinsViewCache &view, bool fJustCheck) |
0a61b0df | 1583 | { |
1584 | // Check it again in case a previous version let a bad block in | |
ef3988ca | 1585 | if (!CheckBlock(state, !fJustCheck, !fJustCheck)) |
0a61b0df | 1586 | return false; |
1587 | ||
450cbb09 PW |
1588 | // verify that the view's current state corresponds to the previous block |
1589 | assert(pindex->pprev == view.GetBestBlock()); | |
1590 | ||
8301ff50 PW |
1591 | // Special case for the genesis block, skipping connection of its transactions |
1592 | // (its coinbase is unspendable) | |
1593 | if (GetHash() == hashGenesisBlock) { | |
1594 | view.SetBestBlock(pindex); | |
1595 | pindexGenesisBlock = pindex; | |
1596 | return true; | |
1597 | } | |
1598 | ||
1d70f4bd PW |
1599 | bool fScriptChecks = pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate(); |
1600 | ||
a206b0ea PW |
1601 | // Do not allow blocks that contain transactions which 'overwrite' older transactions, |
1602 | // unless those are already completely spent. | |
1603 | // If such overwrites are allowed, coinbases and transactions depending upon those | |
1604 | // can be duplicated to remove the ability to spend the first instance -- even after | |
1605 | // being sent to another address. | |
1606 | // See BIP30 and http://r6.ca/blog/20120206T005236Z.html for more information. | |
1607 | // This logic is not necessary for memory pool transactions, as AcceptToMemoryPool | |
b49f1398 | 1608 | // already refuses previously-known transaction ids entirely. |
ab91bf39 GM |
1609 | // This rule was originally applied all blocks whose timestamp was after March 15, 2012, 0:00 UTC. |
1610 | // Now that the whole chain is irreversibly beyond that time it is applied to all blocks except the | |
1611 | // two in the chain that violate it. This prevents exploiting the issue against nodes in their | |
1612 | // initial block download. | |
faff50d1 GM |
1613 | bool fEnforceBIP30 = (!pindex->phashBlock) || // Enforce on CreateNewBlock invocations which don't have a hash. |
1614 | !((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) || | |
ab91bf39 | 1615 | (pindex->nHeight==91880 && pindex->GetBlockHash() == uint256("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721"))); |
450cbb09 | 1616 | if (fEnforceBIP30) { |
64dd46fd PW |
1617 | for (unsigned int i=0; i<vtx.size(); i++) { |
1618 | uint256 hash = GetTxHash(i); | |
13c51f20 | 1619 | if (view.HaveCoins(hash) && !view.GetCoins(hash).IsPruned()) |
7cdc37c0 | 1620 | return state.DoS(100, error("ConnectBlock() : tried to overwrite transaction")); |
450cbb09 PW |
1621 | } |
1622 | } | |
a206b0ea | 1623 | |
e6332751 GM |
1624 | // BIP16 didn't become active until Apr 1 2012 |
1625 | int64 nBIP16SwitchTime = 1333238400; | |
8f188ece | 1626 | bool fStrictPayToScriptHash = (pindex->nTime >= nBIP16SwitchTime); |
137d0685 | 1627 | |
ef0f4225 PW |
1628 | unsigned int flags = SCRIPT_VERIFY_NOCACHE | |
1629 | (fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE); | |
1630 | ||
8adf48dc PW |
1631 | CBlockUndo blockundo; |
1632 | ||
f9cae832 PW |
1633 | CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL); |
1634 | ||
8a28bb6d | 1635 | int64 nStart = GetTimeMicros(); |
bde280b9 | 1636 | int64 nFees = 0; |
8a28bb6d | 1637 | int nInputs = 0; |
7bd9c3a3 | 1638 | unsigned int nSigOps = 0; |
2d1fa42e PW |
1639 | CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(vtx.size())); |
1640 | std::vector<std::pair<uint256, CDiskTxPos> > vPos; | |
1641 | vPos.reserve(vtx.size()); | |
64dd46fd | 1642 | for (unsigned int i=0; i<vtx.size(); i++) |
0a61b0df | 1643 | { |
64dd46fd PW |
1644 | const CTransaction &tx = vtx[i]; |
1645 | ||
8a28bb6d | 1646 | nInputs += tx.vin.size(); |
137d0685 GA |
1647 | nSigOps += tx.GetLegacySigOpCount(); |
1648 | if (nSigOps > MAX_BLOCK_SIGOPS) | |
ef3988ca | 1649 | return state.DoS(100, error("ConnectBlock() : too many sigops")); |
137d0685 | 1650 | |
8d7849b6 GA |
1651 | if (!tx.IsCoinBase()) |
1652 | { | |
450cbb09 | 1653 | if (!tx.HaveInputs(view)) |
ef3988ca | 1654 | return state.DoS(100, error("ConnectBlock() : inputs missing/spent")); |
922e8e29 | 1655 | |
137d0685 GA |
1656 | if (fStrictPayToScriptHash) |
1657 | { | |
1658 | // Add in sigops done by pay-to-script-hash inputs; | |
1659 | // this is to prevent a "rogue miner" from creating | |
1660 | // an incredibly-expensive-to-validate block. | |
450cbb09 | 1661 | nSigOps += tx.GetP2SHSigOpCount(view); |
137d0685 | 1662 | if (nSigOps > MAX_BLOCK_SIGOPS) |
ef3988ca | 1663 | return state.DoS(100, error("ConnectBlock() : too many sigops")); |
137d0685 | 1664 | } |
922e8e29 | 1665 | |
450cbb09 | 1666 | nFees += tx.GetValueIn(view)-tx.GetValueOut(); |
8adf48dc | 1667 | |
f9cae832 | 1668 | std::vector<CScriptCheck> vChecks; |
ef3988ca | 1669 | if (!tx.CheckInputs(state, view, fScriptChecks, flags, nScriptCheckThreads ? &vChecks : NULL)) |
40634605 | 1670 | return false; |
f9cae832 | 1671 | control.Add(vChecks); |
8d7849b6 GA |
1672 | } |
1673 | ||
450cbb09 | 1674 | CTxUndo txundo; |
2ec349bc | 1675 | tx.UpdateCoins(state, view, txundo, pindex->nHeight, GetTxHash(i)); |
450cbb09 PW |
1676 | if (!tx.IsCoinBase()) |
1677 | blockundo.vtxundo.push_back(txundo); | |
8a28bb6d | 1678 | |
2d1fa42e PW |
1679 | vPos.push_back(std::make_pair(GetTxHash(i), pos)); |
1680 | pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); | |
0a61b0df | 1681 | } |
8a28bb6d PW |
1682 | int64 nTime = GetTimeMicros() - nStart; |
1683 | if (fBenchmark) | |
1684 | printf("- Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin)\n", (unsigned)vtx.size(), 0.001 * nTime, 0.001 * nTime / vtx.size(), nInputs <= 1 ? 0 : 0.001 * nTime / (nInputs-1)); | |
e679ec96 | 1685 | |
9e957fb3 | 1686 | if (vtx[0].GetValueOut() > GetBlockValue(pindex->nHeight, nFees)) |
86c82bf9 | 1687 | return state.DoS(100, error("ConnectBlock() : coinbase pays too much (actual=%"PRI64d" vs limit=%"PRI64d")", vtx[0].GetValueOut(), GetBlockValue(pindex->nHeight, nFees))); |
9e957fb3 | 1688 | |
f9cae832 | 1689 | if (!control.Wait()) |
ef3988ca | 1690 | return state.DoS(100, false); |
f9cae832 PW |
1691 | int64 nTime2 = GetTimeMicros() - nStart; |
1692 | if (fBenchmark) | |
1693 | printf("- Verify %u txins: %.2fms (%.3fms/txin)\n", nInputs - 1, 0.001 * nTime2, nInputs <= 1 ? 0 : 0.001 * nTime2 / (nInputs-1)); | |
1694 | ||
3cd01fdf LD |
1695 | if (fJustCheck) |
1696 | return true; | |
1697 | ||
5382bcf8 | 1698 | // Write undo information to disk |
857c61df | 1699 | if (pindex->GetUndoPos().IsNull() || (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) |
5382bcf8 | 1700 | { |
857c61df PW |
1701 | if (pindex->GetUndoPos().IsNull()) { |
1702 | CDiskBlockPos pos; | |
ef3988ca | 1703 | if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40)) |
857c61df | 1704 | return error("ConnectBlock() : FindUndoPos failed"); |
8539361e | 1705 | if (!blockundo.WriteToDisk(pos, pindex->pprev->GetBlockHash())) |
421218d3 | 1706 | return state.Abort(_("Failed to write undo data")); |
857c61df PW |
1707 | |
1708 | // update nUndoPos in block index | |
1709 | pindex->nUndoPos = pos.nPos; | |
1710 | pindex->nStatus |= BLOCK_HAVE_UNDO; | |
1711 | } | |
1712 | ||
1713 | pindex->nStatus = (pindex->nStatus & ~BLOCK_VALID_MASK) | BLOCK_VALID_SCRIPTS; | |
1714 | ||
450cbb09 | 1715 | CDiskBlockIndex blockindex(pindex); |
d979e6e3 | 1716 | if (!pblocktree->WriteBlockIndex(blockindex)) |
421218d3 | 1717 | return state.Abort(_("Failed to write block index")); |
0a61b0df | 1718 | } |
1719 | ||
2d1fa42e | 1720 | if (fTxIndex) |
ef3988ca | 1721 | if (!pblocktree->WriteTxIndex(vPos)) |
421218d3 | 1722 | return state.Abort(_("Failed to write transaction index")); |
2d1fa42e | 1723 | |
729b1806 | 1724 | // add this block to the view's block chain |
7851033d | 1725 | assert(view.SetBestBlock(pindex)); |
450cbb09 | 1726 | |
0a61b0df | 1727 | // Watch for transactions paying to me |
64dd46fd PW |
1728 | for (unsigned int i=0; i<vtx.size(); i++) |
1729 | SyncWithWallets(GetTxHash(i), vtx[i], this, true); | |
0a61b0df | 1730 | |
1731 | return true; | |
1732 | } | |
1733 | ||
ef3988ca | 1734 | bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew) |
0a61b0df | 1735 | { |
d33a9218 PW |
1736 | // All modifications to the coin state will be done in this cache. |
1737 | // Only when all have succeeded, we push it to pcoinsTip. | |
1738 | CCoinsViewCache view(*pcoinsTip, true); | |
450cbb09 | 1739 | |
450cbb09 PW |
1740 | // Find the fork (typically, there is none) |
1741 | CBlockIndex* pfork = view.GetBestBlock(); | |
0a61b0df | 1742 | CBlockIndex* plonger = pindexNew; |
89b7019b | 1743 | while (pfork && pfork != plonger) |
0a61b0df | 1744 | { |
7851033d PW |
1745 | while (plonger->nHeight > pfork->nHeight) { |
1746 | plonger = plonger->pprev; | |
1747 | assert(plonger != NULL); | |
1748 | } | |
0a61b0df | 1749 | if (pfork == plonger) |
1750 | break; | |
7851033d PW |
1751 | pfork = pfork->pprev; |
1752 | assert(pfork != NULL); | |
0a61b0df | 1753 | } |
1754 | ||
450cbb09 | 1755 | // List of what to disconnect (typically nothing) |
0a61b0df | 1756 | vector<CBlockIndex*> vDisconnect; |
450cbb09 | 1757 | for (CBlockIndex* pindex = view.GetBestBlock(); pindex != pfork; pindex = pindex->pprev) |
0a61b0df | 1758 | vDisconnect.push_back(pindex); |
1759 | ||
450cbb09 | 1760 | // List of what to connect (typically only pindexNew) |
0a61b0df | 1761 | vector<CBlockIndex*> vConnect; |
1762 | for (CBlockIndex* pindex = pindexNew; pindex != pfork; pindex = pindex->pprev) | |
1763 | vConnect.push_back(pindex); | |
1764 | reverse(vConnect.begin(), vConnect.end()); | |
1765 | ||
450cbb09 | 1766 | if (vDisconnect.size() > 0) { |
1c06aa98 PW |
1767 | printf("REORGANIZE: Disconnect %"PRIszu" blocks; %s..\n", vDisconnect.size(), pfork->GetBlockHash().ToString().c_str()); |
1768 | printf("REORGANIZE: Connect %"PRIszu" blocks; ..%s\n", vConnect.size(), pindexNew->GetBlockHash().ToString().c_str()); | |
450cbb09 | 1769 | } |
a1a0469f | 1770 | |
0a61b0df | 1771 | // Disconnect shorter branch |
1772 | vector<CTransaction> vResurrect; | |
450cbb09 | 1773 | BOOST_FOREACH(CBlockIndex* pindex, vDisconnect) { |
0a61b0df | 1774 | CBlock block; |
1775 | if (!block.ReadFromDisk(pindex)) | |
421218d3 | 1776 | return state.Abort(_("Failed to read block")); |
8a28bb6d | 1777 | int64 nStart = GetTimeMicros(); |
ef3988ca | 1778 | if (!block.DisconnectBlock(state, pindex, view)) |
1c06aa98 | 1779 | return error("SetBestBlock() : DisconnectBlock %s failed", pindex->GetBlockHash().ToString().c_str()); |
8a28bb6d PW |
1780 | if (fBenchmark) |
1781 | printf("- Disconnect: %.2fms\n", (GetTimeMicros() - nStart) * 0.001); | |
0a61b0df | 1782 | |
8259c573 PW |
1783 | // Queue memory transactions to resurrect. |
1784 | // We only do this for blocks after the last checkpoint (reorganisation before that | |
1785 | // point should only happen with -reindex/-loadblock, or a misbehaving peer. | |
223b6f1b | 1786 | BOOST_FOREACH(const CTransaction& tx, block.vtx) |
8259c573 | 1787 | if (!tx.IsCoinBase() && pindex->nHeight > Checkpoints::GetTotalBlocksEstimate()) |
0a61b0df | 1788 | vResurrect.push_back(tx); |
1789 | } | |
1790 | ||
1791 | // Connect longer branch | |
1792 | vector<CTransaction> vDelete; | |
450cbb09 | 1793 | BOOST_FOREACH(CBlockIndex *pindex, vConnect) { |
0a61b0df | 1794 | CBlock block; |
857c61df | 1795 | if (!block.ReadFromDisk(pindex)) |
421218d3 | 1796 | return state.Abort(_("Failed to read block")); |
8a28bb6d | 1797 | int64 nStart = GetTimeMicros(); |
ef3988ca PW |
1798 | if (!block.ConnectBlock(state, pindex, view)) { |
1799 | if (state.IsInvalid()) { | |
1800 | InvalidChainFound(pindexNew); | |
1801 | InvalidBlockFound(pindex); | |
1802 | } | |
1c06aa98 | 1803 | return error("SetBestBlock() : ConnectBlock %s failed", pindex->GetBlockHash().ToString().c_str()); |
0a61b0df | 1804 | } |
8a28bb6d | 1805 | if (fBenchmark) |
69e07747 | 1806 | printf("- Connect: %.2fms\n", (GetTimeMicros() - nStart) * 0.001); |
0a61b0df | 1807 | |
1808 | // Queue memory transactions to delete | |
857c61df | 1809 | BOOST_FOREACH(const CTransaction& tx, block.vtx) |
0a61b0df | 1810 | vDelete.push_back(tx); |
1811 | } | |
0a61b0df | 1812 | |
d33a9218 | 1813 | // Flush changes to global coin state |
8a28bb6d PW |
1814 | int64 nStart = GetTimeMicros(); |
1815 | int nModified = view.GetCacheSize(); | |
7851033d | 1816 | assert(view.Flush()); |
8a28bb6d PW |
1817 | int64 nTime = GetTimeMicros() - nStart; |
1818 | if (fBenchmark) | |
1819 | printf("- Flush %i transactions: %.2fms (%.4fms/tx)\n", nModified, 0.001 * nTime, 0.001 * nTime / nModified); | |
d33a9218 | 1820 | |
b22c8842 | 1821 | // Make sure it's successfully written to disk before changing memory structure |
ae8bfd12 | 1822 | bool fIsInitialDownload = IsInitialBlockDownload(); |
d33a9218 | 1823 | if (!fIsInitialDownload || pcoinsTip->GetCacheSize() > nCoinCacheSize) { |
18379c80 PW |
1824 | // Typical CCoins structures on disk are around 100 bytes in size. |
1825 | // Pushing a new one to the database can cause it to be written | |
1826 | // twice (once in the log, and once in the tables). This is already | |
1827 | // an overestimation, as most will delete an existing entry or | |
1828 | // overwrite one. Still, use a conservative safety factor of 2. | |
1829 | if (!CheckDiskSpace(100 * 2 * 2 * pcoinsTip->GetCacheSize())) | |
1830 | return state.Error(); | |
44d40f26 | 1831 | FlushBlockFile(); |
2d8a4829 | 1832 | pblocktree->Sync(); |
d33a9218 | 1833 | if (!pcoinsTip->Flush()) |
421218d3 | 1834 | return state.Abort(_("Failed to write to coin database")); |
44d40f26 | 1835 | } |
450cbb09 PW |
1836 | |
1837 | // At this point, all changes have been done to the database. | |
1838 | // Proceed by updating the memory structures. | |
0a61b0df | 1839 | |
0fe8010a PW |
1840 | // Register new best chain |
1841 | vBlockIndexByHeight.resize(pindexNew->nHeight + 1); | |
223b6f1b | 1842 | BOOST_FOREACH(CBlockIndex* pindex, vConnect) |
0fe8010a | 1843 | vBlockIndexByHeight[pindex->nHeight] = pindex; |
0a61b0df | 1844 | |
1845 | // Resurrect memory transactions that were in the disconnected branch | |
ef3988ca PW |
1846 | BOOST_FOREACH(CTransaction& tx, vResurrect) { |
1847 | // ignore validation errors in resurrected transactions | |
1848 | CValidationState stateDummy; | |
1849 | tx.AcceptToMemoryPool(stateDummy, true, false); | |
1850 | } | |
0a61b0df | 1851 | |
1852 | // Delete redundant memory transactions that are in the connected branch | |
231b3999 | 1853 | BOOST_FOREACH(CTransaction& tx, vDelete) { |
8e45ed66 | 1854 | mempool.remove(tx); |
231b3999 PW |
1855 | mempool.removeConflicts(tx); |
1856 | } | |
0a61b0df | 1857 | |
6a76c60e | 1858 | // Update best block in wallet (so we can detect restored wallets) |
95c7db3d | 1859 | if ((pindexNew->nHeight % 20160) == 0 || (!fIsInitialDownload && (pindexNew->nHeight % 144) == 0)) |
6a76c60e | 1860 | { |
6a76c60e | 1861 | const CBlockLocator locator(pindexNew); |
64c7ee7e | 1862 | ::SetBestChain(locator); |
6a76c60e PW |
1863 | } |
1864 | ||
0a61b0df | 1865 | // New best block |
450cbb09 | 1866 | hashBestChain = pindexNew->GetBlockHash(); |
0a61b0df | 1867 | pindexBest = pindexNew; |
1be06419 | 1868 | pblockindexFBBHLast = NULL; |
0a61b0df | 1869 | nBestHeight = pindexBest->nHeight; |
1657c4bc | 1870 | nBestChainWork = pindexNew->nChainWork; |
0a61b0df | 1871 | nTimeBestReceived = GetTime(); |
1872 | nTransactionsUpdated++; | |
1657c4bc PW |
1873 | printf("SetBestChain: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f\n", |
1874 | hashBestChain.ToString().c_str(), nBestHeight, log(nBestChainWork.getdouble())/log(2.0), (unsigned long)pindexNew->nChainTx, | |
92a12998 PW |
1875 | DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexBest->GetBlockTime()).c_str(), |
1876 | Checkpoints::GuessVerificationProgress(pindexBest)); | |
0a61b0df | 1877 | |
2a919e39 GA |
1878 | // Check the version of the last 100 blocks to see if we need to upgrade: |
1879 | if (!fIsInitialDownload) | |
1880 | { | |
1881 | int nUpgraded = 0; | |
1882 | const CBlockIndex* pindex = pindexBest; | |
1883 | for (int i = 0; i < 100 && pindex != NULL; i++) | |
1884 | { | |
1885 | if (pindex->nVersion > CBlock::CURRENT_VERSION) | |
1886 | ++nUpgraded; | |
1887 | pindex = pindex->pprev; | |
1888 | } | |
1889 | if (nUpgraded > 0) | |
1890 | printf("SetBestChain: %d of last 100 blocks above version %d\n", nUpgraded, CBlock::CURRENT_VERSION); | |
1891 | if (nUpgraded > 100/2) | |
1892 | // strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user: | |
e6bc9c35 | 1893 | strMiscWarning = _("Warning: This version is obsolete, upgrade required!"); |
2a919e39 GA |
1894 | } |
1895 | ||
d237f62c GA |
1896 | std::string strCmd = GetArg("-blocknotify", ""); |
1897 | ||
1898 | if (!fIsInitialDownload && !strCmd.empty()) | |
1899 | { | |
1900 | boost::replace_all(strCmd, "%s", hashBestChain.GetHex()); | |
1901 | boost::thread t(runCommand, strCmd); // thread runs free | |
1902 | } | |
1903 | ||
0a61b0df | 1904 | return true; |
1905 | } | |
1906 | ||
1907 | ||
ef3988ca | 1908 | bool CBlock::AddToBlockIndex(CValidationState &state, const CDiskBlockPos &pos) |
0a61b0df | 1909 | { |
1910 | // Check for duplicate | |
1911 | uint256 hash = GetHash(); | |
1912 | if (mapBlockIndex.count(hash)) | |
1c06aa98 | 1913 | return state.Invalid(error("AddToBlockIndex() : %s already exists", hash.ToString().c_str())); |
0a61b0df | 1914 | |
1915 | // Construct new block index object | |
630fd8dc | 1916 | CBlockIndex* pindexNew = new CBlockIndex(*this); |
7851033d | 1917 | assert(pindexNew); |
0a61b0df | 1918 | map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; |
1919 | pindexNew->phashBlock = &((*mi).first); | |
1920 | map<uint256, CBlockIndex*>::iterator miPrev = mapBlockIndex.find(hashPrevBlock); | |
1921 | if (miPrev != mapBlockIndex.end()) | |
1922 | { | |
1923 | pindexNew->pprev = (*miPrev).second; | |
1924 | pindexNew->nHeight = pindexNew->pprev->nHeight + 1; | |
1925 | } | |
857c61df | 1926 | pindexNew->nTx = vtx.size(); |
1657c4bc | 1927 | pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + pindexNew->GetBlockWork().getuint256(); |
857c61df PW |
1928 | pindexNew->nChainTx = (pindexNew->pprev ? pindexNew->pprev->nChainTx : 0) + pindexNew->nTx; |
1929 | pindexNew->nFile = pos.nFile; | |
1930 | pindexNew->nDataPos = pos.nPos; | |
5382bcf8 | 1931 | pindexNew->nUndoPos = 0; |
857c61df PW |
1932 | pindexNew->nStatus = BLOCK_VALID_TRANSACTIONS | BLOCK_HAVE_DATA; |
1933 | setBlockIndexValid.insert(pindexNew); | |
0a61b0df | 1934 | |
ef3988ca | 1935 | if (!pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexNew))) |
421218d3 | 1936 | return state.Abort(_("Failed to write block index")); |
0a61b0df | 1937 | |
857c61df | 1938 | // New best? |
ef3988ca | 1939 | if (!ConnectBestBlock(state)) |
ae8bfd12 | 1940 | return false; |
0a61b0df | 1941 | |
1942 | if (pindexNew == pindexBest) | |
1943 | { | |
1944 | // Notify UI to display prev block's coinbase if it was ours | |
1945 | static uint256 hashPrevBestCoinBase; | |
64c7ee7e | 1946 | UpdatedTransaction(hashPrevBestCoinBase); |
64dd46fd | 1947 | hashPrevBestCoinBase = GetTxHash(0); |
0a61b0df | 1948 | } |
1949 | ||
ef3988ca | 1950 | if (!pblocktree->Flush()) |
421218d3 | 1951 | return state.Abort(_("Failed to sync block index")); |
d979e6e3 | 1952 | |
ab1b288f | 1953 | uiInterface.NotifyBlocksChanged(); |
0a61b0df | 1954 | return true; |
1955 | } | |
1956 | ||
1957 | ||
ef3988ca | 1958 | bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64 nTime, bool fKnown = false) |
5382bcf8 PW |
1959 | { |
1960 | bool fUpdatedLast = false; | |
1961 | ||
1962 | LOCK(cs_LastBlockFile); | |
1963 | ||
7fea4846 PW |
1964 | if (fKnown) { |
1965 | if (nLastBlockFile != pos.nFile) { | |
1966 | nLastBlockFile = pos.nFile; | |
1967 | infoLastBlockFile.SetNull(); | |
1968 | pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile); | |
c8b2e442 | 1969 | fUpdatedLast = true; |
7fea4846 PW |
1970 | } |
1971 | } else { | |
1972 | while (infoLastBlockFile.nSize + nAddSize >= MAX_BLOCKFILE_SIZE) { | |
1973 | printf("Leaving block file %i: %s\n", nLastBlockFile, infoLastBlockFile.ToString().c_str()); | |
1eb57879 | 1974 | FlushBlockFile(true); |
7fea4846 PW |
1975 | nLastBlockFile++; |
1976 | infoLastBlockFile.SetNull(); | |
1977 | pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile); // check whether data for the new file somehow already exist; can fail just fine | |
1978 | fUpdatedLast = true; | |
1979 | } | |
1980 | pos.nFile = nLastBlockFile; | |
1981 | pos.nPos = infoLastBlockFile.nSize; | |
5382bcf8 PW |
1982 | } |
1983 | ||
5382bcf8 PW |
1984 | infoLastBlockFile.nSize += nAddSize; |
1985 | infoLastBlockFile.AddBlock(nHeight, nTime); | |
1986 | ||
7fea4846 PW |
1987 | if (!fKnown) { |
1988 | unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE; | |
1989 | unsigned int nNewChunks = (infoLastBlockFile.nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE; | |
1990 | if (nNewChunks > nOldChunks) { | |
fa45c26a PK |
1991 | if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) { |
1992 | FILE *file = OpenBlockFile(pos); | |
1993 | if (file) { | |
1994 | printf("Pre-allocating up to position 0x%x in blk%05u.dat\n", nNewChunks * BLOCKFILE_CHUNK_SIZE, pos.nFile); | |
1995 | AllocateFileRange(file, pos.nPos, nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos); | |
1996 | fclose(file); | |
1997 | } | |
7fea4846 | 1998 | } |
fa45c26a | 1999 | else |
7851033d | 2000 | return state.Error(); |
bba89aa8 | 2001 | } |
bba89aa8 PW |
2002 | } |
2003 | ||
d979e6e3 | 2004 | if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile)) |
421218d3 | 2005 | return state.Abort(_("Failed to write file info")); |
5382bcf8 | 2006 | if (fUpdatedLast) |
d979e6e3 | 2007 | pblocktree->WriteLastBlockFile(nLastBlockFile); |
5382bcf8 PW |
2008 | |
2009 | return true; | |
2010 | } | |
2011 | ||
ef3988ca | 2012 | bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize) |
5382bcf8 PW |
2013 | { |
2014 | pos.nFile = nFile; | |
2015 | ||
2016 | LOCK(cs_LastBlockFile); | |
2017 | ||
bba89aa8 | 2018 | unsigned int nNewSize; |
5382bcf8 PW |
2019 | if (nFile == nLastBlockFile) { |
2020 | pos.nPos = infoLastBlockFile.nUndoSize; | |
bba89aa8 | 2021 | nNewSize = (infoLastBlockFile.nUndoSize += nAddSize); |
d979e6e3 | 2022 | if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile)) |
421218d3 | 2023 | return state.Abort(_("Failed to write block info")); |
bba89aa8 PW |
2024 | } else { |
2025 | CBlockFileInfo info; | |
d979e6e3 | 2026 | if (!pblocktree->ReadBlockFileInfo(nFile, info)) |
421218d3 | 2027 | return state.Abort(_("Failed to read block info")); |
bba89aa8 PW |
2028 | pos.nPos = info.nUndoSize; |
2029 | nNewSize = (info.nUndoSize += nAddSize); | |
d979e6e3 | 2030 | if (!pblocktree->WriteBlockFileInfo(nFile, info)) |
421218d3 | 2031 | return state.Abort(_("Failed to write block info")); |
bba89aa8 PW |
2032 | } |
2033 | ||
2034 | unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE; | |
2035 | unsigned int nNewChunks = (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE; | |
2036 | if (nNewChunks > nOldChunks) { | |
fa45c26a PK |
2037 | if (CheckDiskSpace(nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos)) { |
2038 | FILE *file = OpenUndoFile(pos); | |
2039 | if (file) { | |
2040 | printf("Pre-allocating up to position 0x%x in rev%05u.dat\n", nNewChunks * UNDOFILE_CHUNK_SIZE, pos.nFile); | |
2041 | AllocateFileRange(file, pos.nPos, nNewChunks * UNDOFILE_CHUNK_SIZE - pos.nPos); | |
2042 | fclose(file); | |
2043 | } | |
bba89aa8 | 2044 | } |
fa45c26a | 2045 | else |
7851033d | 2046 | return state.Error(); |
5382bcf8 PW |
2047 | } |
2048 | ||
5382bcf8 PW |
2049 | return true; |
2050 | } | |
2051 | ||
0a61b0df | 2052 | |
ef3988ca | 2053 | bool CBlock::CheckBlock(CValidationState &state, bool fCheckPOW, bool fCheckMerkleRoot) const |
0a61b0df | 2054 | { |
2055 | // These are checks that are independent of context | |
2056 | // that can be verified before saving an orphan block. | |
2057 | ||
2058 | // Size limits | |
6b6aaa16 | 2059 | if (vtx.empty() || vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) |
ef3988ca | 2060 | return state.DoS(100, error("CheckBlock() : size limits failed")); |
0a61b0df | 2061 | |
172f0060 | 2062 | // Check proof of work matches claimed amount |
3cd01fdf | 2063 | if (fCheckPOW && !CheckProofOfWork(GetHash(), nBits)) |
ef3988ca | 2064 | return state.DoS(50, error("CheckBlock() : proof of work failed")); |
172f0060 | 2065 | |
0a61b0df | 2066 | // Check timestamp |
2067 | if (GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60) | |
ef3988ca | 2068 | return state.Invalid(error("CheckBlock() : block timestamp too far in the future")); |
0a61b0df | 2069 | |
2070 | // First transaction must be coinbase, the rest must not be | |
2071 | if (vtx.empty() || !vtx[0].IsCoinBase()) | |
ef3988ca | 2072 | return state.DoS(100, error("CheckBlock() : first tx is not coinbase")); |
c376ac35 | 2073 | for (unsigned int i = 1; i < vtx.size(); i++) |
0a61b0df | 2074 | if (vtx[i].IsCoinBase()) |
ef3988ca | 2075 | return state.DoS(100, error("CheckBlock() : more than one coinbase")); |
0a61b0df | 2076 | |
2077 | // Check transactions | |
223b6f1b | 2078 | BOOST_FOREACH(const CTransaction& tx, vtx) |
ef3988ca PW |
2079 | if (!tx.CheckTransaction(state)) |
2080 | return error("CheckBlock() : CheckTransaction failed"); | |
0a61b0df | 2081 | |
c2ed184f PW |
2082 | // Build the merkle tree already. We need it anyway later, and it makes the |
2083 | // block cache the transaction hashes, which means they don't need to be | |
2084 | // recalculated many times during this block's validation. | |
2085 | BuildMerkleTree(); | |
2086 | ||
be8651dd GA |
2087 | // Check for duplicate txids. This is caught by ConnectInputs(), |
2088 | // but catching it earlier avoids a potential DoS attack: | |
2089 | set<uint256> uniqueTx; | |
64dd46fd PW |
2090 | for (unsigned int i=0; i<vtx.size(); i++) { |
2091 | uniqueTx.insert(GetTxHash(i)); | |
be8651dd GA |
2092 | } |
2093 | if (uniqueTx.size() != vtx.size()) | |
ef3988ca | 2094 | return state.DoS(100, error("CheckBlock() : duplicate transaction")); |
be8651dd | 2095 | |
7bd9c3a3 | 2096 | unsigned int nSigOps = 0; |
e679ec96 GA |
2097 | BOOST_FOREACH(const CTransaction& tx, vtx) |
2098 | { | |
922e8e29 | 2099 | nSigOps += tx.GetLegacySigOpCount(); |
e679ec96 GA |
2100 | } |
2101 | if (nSigOps > MAX_BLOCK_SIGOPS) | |
ef3988ca | 2102 | return state.DoS(100, error("CheckBlock() : out-of-bounds SigOpCount")); |
0a61b0df | 2103 | |
814efd6f | 2104 | // Check merkle root |
3cd01fdf | 2105 | if (fCheckMerkleRoot && hashMerkleRoot != BuildMerkleTree()) |
ef3988ca | 2106 | return state.DoS(100, error("CheckBlock() : hashMerkleRoot mismatch")); |
0a61b0df | 2107 | |
2108 | return true; | |
2109 | } | |
2110 | ||
ef3988ca | 2111 | bool CBlock::AcceptBlock(CValidationState &state, CDiskBlockPos *dbp) |
0a61b0df | 2112 | { |
2113 | // Check for duplicate | |
2114 | uint256 hash = GetHash(); | |
2115 | if (mapBlockIndex.count(hash)) | |
ef3988ca | 2116 | return state.Invalid(error("AcceptBlock() : block already in mapBlockIndex")); |
0a61b0df | 2117 | |
2118 | // Get prev block index | |
7fea4846 PW |
2119 | CBlockIndex* pindexPrev = NULL; |
2120 | int nHeight = 0; | |
2121 | if (hash != hashGenesisBlock) { | |
b56585d0 PK |
2122 | map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrevBlock); |
2123 | if (mi == mapBlockIndex.end()) | |
ef3988ca | 2124 | return state.DoS(10, error("AcceptBlock() : prev block not found")); |
b56585d0 PK |
2125 | pindexPrev = (*mi).second; |
2126 | nHeight = pindexPrev->nHeight+1; | |
2127 | ||
2128 | // Check proof of work | |
2129 | if (nBits != GetNextWorkRequired(pindexPrev, this)) | |
ef3988ca | 2130 | return state.DoS(100, error("AcceptBlock() : incorrect proof of work")); |
b56585d0 PK |
2131 | |
2132 | // Check timestamp against prev | |
2133 | if (GetBlockTime() <= pindexPrev->GetMedianTimePast()) | |
ef3988ca | 2134 | return state.Invalid(error("AcceptBlock() : block's timestamp is too early")); |
b56585d0 PK |
2135 | |
2136 | // Check that all transactions are finalized | |
2137 | BOOST_FOREACH(const CTransaction& tx, vtx) | |
2138 | if (!tx.IsFinal(nHeight, GetBlockTime())) | |
ef3988ca | 2139 | return state.DoS(10, error("AcceptBlock() : contains a non-final transaction")); |
b56585d0 PK |
2140 | |
2141 | // Check that the block chain matches the known block chain up to a checkpoint | |
2142 | if (!Checkpoints::CheckBlock(nHeight, hash)) | |
ef3988ca | 2143 | return state.DoS(100, error("AcceptBlock() : rejected by checkpoint lock-in at %d", nHeight)); |
b56585d0 PK |
2144 | |
2145 | // Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded: | |
2146 | if (nVersion < 2) | |
d18f2fd9 | 2147 | { |
b56585d0 PK |
2148 | if ((!fTestNet && CBlockIndex::IsSuperMajority(2, pindexPrev, 950, 1000)) || |
2149 | (fTestNet && CBlockIndex::IsSuperMajority(2, pindexPrev, 75, 100))) | |
2150 | { | |
ef3988ca | 2151 | return state.Invalid(error("AcceptBlock() : rejected nVersion=1 block")); |
b56585d0 | 2152 | } |
d18f2fd9 | 2153 | } |
b56585d0 PK |
2154 | // Enforce block.nVersion=2 rule that the coinbase starts with serialized block height |
2155 | if (nVersion >= 2) | |
de237cbf | 2156 | { |
b56585d0 PK |
2157 | // if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet): |
2158 | if ((!fTestNet && CBlockIndex::IsSuperMajority(2, pindexPrev, 750, 1000)) || | |
2159 | (fTestNet && CBlockIndex::IsSuperMajority(2, pindexPrev, 51, 100))) | |
2160 | { | |
2161 | CScript expect = CScript() << nHeight; | |
2162 | if (!std::equal(expect.begin(), expect.end(), vtx[0].vin[0].scriptSig.begin())) | |
ef3988ca | 2163 | return state.DoS(100, error("AcceptBlock() : block height mismatch in coinbase")); |
b56585d0 | 2164 | } |
de237cbf GA |
2165 | } |
2166 | } | |
2167 | ||
0a61b0df | 2168 | // Write block to history file |
421218d3 PW |
2169 | try { |
2170 | unsigned int nBlockSize = ::GetSerializeSize(*this, SER_DISK, CLIENT_VERSION); | |
2171 | CDiskBlockPos blockPos; | |
2172 | if (dbp != NULL) | |
2173 | blockPos = *dbp; | |
2174 | if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, nTime, dbp != NULL)) | |
2175 | return error("AcceptBlock() : FindBlockPos failed"); | |
2176 | if (dbp == NULL) | |
2177 | if (!WriteToDisk(blockPos)) | |
2178 | return state.Abort(_("Failed to write block")); | |
2179 | if (!AddToBlockIndex(state, blockPos)) | |
2180 | return error("AcceptBlock() : AddToBlockIndex failed"); | |
2181 | } catch(std::runtime_error &e) { | |
2182 | return state.Abort(_("System error: ") + e.what()); | |
2183 | } | |
0a61b0df | 2184 | |
2185 | // Relay inventory, but don't relay old inventory during initial block download | |
eae82d8e | 2186 | int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(); |
0a61b0df | 2187 | if (hashBestChain == hash) |
f8dcd5ca PW |
2188 | { |
2189 | LOCK(cs_vNodes); | |
2190 | BOOST_FOREACH(CNode* pnode, vNodes) | |
2191 | if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) | |
2192 | pnode->PushInventory(CInv(MSG_BLOCK, hash)); | |
2193 | } | |
0a61b0df | 2194 | |
2195 | return true; | |
2196 | } | |
2197 | ||
de237cbf GA |
2198 | bool CBlockIndex::IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired, unsigned int nToCheck) |
2199 | { | |
2200 | unsigned int nFound = 0; | |
2201 | for (unsigned int i = 0; i < nToCheck && nFound < nRequired && pstart != NULL; i++) | |
2202 | { | |
2203 | if (pstart->nVersion >= minVersion) | |
2204 | ++nFound; | |
2205 | pstart = pstart->pprev; | |
2206 | } | |
2207 | return (nFound >= nRequired); | |
2208 | } | |
2209 | ||
ef3988ca | 2210 | bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp) |
0a61b0df | 2211 | { |
2212 | // Check for duplicate | |
2213 | uint256 hash = pblock->GetHash(); | |
2214 | if (mapBlockIndex.count(hash)) | |
1c06aa98 | 2215 | return state.Invalid(error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().c_str())); |
0a61b0df | 2216 | if (mapOrphanBlocks.count(hash)) |
1c06aa98 | 2217 | return state.Invalid(error("ProcessBlock() : already have block (orphan) %s", hash.ToString().c_str())); |
0a61b0df | 2218 | |
2219 | // Preliminary checks | |
ef3988ca | 2220 | if (!pblock->CheckBlock(state)) |
0a61b0df | 2221 | return error("ProcessBlock() : CheckBlock FAILED"); |
0a61b0df | 2222 | |
10fd7f66 GA |
2223 | CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex); |
2224 | if (pcheckpoint && pblock->hashPrevBlock != hashBestChain) | |
2225 | { | |
2226 | // Extra checks to prevent "fill up memory by spamming with bogus blocks" | |
bde280b9 | 2227 | int64 deltaTime = pblock->GetBlockTime() - pcheckpoint->nTime; |
10fd7f66 GA |
2228 | if (deltaTime < 0) |
2229 | { | |
ef3988ca | 2230 | return state.DoS(100, error("ProcessBlock() : block with timestamp before last checkpoint")); |
10fd7f66 GA |
2231 | } |
2232 | CBigNum bnNewBlock; | |
2233 | bnNewBlock.SetCompact(pblock->nBits); | |
2234 | CBigNum bnRequired; | |
2235 | bnRequired.SetCompact(ComputeMinWork(pcheckpoint->nBits, deltaTime)); | |
2236 | if (bnNewBlock > bnRequired) | |
2237 | { | |
ef3988ca | 2238 | return state.DoS(100, error("ProcessBlock() : block with too little proof-of-work")); |
10fd7f66 GA |
2239 | } |
2240 | } | |
2241 | ||
2242 | ||
5c88e3c1 | 2243 | // If we don't already have its previous block, shunt it off to holding area until we get it |
7fea4846 | 2244 | if (pblock->hashPrevBlock != 0 && !mapBlockIndex.count(pblock->hashPrevBlock)) |
0a61b0df | 2245 | { |
1c06aa98 | 2246 | printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().c_str()); |
0a61b0df | 2247 | |
5c88e3c1 PW |
2248 | // Accept orphans as long as there is a node to request its parents from |
2249 | if (pfrom) { | |
2250 | CBlock* pblock2 = new CBlock(*pblock); | |
2251 | mapOrphanBlocks.insert(make_pair(hash, pblock2)); | |
2252 | mapOrphanBlocksByPrev.insert(make_pair(pblock2->hashPrevBlock, pblock2)); | |
2253 | ||
2254 | // Ask this guy to fill in what we're missing | |
776d0f34 | 2255 | pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(pblock2)); |
5c88e3c1 | 2256 | } |
0a61b0df | 2257 | return true; |
2258 | } | |
2259 | ||
2260 | // Store to disk | |
ef3988ca | 2261 | if (!pblock->AcceptBlock(state, dbp)) |
0a61b0df | 2262 | return error("ProcessBlock() : AcceptBlock FAILED"); |
0a61b0df | 2263 | |
2264 | // Recursively process any orphan blocks that depended on this one | |
2265 | vector<uint256> vWorkQueue; | |
2266 | vWorkQueue.push_back(hash); | |
c376ac35 | 2267 | for (unsigned int i = 0; i < vWorkQueue.size(); i++) |
0a61b0df | 2268 | { |
2269 | uint256 hashPrev = vWorkQueue[i]; | |
2270 | for (multimap<uint256, CBlock*>::iterator mi = mapOrphanBlocksByPrev.lower_bound(hashPrev); | |
2271 | mi != mapOrphanBlocksByPrev.upper_bound(hashPrev); | |
2272 | ++mi) | |
2273 | { | |
2274 | CBlock* pblockOrphan = (*mi).second; | |
8c4e4313 LD |
2275 | // 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) |
2276 | CValidationState stateDummy; | |
2277 | if (pblockOrphan->AcceptBlock(stateDummy)) | |
0a61b0df | 2278 | vWorkQueue.push_back(pblockOrphan->GetHash()); |
2279 | mapOrphanBlocks.erase(pblockOrphan->GetHash()); | |
2280 | delete pblockOrphan; | |
2281 | } | |
2282 | mapOrphanBlocksByPrev.erase(hashPrev); | |
2283 | } | |
2284 | ||
2285 | printf("ProcessBlock: ACCEPTED\n"); | |
2286 | return true; | |
2287 | } | |
2288 | ||
2289 | ||
2290 | ||
2291 | ||
2292 | ||
2293 | ||
2294 | ||
2295 | ||
9fb106e7 MC |
2296 | CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter& filter) |
2297 | { | |
2298 | header = block.GetBlockHeader(); | |
9fb106e7 | 2299 | |
21aaf255 MC |
2300 | vector<bool> vMatch; |
2301 | vector<uint256> vHashes; | |
2302 | ||
2303 | vMatch.reserve(block.vtx.size()); | |
2304 | vHashes.reserve(block.vtx.size()); | |
2305 | ||
2306 | for (unsigned int i = 0; i < block.vtx.size(); i++) | |
9fb106e7 | 2307 | { |
9fb106e7 MC |
2308 | uint256 hash = block.vtx[i].GetHash(); |
2309 | if (filter.IsRelevantAndUpdate(block.vtx[i], hash)) | |
2310 | { | |
21aaf255 MC |
2311 | vMatch.push_back(true); |
2312 | vMatchedTxn.push_back(make_pair(i, hash)); | |
9fb106e7 | 2313 | } |
21aaf255 MC |
2314 | else |
2315 | vMatch.push_back(false); | |
2316 | vHashes.push_back(hash); | |
9fb106e7 | 2317 | } |
21aaf255 MC |
2318 | |
2319 | txn = CPartialMerkleTree(vHashes, vMatch); | |
9fb106e7 MC |
2320 | } |
2321 | ||
2322 | ||
2323 | ||
2324 | ||
2325 | ||
2326 | ||
2327 | ||
2328 | ||
4bedfa92 PW |
2329 | uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::vector<uint256> &vTxid) { |
2330 | if (height == 0) { | |
2331 | // hash at height 0 is the txids themself | |
2332 | return vTxid[pos]; | |
2333 | } else { | |
2334 | // calculate left hash | |
2335 | uint256 left = CalcHash(height-1, pos*2, vTxid), right; | |
2336 | // calculate right hash if not beyong the end of the array - copy left hash otherwise1 | |
2337 | if (pos*2+1 < CalcTreeWidth(height-1)) | |
2338 | right = CalcHash(height-1, pos*2+1, vTxid); | |
2339 | else | |
2340 | right = left; | |
2341 | // combine subhashes | |
2342 | return Hash(BEGIN(left), END(left), BEGIN(right), END(right)); | |
2343 | } | |
2344 | } | |
2345 | ||
2346 | void CPartialMerkleTree::TraverseAndBuild(int height, unsigned int pos, const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) { | |
2347 | // determine whether this node is the parent of at least one matched txid | |
2348 | bool fParentOfMatch = false; | |
2349 | for (unsigned int p = pos << height; p < (pos+1) << height && p < nTransactions; p++) | |
2350 | fParentOfMatch |= vMatch[p]; | |
2351 | // store as flag bit | |
2352 | vBits.push_back(fParentOfMatch); | |
2353 | if (height==0 || !fParentOfMatch) { | |
2354 | // if at height 0, or nothing interesting below, store hash and stop | |
2355 | vHash.push_back(CalcHash(height, pos, vTxid)); | |
2356 | } else { | |
2357 | // otherwise, don't store any hash, but descend into the subtrees | |
2358 | TraverseAndBuild(height-1, pos*2, vTxid, vMatch); | |
2359 | if (pos*2+1 < CalcTreeWidth(height-1)) | |
2360 | TraverseAndBuild(height-1, pos*2+1, vTxid, vMatch); | |
2361 | } | |
2362 | } | |
2363 | ||
2364 | uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<uint256> &vMatch) { | |
2365 | if (nBitsUsed >= vBits.size()) { | |
2366 | // overflowed the bits array - failure | |
2367 | fBad = true; | |
2368 | return 0; | |
2369 | } | |
2370 | bool fParentOfMatch = vBits[nBitsUsed++]; | |
2371 | if (height==0 || !fParentOfMatch) { | |
2372 | // if at height 0, or nothing interesting below, use stored hash and do not descend | |
2373 | if (nHashUsed >= vHash.size()) { | |
2374 | // overflowed the hash array - failure | |
2375 | fBad = true; | |
2376 | return 0; | |
2377 | } | |
2378 | const uint256 &hash = vHash[nHashUsed++]; | |
2379 | if (height==0 && fParentOfMatch) // in case of height 0, we have a matched txid | |
2380 | vMatch.push_back(hash); | |
2381 | return hash; | |
2382 | } else { | |
2383 | // otherwise, descend into the subtrees to extract matched txids and hashes | |
2384 | uint256 left = TraverseAndExtract(height-1, pos*2, nBitsUsed, nHashUsed, vMatch), right; | |
2385 | if (pos*2+1 < CalcTreeWidth(height-1)) | |
2386 | right = TraverseAndExtract(height-1, pos*2+1, nBitsUsed, nHashUsed, vMatch); | |
2387 | else | |
2388 | right = left; | |
2389 | // and combine them before returning | |
2390 | return Hash(BEGIN(left), END(left), BEGIN(right), END(right)); | |
2391 | } | |
2392 | } | |
2393 | ||
2394 | CPartialMerkleTree::CPartialMerkleTree(const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) : nTransactions(vTxid.size()), fBad(false) { | |
2395 | // reset state | |
2396 | vBits.clear(); | |
2397 | vHash.clear(); | |
2398 | ||
2399 | // calculate height of tree | |
2400 | int nHeight = 0; | |
2401 | while (CalcTreeWidth(nHeight) > 1) | |
2402 | nHeight++; | |
2403 | ||
2404 | // traverse the partial tree | |
2405 | TraverseAndBuild(nHeight, 0, vTxid, vMatch); | |
2406 | } | |
2407 | ||
2408 | CPartialMerkleTree::CPartialMerkleTree() : nTransactions(0), fBad(true) {} | |
2409 | ||
2410 | uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) { | |
2411 | vMatch.clear(); | |
2412 | // An empty set will not work | |
2413 | if (nTransactions == 0) | |
2414 | return 0; | |
2415 | // check for excessively high numbers of transactions | |
2416 | if (nTransactions > MAX_BLOCK_SIZE / 60) // 60 is the lower bound for the size of a serialized CTransaction | |
2417 | return 0; | |
2418 | // there can never be more hashes provided than one for every txid | |
2419 | if (vHash.size() > nTransactions) | |
2420 | return 0; | |
2421 | // there must be at least one bit per node in the partial tree, and at least one node per hash | |
2422 | if (vBits.size() < vHash.size()) | |
2423 | return 0; | |
2424 | // calculate height of tree | |
2425 | int nHeight = 0; | |
2426 | while (CalcTreeWidth(nHeight) > 1) | |
2427 | nHeight++; | |
2428 | // traverse the partial tree | |
2429 | unsigned int nBitsUsed = 0, nHashUsed = 0; | |
2430 | uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch); | |
2431 | // verify that no problems occured during the tree traversal | |
2432 | if (fBad) | |
2433 | return 0; | |
2434 | // verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence) | |
2435 | if ((nBitsUsed+7)/8 != (vBits.size()+7)/8) | |
2436 | return 0; | |
2437 | // verify that all hashes were consumed | |
2438 | if (nHashUsed != vHash.size()) | |
2439 | return 0; | |
2440 | return hashMerkleRoot; | |
2441 | } | |
2442 | ||
2443 | ||
2444 | ||
2445 | ||
2446 | ||
2447 | ||
2448 | ||
7851033d | 2449 | bool AbortNode(const std::string &strMessage) { |
7851033d PW |
2450 | strMiscWarning = strMessage; |
2451 | printf("*** %s\n", strMessage.c_str()); | |
69e07747 | 2452 | uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_ERROR); |
7851033d PW |
2453 | StartShutdown(); |
2454 | return false; | |
2455 | } | |
4bedfa92 | 2456 | |
bde280b9 | 2457 | bool CheckDiskSpace(uint64 nAdditionalBytes) |
0a61b0df | 2458 | { |
bde280b9 | 2459 | uint64 nFreeBytesAvailable = filesystem::space(GetDataDir()).available; |
0a61b0df | 2460 | |
966ae00f PK |
2461 | // Check for nMinDiskSpace bytes (currently 50MB) |
2462 | if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes) | |
7851033d PW |
2463 | return AbortNode(_("Error: Disk space is low!")); |
2464 | ||
0a61b0df | 2465 | return true; |
2466 | } | |
2467 | ||
5382bcf8 PW |
2468 | CCriticalSection cs_LastBlockFile; |
2469 | CBlockFileInfo infoLastBlockFile; | |
2470 | int nLastBlockFile = 0; | |
2471 | ||
2472 | FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly) | |
42613c97 | 2473 | { |
450cbb09 | 2474 | if (pos.IsNull()) |
0a61b0df | 2475 | return NULL; |
5382bcf8 PW |
2476 | boost::filesystem::path path = GetDataDir() / "blocks" / strprintf("%s%05u.dat", prefix, pos.nFile); |
2477 | boost::filesystem::create_directories(path.parent_path()); | |
2478 | FILE* file = fopen(path.string().c_str(), "rb+"); | |
2479 | if (!file && !fReadOnly) | |
2480 | file = fopen(path.string().c_str(), "wb+"); | |
450cbb09 PW |
2481 | if (!file) { |
2482 | printf("Unable to open file %s\n", path.string().c_str()); | |
0a61b0df | 2483 | return NULL; |
450cbb09 | 2484 | } |
5382bcf8 PW |
2485 | if (pos.nPos) { |
2486 | if (fseek(file, pos.nPos, SEEK_SET)) { | |
2487 | printf("Unable to seek to position %u of %s\n", pos.nPos, path.string().c_str()); | |
2488 | fclose(file); | |
2489 | return NULL; | |
2490 | } | |
2491 | } | |
0a61b0df | 2492 | return file; |
2493 | } | |
2494 | ||
5382bcf8 PW |
2495 | FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly) { |
2496 | return OpenDiskFile(pos, "blk", fReadOnly); | |
2497 | } | |
2498 | ||
69e07747 | 2499 | FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly) { |
5382bcf8 PW |
2500 | return OpenDiskFile(pos, "rev", fReadOnly); |
2501 | } | |
2502 | ||
2d8a4829 PW |
2503 | CBlockIndex * InsertBlockIndex(uint256 hash) |
2504 | { | |
2505 | if (hash == 0) | |
2506 | return NULL; | |
2507 | ||
2508 | // Return existing | |
2509 | map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash); | |
2510 | if (mi != mapBlockIndex.end()) | |
2511 | return (*mi).second; | |
2512 | ||
2513 | // Create new | |
2514 | CBlockIndex* pindexNew = new CBlockIndex(); | |
2515 | if (!pindexNew) | |
2516 | throw runtime_error("LoadBlockIndex() : new CBlockIndex failed"); | |
2517 | mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; | |
2518 | pindexNew->phashBlock = &((*mi).first); | |
2519 | ||
2520 | return pindexNew; | |
2521 | } | |
2522 | ||
2523 | bool static LoadBlockIndexDB() | |
2524 | { | |
2525 | if (!pblocktree->LoadBlockIndexGuts()) | |
2526 | return false; | |
2527 | ||
b31499ec | 2528 | boost::this_thread::interruption_point(); |
2d8a4829 | 2529 | |
1657c4bc | 2530 | // Calculate nChainWork |
2d8a4829 PW |
2531 | vector<pair<int, CBlockIndex*> > vSortedByHeight; |
2532 | vSortedByHeight.reserve(mapBlockIndex.size()); | |
2533 | BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex) | |
2534 | { | |
2535 | CBlockIndex* pindex = item.second; | |
2536 | vSortedByHeight.push_back(make_pair(pindex->nHeight, pindex)); | |
2537 | } | |
2538 | sort(vSortedByHeight.begin(), vSortedByHeight.end()); | |
2539 | BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight) | |
2540 | { | |
2541 | CBlockIndex* pindex = item.second; | |
1657c4bc | 2542 | pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + pindex->GetBlockWork().getuint256(); |
2d8a4829 PW |
2543 | pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx; |
2544 | if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS && !(pindex->nStatus & BLOCK_FAILED_MASK)) | |
2545 | setBlockIndexValid.insert(pindex); | |
2546 | } | |
2547 | ||
2548 | // Load block file info | |
2549 | pblocktree->ReadLastBlockFile(nLastBlockFile); | |
69e07747 | 2550 | printf("LoadBlockIndexDB(): last block file = %i\n", nLastBlockFile); |
2d8a4829 | 2551 | if (pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile)) |
69e07747 | 2552 | printf("LoadBlockIndexDB(): last block file info: %s\n", infoLastBlockFile.ToString().c_str()); |
729b1806 | 2553 | |
1657c4bc PW |
2554 | // Load nBestInvalidWork, OK if it doesn't exist |
2555 | CBigNum bnBestInvalidWork; | |
89b7019b | 2556 | pblocktree->ReadBestInvalidWork(bnBestInvalidWork); |
1657c4bc | 2557 | nBestInvalidWork = bnBestInvalidWork.getuint256(); |
89b7019b PW |
2558 | |
2559 | // Check whether we need to continue reindexing | |
2560 | bool fReindexing = false; | |
2561 | pblocktree->ReadReindexing(fReindexing); | |
2562 | fReindex |= fReindexing; | |
2563 | ||
2d1fa42e PW |
2564 | // Check whether we have a transaction index |
2565 | pblocktree->ReadFlag("txindex", fTxIndex); | |
69e07747 | 2566 | printf("LoadBlockIndexDB(): transaction index %s\n", fTxIndex ? "enabled" : "disabled"); |
2d1fa42e | 2567 | |
2d8a4829 PW |
2568 | // Load hashBestChain pointer to end of best chain |
2569 | pindexBest = pcoinsTip->GetBestBlock(); | |
2570 | if (pindexBest == NULL) | |
89b7019b | 2571 | return true; |
2d8a4829 PW |
2572 | hashBestChain = pindexBest->GetBlockHash(); |
2573 | nBestHeight = pindexBest->nHeight; | |
1657c4bc | 2574 | nBestChainWork = pindexBest->nChainWork; |
2d8a4829 | 2575 | |
0fe8010a | 2576 | // register best chain |
2d8a4829 | 2577 | CBlockIndex *pindex = pindexBest; |
0fe8010a PW |
2578 | vBlockIndexByHeight.resize(pindexBest->nHeight + 1); |
2579 | while(pindex != NULL) { | |
2580 | vBlockIndexByHeight[pindex->nHeight] = pindex; | |
2581 | pindex = pindex->pprev; | |
2d8a4829 | 2582 | } |
69e07747 | 2583 | printf("LoadBlockIndexDB(): hashBestChain=%s height=%d date=%s\n", |
1c06aa98 | 2584 | hashBestChain.ToString().c_str(), nBestHeight, |
3f964b3c | 2585 | DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexBest->GetBlockTime()).c_str()); |
2d8a4829 | 2586 | |
1f355b66 PW |
2587 | return true; |
2588 | } | |
2589 | ||
2590 | bool VerifyDB() { | |
2591 | if (pindexBest == NULL || pindexBest->pprev == NULL) | |
2592 | return true; | |
2593 | ||
2d8a4829 | 2594 | // Verify blocks in the best chain |
1f355b66 | 2595 | int nCheckLevel = GetArg("-checklevel", 3); |
56869fc0 | 2596 | int nCheckDepth = GetArg( "-checkblocks", 288); |
2d8a4829 PW |
2597 | if (nCheckDepth == 0) |
2598 | nCheckDepth = 1000000000; // suffices until the year 19000 | |
2599 | if (nCheckDepth > nBestHeight) | |
2600 | nCheckDepth = nBestHeight; | |
1f355b66 | 2601 | nCheckLevel = std::max(0, std::min(4, nCheckLevel)); |
2d8a4829 | 2602 | printf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel); |
1f355b66 PW |
2603 | CCoinsViewCache coins(*pcoinsTip, true); |
2604 | CBlockIndex* pindexState = pindexBest; | |
2605 | CBlockIndex* pindexFailure = NULL; | |
2606 | int nGoodTransactions = 0; | |
ef3988ca | 2607 | CValidationState state; |
2d8a4829 PW |
2608 | for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev) |
2609 | { | |
b31499ec GA |
2610 | boost::this_thread::interruption_point(); |
2611 | if (pindex->nHeight < nBestHeight-nCheckDepth) | |
2d8a4829 PW |
2612 | break; |
2613 | CBlock block; | |
1f355b66 | 2614 | // check level 0: read from disk |
2d8a4829 | 2615 | if (!block.ReadFromDisk(pindex)) |
1f355b66 | 2616 | return error("VerifyDB() : *** block.ReadFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); |
2d8a4829 | 2617 | // check level 1: verify block validity |
ef3988ca | 2618 | if (nCheckLevel >= 1 && !block.CheckBlock(state)) |
1f355b66 PW |
2619 | return error("VerifyDB() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); |
2620 | // check level 2: verify undo validity | |
2621 | if (nCheckLevel >= 2 && pindex) { | |
2622 | CBlockUndo undo; | |
2623 | CDiskBlockPos pos = pindex->GetUndoPos(); | |
2624 | if (!pos.IsNull()) { | |
2625 | if (!undo.ReadFromDisk(pos, pindex->pprev->GetBlockHash())) | |
2626 | return error("VerifyDB() : *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); | |
2627 | } | |
2628 | } | |
2629 | // check level 3: check for inconsistencies during memory-only disconnect of tip blocks | |
2630 | if (nCheckLevel >= 3 && pindex == pindexState && (coins.GetCacheSize() + pcoinsTip->GetCacheSize()) <= 2*nCoinCacheSize + 32000) { | |
2631 | bool fClean = true; | |
ef3988ca | 2632 | if (!block.DisconnectBlock(state, pindex, coins, &fClean)) |
1f355b66 PW |
2633 | return error("VerifyDB() : *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); |
2634 | pindexState = pindex->pprev; | |
2635 | if (!fClean) { | |
2636 | nGoodTransactions = 0; | |
2637 | pindexFailure = pindex; | |
2638 | } else | |
2639 | nGoodTransactions += block.vtx.size(); | |
2d8a4829 | 2640 | } |
2d8a4829 | 2641 | } |
1f355b66 PW |
2642 | if (pindexFailure) |
2643 | return error("VerifyDB() : *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", pindexBest->nHeight - pindexFailure->nHeight + 1, nGoodTransactions); | |
2644 | ||
2645 | // check level 4: try reconnecting blocks | |
2646 | if (nCheckLevel >= 4) { | |
2647 | CBlockIndex *pindex = pindexState; | |
b31499ec GA |
2648 | while (pindex != pindexBest) { |
2649 | boost::this_thread::interruption_point(); | |
0fe8010a | 2650 | pindex = pindex->GetNextInMainChain(); |
b001c871 PK |
2651 | CBlock block; |
2652 | if (!block.ReadFromDisk(pindex)) | |
2653 | return error("VerifyDB() : *** block.ReadFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); | |
2654 | if (!block.ConnectBlock(state, pindex, coins)) | |
2655 | return error("VerifyDB() : *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); | |
1f355b66 | 2656 | } |
2d8a4829 PW |
2657 | } |
2658 | ||
1f355b66 PW |
2659 | printf("No coin database inconsistencies in last %i blocks (%i transactions)\n", pindexBest->nHeight - pindexState->nHeight, nGoodTransactions); |
2660 | ||
2d8a4829 PW |
2661 | return true; |
2662 | } | |
2663 | ||
f7f3a96b PW |
2664 | void UnloadBlockIndex() |
2665 | { | |
2666 | mapBlockIndex.clear(); | |
2667 | setBlockIndexValid.clear(); | |
2668 | pindexGenesisBlock = NULL; | |
2669 | nBestHeight = 0; | |
1657c4bc PW |
2670 | nBestChainWork = 0; |
2671 | nBestInvalidWork = 0; | |
f7f3a96b PW |
2672 | hashBestChain = 0; |
2673 | pindexBest = NULL; | |
2674 | } | |
2675 | ||
7fea4846 | 2676 | bool LoadBlockIndex() |
0a61b0df | 2677 | { |
5cbf7532 | 2678 | if (fTestNet) |
2679 | { | |
a9d811a9 GM |
2680 | pchMessageStart[0] = 0x0b; |
2681 | pchMessageStart[1] = 0x11; | |
2682 | pchMessageStart[2] = 0x09; | |
2683 | pchMessageStart[3] = 0x07; | |
feeb761b | 2684 | hashGenesisBlock = uint256("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"); |
5cbf7532 | 2685 | } |
2686 | ||
0a61b0df | 2687 | // |
d979e6e3 | 2688 | // Load block index from databases |
0a61b0df | 2689 | // |
2d1fa42e | 2690 | if (!fReindex && !LoadBlockIndexDB()) |
0a61b0df | 2691 | return false; |
0a61b0df | 2692 | |
38603761 PW |
2693 | return true; |
2694 | } | |
2d1fa42e | 2695 | |
2d1fa42e | 2696 | |
38603761 PW |
2697 | bool InitBlockIndex() { |
2698 | // Check whether we're already initialized | |
2699 | if (pindexGenesisBlock != NULL) | |
2700 | return true; | |
2701 | ||
2702 | // Use the provided setting for -txindex in the new database | |
2703 | fTxIndex = GetBoolArg("-txindex", false); | |
2704 | pblocktree->WriteFlag("txindex", fTxIndex); | |
2705 | printf("Initializing databases...\n"); | |
2706 | ||
2707 | // Only add the genesis block if not reindexing (in which case we reuse the one already on disk) | |
2708 | if (!fReindex) { | |
0a61b0df | 2709 | // Genesis Block: |
2710 | // CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1) | |
2711 | // CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0) | |
2712 | // CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73) | |
2713 | // CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B) | |
2714 | // vMerkleTree: 4a5e1e | |
2715 | ||
2716 | // Genesis block | |
2717 | const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"; | |
2718 | CTransaction txNew; | |
2719 | txNew.vin.resize(1); | |
2720 | txNew.vout.resize(1); | |
2721 | txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); | |
2722 | txNew.vout[0].nValue = 50 * COIN; | |
2723 | txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; | |
2724 | CBlock block; | |
2725 | block.vtx.push_back(txNew); | |
2726 | block.hashPrevBlock = 0; | |
2727 | block.hashMerkleRoot = block.BuildMerkleTree(); | |
2728 | block.nVersion = 1; | |
2729 | block.nTime = 1231006505; | |
2730 | block.nBits = 0x1d00ffff; | |
2731 | block.nNonce = 2083236893; | |
2732 | ||
5cbf7532 | 2733 | if (fTestNet) |
2734 | { | |
98ba262a | 2735 | block.nTime = 1296688602; |
feeb761b | 2736 | block.nNonce = 414098458; |
5cbf7532 | 2737 | } |
0a61b0df | 2738 | |
5cbf7532 | 2739 | //// debug print |
630fd8dc PW |
2740 | uint256 hash = block.GetHash(); |
2741 | printf("%s\n", hash.ToString().c_str()); | |
5cbf7532 | 2742 | printf("%s\n", hashGenesisBlock.ToString().c_str()); |
2743 | printf("%s\n", block.hashMerkleRoot.ToString().c_str()); | |
2744 | assert(block.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); | |
2745 | block.print(); | |
630fd8dc | 2746 | assert(hash == hashGenesisBlock); |
0a61b0df | 2747 | |
2748 | // Start new block file | |
38603761 PW |
2749 | try { |
2750 | unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); | |
2751 | CDiskBlockPos blockPos; | |
2752 | CValidationState state; | |
2753 | if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.nTime)) | |
69e07747 | 2754 | return error("LoadBlockIndex() : FindBlockPos failed"); |
38603761 PW |
2755 | if (!block.WriteToDisk(blockPos)) |
2756 | return error("LoadBlockIndex() : writing genesis block to disk failed"); | |
2757 | if (!block.AddToBlockIndex(state, blockPos)) | |
2758 | return error("LoadBlockIndex() : genesis block not accepted"); | |
2759 | } catch(std::runtime_error &e) { | |
2760 | return error("LoadBlockIndex() : failed to initialize block database: %s", e.what()); | |
2761 | } | |
0a61b0df | 2762 | } |
2763 | ||
2764 | return true; | |
2765 | } | |
2766 | ||
2767 | ||
2768 | ||
2769 | void PrintBlockTree() | |
2770 | { | |
814efd6f | 2771 | // pre-compute tree structure |
0a61b0df | 2772 | map<CBlockIndex*, vector<CBlockIndex*> > mapNext; |
2773 | for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) | |
2774 | { | |
2775 | CBlockIndex* pindex = (*mi).second; | |
2776 | mapNext[pindex->pprev].push_back(pindex); | |
2777 | // test | |
2778 | //while (rand() % 3 == 0) | |
2779 | // mapNext[pindex->pprev].push_back(pindex); | |
2780 | } | |
2781 | ||
2782 | vector<pair<int, CBlockIndex*> > vStack; | |
2783 | vStack.push_back(make_pair(0, pindexGenesisBlock)); | |
2784 | ||
2785 | int nPrevCol = 0; | |
2786 | while (!vStack.empty()) | |
2787 | { | |
2788 | int nCol = vStack.back().first; | |
2789 | CBlockIndex* pindex = vStack.back().second; | |
2790 | vStack.pop_back(); | |
2791 | ||
2792 | // print split or gap | |
2793 | if (nCol > nPrevCol) | |
2794 | { | |
2795 | for (int i = 0; i < nCol-1; i++) | |
2796 | printf("| "); | |
2797 | printf("|\\\n"); | |
2798 | } | |
2799 | else if (nCol < nPrevCol) | |
2800 | { | |
2801 | for (int i = 0; i < nCol; i++) | |
2802 | printf("| "); | |
2803 | printf("|\n"); | |
64c7ee7e | 2804 | } |
0a61b0df | 2805 | nPrevCol = nCol; |
2806 | ||
2807 | // print columns | |
2808 | for (int i = 0; i < nCol; i++) | |
2809 | printf("| "); | |
2810 | ||
2811 | // print item | |
2812 | CBlock block; | |
2813 | block.ReadFromDisk(pindex); | |
450cbb09 | 2814 | printf("%d (blk%05u.dat:0x%x) %s tx %"PRIszu"", |
0a61b0df | 2815 | pindex->nHeight, |
5382bcf8 | 2816 | pindex->GetBlockPos().nFile, pindex->GetBlockPos().nPos, |
3f964b3c | 2817 | DateTimeStrFormat("%Y-%m-%d %H:%M:%S", block.GetBlockTime()).c_str(), |
0a61b0df | 2818 | block.vtx.size()); |
2819 | ||
64c7ee7e | 2820 | PrintWallets(block); |
0a61b0df | 2821 | |
814efd6f | 2822 | // put the main time-chain first |
0a61b0df | 2823 | vector<CBlockIndex*>& vNext = mapNext[pindex]; |
c376ac35 | 2824 | for (unsigned int i = 0; i < vNext.size(); i++) |
0a61b0df | 2825 | { |
0fe8010a | 2826 | if (vNext[i]->GetNextInMainChain()) |
0a61b0df | 2827 | { |
2828 | swap(vNext[0], vNext[i]); | |
2829 | break; | |
2830 | } | |
2831 | } | |
2832 | ||
2833 | // iterate children | |
c376ac35 | 2834 | for (unsigned int i = 0; i < vNext.size(); i++) |
0a61b0df | 2835 | vStack.push_back(make_pair(nCol+i, vNext[i])); |
2836 | } | |
2837 | } | |
2838 | ||
7fea4846 | 2839 | bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) |
1d740055 | 2840 | { |
746f502a PK |
2841 | int64 nStart = GetTimeMillis(); |
2842 | ||
1d740055 | 2843 | int nLoaded = 0; |
421218d3 | 2844 | try { |
05d97268 | 2845 | CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION); |
7fea4846 PW |
2846 | uint64 nStartByte = 0; |
2847 | if (dbp) { | |
2848 | // (try to) skip already indexed part | |
2849 | CBlockFileInfo info; | |
2850 | if (pblocktree->ReadBlockFileInfo(dbp->nFile, info)) { | |
2851 | nStartByte = info.nSize; | |
2852 | blkdat.Seek(info.nSize); | |
2853 | } | |
2854 | } | |
05d97268 | 2855 | uint64 nRewind = blkdat.GetPos(); |
21eb5ada GA |
2856 | while (blkdat.good() && !blkdat.eof()) { |
2857 | boost::this_thread::interruption_point(); | |
2858 | ||
05d97268 PW |
2859 | blkdat.SetPos(nRewind); |
2860 | nRewind++; // start one byte further next time, in case of failure | |
2861 | blkdat.SetLimit(); // remove former limit | |
7fea4846 | 2862 | unsigned int nSize = 0; |
05d97268 PW |
2863 | try { |
2864 | // locate a header | |
2865 | unsigned char buf[4]; | |
2866 | blkdat.FindByte(pchMessageStart[0]); | |
2867 | nRewind = blkdat.GetPos()+1; | |
2868 | blkdat >> FLATDATA(buf); | |
2869 | if (memcmp(buf, pchMessageStart, 4)) | |
2870 | continue; | |
2871 | // read size | |
1d740055 | 2872 | blkdat >> nSize; |
05d97268 PW |
2873 | if (nSize < 80 || nSize > MAX_BLOCK_SIZE) |
2874 | continue; | |
7fea4846 PW |
2875 | } catch (std::exception &e) { |
2876 | // no valid block header found; don't complain | |
2877 | break; | |
2878 | } | |
2879 | try { | |
05d97268 | 2880 | // read block |
7fea4846 PW |
2881 | uint64 nBlockPos = blkdat.GetPos(); |
2882 | blkdat.SetLimit(nBlockPos + nSize); | |
05d97268 PW |
2883 | CBlock block; |
2884 | blkdat >> block; | |
2885 | nRewind = blkdat.GetPos(); | |
7fea4846 PW |
2886 | |
2887 | // process block | |
2888 | if (nBlockPos >= nStartByte) { | |
66b02c93 | 2889 | LOCK(cs_main); |
7fea4846 PW |
2890 | if (dbp) |
2891 | dbp->nPos = nBlockPos; | |
ef3988ca PW |
2892 | CValidationState state; |
2893 | if (ProcessBlock(state, NULL, &block, dbp)) | |
1d740055 | 2894 | nLoaded++; |
ef3988ca PW |
2895 | if (state.IsError()) |
2896 | break; | |
1d740055 | 2897 | } |
05d97268 PW |
2898 | } catch (std::exception &e) { |
2899 | printf("%s() : Deserialize or I/O error caught during load\n", __PRETTY_FUNCTION__); | |
1d740055 PW |
2900 | } |
2901 | } | |
05d97268 | 2902 | fclose(fileIn); |
421218d3 PW |
2903 | } catch(std::runtime_error &e) { |
2904 | AbortNode(_("Error: system error: ") + e.what()); | |
1d740055 | 2905 | } |
7fea4846 PW |
2906 | if (nLoaded > 0) |
2907 | printf("Loaded %i blocks from external file in %"PRI64d"ms\n", nLoaded, GetTimeMillis() - nStart); | |
1d740055 PW |
2908 | return nLoaded > 0; |
2909 | } | |
0a61b0df | 2910 | |
66b02c93 | 2911 | |
0a61b0df | 2912 | |
2913 | ||
2914 | ||
2915 | ||
2916 | ||
2917 | ||
2918 | ||
2919 | ||
2920 | ////////////////////////////////////////////////////////////////////////////// | |
2921 | // | |
2922 | // CAlert | |
2923 | // | |
2924 | ||
f35c6c4f GA |
2925 | extern map<uint256, CAlert> mapAlerts; |
2926 | extern CCriticalSection cs_mapAlerts; | |
0a61b0df | 2927 | |
2928 | string GetWarnings(string strFor) | |
2929 | { | |
2930 | int nPriority = 0; | |
2931 | string strStatusBar; | |
2932 | string strRPC; | |
62e21fb5 | 2933 | |
bdde31d7 | 2934 | if (GetBoolArg("-testsafemode")) |
0a61b0df | 2935 | strRPC = "test"; |
2936 | ||
62e21fb5 WL |
2937 | if (!CLIENT_VERSION_IS_RELEASE) |
2938 | strStatusBar = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications"); | |
2939 | ||
0a61b0df | 2940 | // Misc warnings like out of disk space and clock is wrong |
2941 | if (strMiscWarning != "") | |
2942 | { | |
2943 | nPriority = 1000; | |
2944 | strStatusBar = strMiscWarning; | |
2945 | } | |
2946 | ||
2947 | // Longer invalid proof-of-work chain | |
1657c4bc | 2948 | if (pindexBest && nBestInvalidWork > nBestChainWork + (pindexBest->GetBlockWork() * 6).getuint256()) |
0a61b0df | 2949 | { |
2950 | nPriority = 2000; | |
e6bc9c35 | 2951 | strStatusBar = strRPC = _("Warning: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade."); |
0a61b0df | 2952 | } |
2953 | ||
2954 | // Alerts | |
0a61b0df | 2955 | { |
f8dcd5ca | 2956 | LOCK(cs_mapAlerts); |
223b6f1b | 2957 | BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts) |
0a61b0df | 2958 | { |
2959 | const CAlert& alert = item.second; | |
2960 | if (alert.AppliesToMe() && alert.nPriority > nPriority) | |
2961 | { | |
2962 | nPriority = alert.nPriority; | |
2963 | strStatusBar = alert.strStatusBar; | |
0a61b0df | 2964 | } |
2965 | } | |
2966 | } | |
2967 | ||
2968 | if (strFor == "statusbar") | |
2969 | return strStatusBar; | |
2970 | else if (strFor == "rpc") | |
2971 | return strRPC; | |
ecf1c79a | 2972 | assert(!"GetWarnings() : invalid parameter"); |
0a61b0df | 2973 | return "error"; |
2974 | } | |
2975 | ||
0a61b0df | 2976 | |
2977 | ||
2978 | ||
2979 | ||
2980 | ||
2981 | ||
2982 | ||
2983 | ////////////////////////////////////////////////////////////////////////////// | |
2984 | // | |
2985 | // Messages | |
2986 | // | |
2987 | ||
2988 | ||
ae8bfd12 | 2989 | bool static AlreadyHave(const CInv& inv) |
0a61b0df | 2990 | { |
2991 | switch (inv.type) | |
2992 | { | |
8deb9822 JG |
2993 | case MSG_TX: |
2994 | { | |
450cbb09 | 2995 | bool txInMap = false; |
ce8c9349 | 2996 | { |
450cbb09 PW |
2997 | LOCK(mempool.cs); |
2998 | txInMap = mempool.exists(inv.hash); | |
ce8c9349 | 2999 | } |
450cbb09 | 3000 | return txInMap || mapOrphanTransactions.count(inv.hash) || |
ae8bfd12 | 3001 | pcoinsTip->HaveCoins(inv.hash); |
8deb9822 | 3002 | } |
8deb9822 JG |
3003 | case MSG_BLOCK: |
3004 | return mapBlockIndex.count(inv.hash) || | |
3005 | mapOrphanBlocks.count(inv.hash); | |
0a61b0df | 3006 | } |
3007 | // Don't know what it is, just say we already got one | |
3008 | return true; | |
3009 | } | |
3010 | ||
3011 | ||
3012 | ||
3013 | ||
5cbf7532 | 3014 | // The message start string is designed to be unlikely to occur in normal data. |
814efd6f | 3015 | // The characters are rarely used upper ASCII, not valid as UTF-8, and produce |
5cbf7532 | 3016 | // a large 4-byte int at any alignment. |
25133bd7 | 3017 | unsigned char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 }; |
0a61b0df | 3018 | |
3019 | ||
c7f039b6 PW |
3020 | void static ProcessGetData(CNode* pfrom) |
3021 | { | |
3022 | std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin(); | |
3023 | ||
3024 | vector<CInv> vNotFound; | |
3025 | ||
3026 | while (it != pfrom->vRecvGetData.end()) { | |
3027 | // Don't bother if send buffer is too full to respond anyway | |
3028 | if (pfrom->nSendSize >= SendBufferSize()) | |
3029 | break; | |
3030 | ||
3031 | const CInv &inv = *it; | |
3032 | { | |
b31499ec | 3033 | boost::this_thread::interruption_point(); |
c7f039b6 PW |
3034 | it++; |
3035 | ||
3036 | if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK) | |
3037 | { | |
3038 | // Send block from disk | |
3039 | map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(inv.hash); | |
3040 | if (mi != mapBlockIndex.end()) | |
3041 | { | |
3042 | CBlock block; | |
3043 | block.ReadFromDisk((*mi).second); | |
3044 | if (inv.type == MSG_BLOCK) | |
3045 | pfrom->PushMessage("block", block); | |
3046 | else // MSG_FILTERED_BLOCK) | |
3047 | { | |
3048 | LOCK(pfrom->cs_filter); | |
3049 | if (pfrom->pfilter) | |
3050 | { | |
3051 | CMerkleBlock merkleBlock(block, *pfrom->pfilter); | |
3052 | pfrom->PushMessage("merkleblock", merkleBlock); | |
3053 | // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see | |
3054 | // This avoids hurting performance by pointlessly requiring a round-trip | |
3055 | // Note that there is currently no way for a node to request any single transactions we didnt send here - | |
3056 | // they must either disconnect and retry or request the full block. | |
3057 | // Thus, the protocol spec specified allows for us to provide duplicate txn here, | |
3058 | // however we MUST always provide at least what the remote peer needs | |
3059 | typedef std::pair<unsigned int, uint256> PairType; | |
3060 | BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn) | |
3061 | if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, pair.second))) | |
3062 | pfrom->PushMessage("tx", block.vtx[pair.first]); | |
3063 | } | |
3064 | // else | |
3065 | // no response | |
3066 | } | |
3067 | ||
3068 | // Trigger them to send a getblocks request for the next batch of inventory | |
3069 | if (inv.hash == pfrom->hashContinue) | |
3070 | { | |
3071 | // Bypass PushInventory, this must send even if redundant, | |
3072 | // and we want it right after the last block so they don't | |
3073 | // wait for other stuff first. | |
3074 | vector<CInv> vInv; | |
3075 | vInv.push_back(CInv(MSG_BLOCK, hashBestChain)); | |
3076 | pfrom->PushMessage("inv", vInv); | |
3077 | pfrom->hashContinue = 0; | |
3078 | } | |
3079 | } | |
3080 | } | |
3081 | else if (inv.IsKnownType()) | |
3082 | { | |
3083 | // Send stream from relay memory | |
3084 | bool pushed = false; | |
3085 | { | |
3086 | LOCK(cs_mapRelay); | |
3087 | map<CInv, CDataStream>::iterator mi = mapRelay.find(inv); | |
3088 | if (mi != mapRelay.end()) { | |
3089 | pfrom->PushMessage(inv.GetCommand(), (*mi).second); | |
3090 | pushed = true; | |
3091 | } | |
3092 | } | |
3093 | if (!pushed && inv.type == MSG_TX) { | |
3094 | LOCK(mempool.cs); | |
3095 | if (mempool.exists(inv.hash)) { | |
3096 | CTransaction tx = mempool.lookup(inv.hash); | |
3097 | CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); | |
3098 | ss.reserve(1000); | |
3099 | ss << tx; | |
3100 | pfrom->PushMessage("tx", ss); | |
3101 | pushed = true; | |
3102 | } | |
3103 | } | |
3104 | if (!pushed) { | |
3105 | vNotFound.push_back(inv); | |
3106 | } | |
3107 | } | |
3108 | ||
3109 | // Track requests for our stuff. | |
3110 | Inventory(inv.hash); | |
3111 | } | |
3112 | } | |
3113 | ||
3114 | pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it); | |
3115 | ||
3116 | if (!vNotFound.empty()) { | |
3117 | // Let the peer know that we didn't find what it asked for, so it doesn't | |
3118 | // have to wait around forever. Currently only SPV clients actually care | |
3119 | // about this message: it's needed when they are recursively walking the | |
3120 | // dependencies of relevant unconfirmed transactions. SPV clients want to | |
3121 | // do that because they want to know about (and store and rebroadcast and | |
3122 | // risk analyze) the dependencies of transactions relevant to them, without | |
3123 | // having to download the entire memory pool. | |
3124 | pfrom->PushMessage("notfound", vNotFound); | |
3125 | } | |
3126 | } | |
3127 | ||
64c7ee7e | 3128 | bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) |
0a61b0df | 3129 | { |
0a61b0df | 3130 | RandAddSeedPerfmon(); |
0985816b | 3131 | if (fDebug) |
d210f4f5 | 3132 | printf("received: %s (%"PRIszu" bytes)\n", strCommand.c_str(), vRecv.size()); |
0a61b0df | 3133 | if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) |
3134 | { | |
3135 | printf("dropmessagestest DROPPING RECV MESSAGE\n"); | |
3136 | return true; | |
3137 | } | |
3138 | ||
3139 | ||
3140 | ||
3141 | ||
3142 | ||
3143 | if (strCommand == "version") | |
3144 | { | |
3145 | // Each connection can only send one version message | |
3146 | if (pfrom->nVersion != 0) | |
806704c2 GA |
3147 | { |
3148 | pfrom->Misbehaving(1); | |
0a61b0df | 3149 | return false; |
806704c2 | 3150 | } |
0a61b0df | 3151 | |
bde280b9 | 3152 | int64 nTime; |
0a61b0df | 3153 | CAddress addrMe; |
3154 | CAddress addrFrom; | |
bde280b9 | 3155 | uint64 nNonce = 1; |
0a61b0df | 3156 | vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe; |
8b09cd3a | 3157 | if (pfrom->nVersion < MIN_PROTO_VERSION) |
18c0fa97 | 3158 | { |
27adfb2e | 3159 | // Since February 20, 2012, the protocol is initiated at version 209, |
18c0fa97 PW |
3160 | // and earlier versions are no longer supported |
3161 | printf("partner %s using obsolete version %i; disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion); | |
3162 | pfrom->fDisconnect = true; | |
3163 | return false; | |
3164 | } | |
3165 | ||
0a61b0df | 3166 | if (pfrom->nVersion == 10300) |
3167 | pfrom->nVersion = 300; | |
18c0fa97 | 3168 | if (!vRecv.empty()) |
0a61b0df | 3169 | vRecv >> addrFrom >> nNonce; |
18c0fa97 | 3170 | if (!vRecv.empty()) |
0a61b0df | 3171 | vRecv >> pfrom->strSubVer; |
18c0fa97 | 3172 | if (!vRecv.empty()) |
0a61b0df | 3173 | vRecv >> pfrom->nStartingHeight; |
4c8fc1a5 MC |
3174 | if (!vRecv.empty()) |
3175 | vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message | |
3176 | else | |
3177 | pfrom->fRelayTxes = true; | |
0a61b0df | 3178 | |
39857190 PW |
3179 | if (pfrom->fInbound && addrMe.IsRoutable()) |
3180 | { | |
3181 | pfrom->addrLocal = addrMe; | |
3182 | SeenLocal(addrMe); | |
3183 | } | |
3184 | ||
0a61b0df | 3185 | // Disconnect if we connected to ourself |
3186 | if (nNonce == nLocalHostNonce && nNonce > 1) | |
3187 | { | |
b22c8842 | 3188 | printf("connected to self at %s, disconnecting\n", pfrom->addr.ToString().c_str()); |
0a61b0df | 3189 | pfrom->fDisconnect = true; |
3190 | return true; | |
3191 | } | |
3192 | ||
cbc920d4 GA |
3193 | // Be shy and don't send version until we hear |
3194 | if (pfrom->fInbound) | |
3195 | pfrom->PushVersion(); | |
3196 | ||
0a61b0df | 3197 | pfrom->fClient = !(pfrom->nServices & NODE_NETWORK); |
0a61b0df | 3198 | |
67a42f92 | 3199 | AddTimeData(pfrom->addr, nTime); |
0a61b0df | 3200 | |
3201 | // Change version | |
18c0fa97 | 3202 | pfrom->PushMessage("verack"); |
41b052ad | 3203 | pfrom->ssSend.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION)); |
0a61b0df | 3204 | |
c891967b | 3205 | if (!pfrom->fInbound) |
3206 | { | |
3207 | // Advertise our address | |
587f929c | 3208 | if (!fNoListen && !IsInitialBlockDownload()) |
c891967b | 3209 | { |
39857190 PW |
3210 | CAddress addr = GetLocalAddress(&pfrom->addr); |
3211 | if (addr.IsRoutable()) | |
3212 | pfrom->PushAddress(addr); | |
c891967b | 3213 | } |
3214 | ||
3215 | // Get recent addresses | |
478b01d9 | 3216 | if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000) |
c891967b | 3217 | { |
3218 | pfrom->PushMessage("getaddr"); | |
3219 | pfrom->fGetAddr = true; | |
3220 | } | |
5fee401f PW |
3221 | addrman.Good(pfrom->addr); |
3222 | } else { | |
3223 | if (((CNetAddr)pfrom->addr) == (CNetAddr)addrFrom) | |
3224 | { | |
3225 | addrman.Add(addrFrom, addrFrom); | |
3226 | addrman.Good(addrFrom); | |
3227 | } | |
c891967b | 3228 | } |
3229 | ||
0a61b0df | 3230 | // Relay alerts |
f8dcd5ca PW |
3231 | { |
3232 | LOCK(cs_mapAlerts); | |
223b6f1b | 3233 | BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts) |
0a61b0df | 3234 | item.second.RelayTo(pfrom); |
f8dcd5ca | 3235 | } |
0a61b0df | 3236 | |
3237 | pfrom->fSuccessfullyConnected = true; | |
3238 | ||
863e995b | 3239 | printf("receive version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", pfrom->nVersion, pfrom->nStartingHeight, addrMe.ToString().c_str(), addrFrom.ToString().c_str(), pfrom->addr.ToString().c_str()); |
a8b95ce6 WL |
3240 | |
3241 | cPeerBlockCounts.input(pfrom->nStartingHeight); | |
0a61b0df | 3242 | } |
3243 | ||
3244 | ||
3245 | else if (pfrom->nVersion == 0) | |
3246 | { | |
3247 | // Must have a version message before anything else | |
806704c2 | 3248 | pfrom->Misbehaving(1); |
0a61b0df | 3249 | return false; |
3250 | } | |
3251 | ||
3252 | ||
3253 | else if (strCommand == "verack") | |
3254 | { | |
607dbfde | 3255 | pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION)); |
0a61b0df | 3256 | } |
3257 | ||
3258 | ||
3259 | else if (strCommand == "addr") | |
3260 | { | |
3261 | vector<CAddress> vAddr; | |
3262 | vRecv >> vAddr; | |
c891967b | 3263 | |
3264 | // Don't want addr from older versions unless seeding | |
8b09cd3a | 3265 | if (pfrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000) |
0a61b0df | 3266 | return true; |
3267 | if (vAddr.size() > 1000) | |
806704c2 GA |
3268 | { |
3269 | pfrom->Misbehaving(20); | |
d210f4f5 | 3270 | return error("message addr size() = %"PRIszu"", vAddr.size()); |
806704c2 | 3271 | } |
0a61b0df | 3272 | |
3273 | // Store the new addresses | |
090e5b40 | 3274 | vector<CAddress> vAddrOk; |
bde280b9 WL |
3275 | int64 nNow = GetAdjustedTime(); |
3276 | int64 nSince = nNow - 10 * 60; | |
223b6f1b | 3277 | BOOST_FOREACH(CAddress& addr, vAddr) |
0a61b0df | 3278 | { |
b31499ec GA |
3279 | boost::this_thread::interruption_point(); |
3280 | ||
c891967b | 3281 | if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60) |
3282 | addr.nTime = nNow - 5 * 24 * 60 * 60; | |
0a61b0df | 3283 | pfrom->AddAddressKnown(addr); |
090e5b40 | 3284 | bool fReachable = IsReachable(addr); |
c891967b | 3285 | if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable()) |
0a61b0df | 3286 | { |
3287 | // Relay to a limited number of other nodes | |
0a61b0df | 3288 | { |
f8dcd5ca | 3289 | LOCK(cs_vNodes); |
5cbf7532 | 3290 | // Use deterministic randomness to send to the same nodes for 24 hours |
3291 | // at a time so the setAddrKnowns of the chosen nodes prevent repeats | |
0a61b0df | 3292 | static uint256 hashSalt; |
3293 | if (hashSalt == 0) | |
f718aedd | 3294 | hashSalt = GetRandHash(); |
4843b55f | 3295 | uint64 hashAddr = addr.GetHash(); |
67a42f92 | 3296 | uint256 hashRand = hashSalt ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60)); |
5cbf7532 | 3297 | hashRand = Hash(BEGIN(hashRand), END(hashRand)); |
0a61b0df | 3298 | multimap<uint256, CNode*> mapMix; |
223b6f1b | 3299 | BOOST_FOREACH(CNode* pnode, vNodes) |
5cbf7532 | 3300 | { |
8b09cd3a | 3301 | if (pnode->nVersion < CADDR_TIME_VERSION) |
c891967b | 3302 | continue; |
5cbf7532 | 3303 | unsigned int nPointer; |
3304 | memcpy(&nPointer, &pnode, sizeof(nPointer)); | |
3305 | uint256 hashKey = hashRand ^ nPointer; | |
3306 | hashKey = Hash(BEGIN(hashKey), END(hashKey)); | |
3307 | mapMix.insert(make_pair(hashKey, pnode)); | |
3308 | } | |
090e5b40 | 3309 | int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s) |
0a61b0df | 3310 | for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi) |
3311 | ((*mi).second)->PushAddress(addr); | |
3312 | } | |
3313 | } | |
090e5b40 PW |
3314 | // Do not store addresses outside our network |
3315 | if (fReachable) | |
3316 | vAddrOk.push_back(addr); | |
0a61b0df | 3317 | } |
090e5b40 | 3318 | addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60); |
0a61b0df | 3319 | if (vAddr.size() < 1000) |
3320 | pfrom->fGetAddr = false; | |
478b01d9 PW |
3321 | if (pfrom->fOneShot) |
3322 | pfrom->fDisconnect = true; | |
0a61b0df | 3323 | } |
3324 | ||
3325 | ||
3326 | else if (strCommand == "inv") | |
3327 | { | |
3328 | vector<CInv> vInv; | |
3329 | vRecv >> vInv; | |
05a85b2b | 3330 | if (vInv.size() > MAX_INV_SZ) |
806704c2 GA |
3331 | { |
3332 | pfrom->Misbehaving(20); | |
d210f4f5 | 3333 | return error("message inv size() = %"PRIszu"", vInv.size()); |
806704c2 | 3334 | } |
0a61b0df | 3335 | |
68601333 PW |
3336 | // find last block in inv vector |
3337 | unsigned int nLastBlock = (unsigned int)(-1); | |
3338 | for (unsigned int nInv = 0; nInv < vInv.size(); nInv++) { | |
385f730f | 3339 | if (vInv[vInv.size() - 1 - nInv].type == MSG_BLOCK) { |
68601333 | 3340 | nLastBlock = vInv.size() - 1 - nInv; |
385f730f PW |
3341 | break; |
3342 | } | |
68601333 | 3343 | } |
c376ac35 | 3344 | for (unsigned int nInv = 0; nInv < vInv.size(); nInv++) |
0a61b0df | 3345 | { |
0aa89c08 PW |
3346 | const CInv &inv = vInv[nInv]; |
3347 | ||
b31499ec | 3348 | boost::this_thread::interruption_point(); |
0a61b0df | 3349 | pfrom->AddInventoryKnown(inv); |
3350 | ||
ae8bfd12 | 3351 | bool fAlreadyHave = AlreadyHave(inv); |
59090133 NS |
3352 | if (fDebug) |
3353 | printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new"); | |
0a61b0df | 3354 | |
66b02c93 | 3355 | if (!fAlreadyHave) { |
7fea4846 | 3356 | if (!fImporting && !fReindex) |
66b02c93 PW |
3357 | pfrom->AskFor(inv); |
3358 | } else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) { | |
0a61b0df | 3359 | pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash])); |
385f730f PW |
3360 | } else if (nInv == nLastBlock) { |
3361 | // In case we are on a very long side-chain, it is possible that we already have | |
3362 | // the last block in an inv bundle sent in response to getblocks. Try to detect | |
3363 | // this situation and push another getblocks to continue. | |
385f730f PW |
3364 | pfrom->PushGetBlocks(mapBlockIndex[inv.hash], uint256(0)); |
3365 | if (fDebug) | |
3366 | printf("force request: %s\n", inv.ToString().c_str()); | |
3367 | } | |
0a61b0df | 3368 | |
3369 | // Track requests for our stuff | |
64c7ee7e | 3370 | Inventory(inv.hash); |
0a61b0df | 3371 | } |
3372 | } | |
3373 | ||
3374 | ||
3375 | else if (strCommand == "getdata") | |
3376 | { | |
3377 | vector<CInv> vInv; | |
3378 | vRecv >> vInv; | |
05a85b2b | 3379 | if (vInv.size() > MAX_INV_SZ) |
806704c2 GA |
3380 | { |
3381 | pfrom->Misbehaving(20); | |
d210f4f5 | 3382 | return error("message getdata size() = %"PRIszu"", vInv.size()); |
806704c2 | 3383 | } |
0a61b0df | 3384 | |
983e4bde | 3385 | if (fDebugNet || (vInv.size() != 1)) |
d210f4f5 | 3386 | printf("received getdata (%"PRIszu" invsz)\n", vInv.size()); |
983e4bde | 3387 | |
c7f039b6 PW |
3388 | if ((fDebugNet && vInv.size() > 0) || (vInv.size() == 1)) |
3389 | printf("received getdata for: %s\n", vInv[0].ToString().c_str()); | |
0a61b0df | 3390 | |
c7f039b6 PW |
3391 | pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end()); |
3392 | ProcessGetData(pfrom); | |
0a61b0df | 3393 | } |
3394 | ||
3395 | ||
3396 | else if (strCommand == "getblocks") | |
3397 | { | |
3398 | CBlockLocator locator; | |
3399 | uint256 hashStop; | |
3400 | vRecv >> locator >> hashStop; | |
3401 | ||
f03304a9 | 3402 | // Find the last block the caller has in the main chain |
0a61b0df | 3403 | CBlockIndex* pindex = locator.GetBlockIndex(); |
3404 | ||
3405 | // Send the rest of the chain | |
3406 | if (pindex) | |
0fe8010a | 3407 | pindex = pindex->GetNextInMainChain(); |
9d6cd04b | 3408 | int nLimit = 500; |
1c06aa98 | 3409 | printf("getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().c_str(), nLimit); |
0fe8010a | 3410 | for (; pindex; pindex = pindex->GetNextInMainChain()) |
0a61b0df | 3411 | { |
3412 | if (pindex->GetBlockHash() == hashStop) | |
3413 | { | |
1c06aa98 | 3414 | printf(" getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); |
0a61b0df | 3415 | break; |
3416 | } | |
3417 | pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash())); | |
9d6cd04b | 3418 | if (--nLimit <= 0) |
0a61b0df | 3419 | { |
3420 | // When this block is requested, we'll send an inv that'll make them | |
3421 | // getblocks the next batch of inventory. | |
1c06aa98 | 3422 | printf(" getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); |
0a61b0df | 3423 | pfrom->hashContinue = pindex->GetBlockHash(); |
3424 | break; | |
3425 | } | |
3426 | } | |
3427 | } | |
3428 | ||
3429 | ||
f03304a9 | 3430 | else if (strCommand == "getheaders") |
3431 | { | |
3432 | CBlockLocator locator; | |
3433 | uint256 hashStop; | |
3434 | vRecv >> locator >> hashStop; | |
3435 | ||
3436 | CBlockIndex* pindex = NULL; | |
3437 | if (locator.IsNull()) | |
3438 | { | |
3439 | // If locator is null, return the hashStop block | |
3440 | map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashStop); | |
3441 | if (mi == mapBlockIndex.end()) | |
3442 | return true; | |
3443 | pindex = (*mi).second; | |
3444 | } | |
3445 | else | |
3446 | { | |
3447 | // Find the last block the caller has in the main chain | |
3448 | pindex = locator.GetBlockIndex(); | |
3449 | if (pindex) | |
0fe8010a | 3450 | pindex = pindex->GetNextInMainChain(); |
f03304a9 | 3451 | } |
3452 | ||
e754cf41 | 3453 | // we must use CBlocks, as CBlockHeaders won't include the 0x00 nTx count at the end |
f03304a9 | 3454 | vector<CBlock> vHeaders; |
ecf07f27 | 3455 | int nLimit = 2000; |
1c06aa98 | 3456 | printf("getheaders %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().c_str()); |
0fe8010a | 3457 | for (; pindex; pindex = pindex->GetNextInMainChain()) |
f03304a9 | 3458 | { |
3459 | vHeaders.push_back(pindex->GetBlockHeader()); | |
3460 | if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop) | |
3461 | break; | |
3462 | } | |
3463 | pfrom->PushMessage("headers", vHeaders); | |
3464 | } | |
3465 | ||
3466 | ||
0a61b0df | 3467 | else if (strCommand == "tx") |
3468 | { | |
3469 | vector<uint256> vWorkQueue; | |
7a15109c | 3470 | vector<uint256> vEraseQueue; |
0a61b0df | 3471 | CDataStream vMsg(vRecv); |
3472 | CTransaction tx; | |
3473 | vRecv >> tx; | |
3474 | ||
3475 | CInv inv(MSG_TX, tx.GetHash()); | |
3476 | pfrom->AddInventoryKnown(inv); | |
3477 | ||
3478 | bool fMissingInputs = false; | |
ef3988ca PW |
3479 | CValidationState state; |
3480 | if (tx.AcceptToMemoryPool(state, true, true, &fMissingInputs)) | |
0a61b0df | 3481 | { |
269d9c64 | 3482 | RelayTransaction(tx, inv.hash, vMsg); |
0a61b0df | 3483 | mapAlreadyAskedFor.erase(inv); |
3484 | vWorkQueue.push_back(inv.hash); | |
7a15109c | 3485 | vEraseQueue.push_back(inv.hash); |
0a61b0df | 3486 | |
3487 | // Recursively process any orphan transactions that depended on this one | |
c376ac35 | 3488 | for (unsigned int i = 0; i < vWorkQueue.size(); i++) |
0a61b0df | 3489 | { |
3490 | uint256 hashPrev = vWorkQueue[i]; | |
77b99cf7 GA |
3491 | for (map<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev[hashPrev].begin(); |
3492 | mi != mapOrphanTransactionsByPrev[hashPrev].end(); | |
0a61b0df | 3493 | ++mi) |
3494 | { | |
3495 | const CDataStream& vMsg = *((*mi).second); | |
3496 | CTransaction tx; | |
3497 | CDataStream(vMsg) >> tx; | |
3498 | CInv inv(MSG_TX, tx.GetHash()); | |
7a15109c | 3499 | bool fMissingInputs2 = false; |
8c4e4313 LD |
3500 | // 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) |
3501 | CValidationState stateDummy; | |
0a61b0df | 3502 | |
8c4e4313 | 3503 | if (tx.AcceptToMemoryPool(stateDummy, true, true, &fMissingInputs2)) |
0a61b0df | 3504 | { |
1c06aa98 | 3505 | printf(" accepted orphan tx %s\n", inv.hash.ToString().c_str()); |
269d9c64 | 3506 | RelayTransaction(tx, inv.hash, vMsg); |
0a61b0df | 3507 | mapAlreadyAskedFor.erase(inv); |
3508 | vWorkQueue.push_back(inv.hash); | |
7a15109c GA |
3509 | vEraseQueue.push_back(inv.hash); |
3510 | } | |
3511 | else if (!fMissingInputs2) | |
3512 | { | |
ce99358f | 3513 | // invalid or too-little-fee orphan |
7a15109c | 3514 | vEraseQueue.push_back(inv.hash); |
1c06aa98 | 3515 | printf(" removed orphan tx %s\n", inv.hash.ToString().c_str()); |
0a61b0df | 3516 | } |
3517 | } | |
3518 | } | |
3519 | ||
7a15109c | 3520 | BOOST_FOREACH(uint256 hash, vEraseQueue) |
0a61b0df | 3521 | EraseOrphanTx(hash); |
3522 | } | |
3523 | else if (fMissingInputs) | |
3524 | { | |
0a61b0df | 3525 | AddOrphanTx(vMsg); |
142e6041 GA |
3526 | |
3527 | // DoS prevention: do not allow mapOrphanTransactions to grow unbounded | |
7bd9c3a3 | 3528 | unsigned int nEvicted = LimitOrphanTxSize(MAX_ORPHAN_TRANSACTIONS); |
142e6041 | 3529 | if (nEvicted > 0) |
7bd9c3a3 | 3530 | printf("mapOrphan overflow, removed %u tx\n", nEvicted); |
0a61b0df | 3531 | } |
ef3988ca PW |
3532 | int nDoS; |
3533 | if (state.IsInvalid(nDoS)) | |
3534 | pfrom->Misbehaving(nDoS); | |
0a61b0df | 3535 | } |
3536 | ||
3537 | ||
7fea4846 | 3538 | else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing |
0a61b0df | 3539 | { |
f03304a9 | 3540 | CBlock block; |
3541 | vRecv >> block; | |
0a61b0df | 3542 | |
1c06aa98 | 3543 | printf("received block %s\n", block.GetHash().ToString().c_str()); |
f03304a9 | 3544 | // block.print(); |
0a61b0df | 3545 | |
f03304a9 | 3546 | CInv inv(MSG_BLOCK, block.GetHash()); |
0a61b0df | 3547 | pfrom->AddInventoryKnown(inv); |
3548 | ||
ef3988ca PW |
3549 | CValidationState state; |
3550 | if (ProcessBlock(state, pfrom, &block)) | |
0a61b0df | 3551 | mapAlreadyAskedFor.erase(inv); |
ef3988ca PW |
3552 | int nDoS; |
3553 | if (state.IsInvalid(nDoS)) | |
3554 | pfrom->Misbehaving(nDoS); | |
0a61b0df | 3555 | } |
3556 | ||
3557 | ||
3558 | else if (strCommand == "getaddr") | |
3559 | { | |
0a61b0df | 3560 | pfrom->vAddrToSend.clear(); |
5fee401f PW |
3561 | vector<CAddress> vAddr = addrman.GetAddr(); |
3562 | BOOST_FOREACH(const CAddress &addr, vAddr) | |
3563 | pfrom->PushAddress(addr); | |
0a61b0df | 3564 | } |
3565 | ||
3566 | ||
05a85b2b JG |
3567 | else if (strCommand == "mempool") |
3568 | { | |
3569 | std::vector<uint256> vtxid; | |
c51694eb | 3570 | LOCK2(mempool.cs, pfrom->cs_filter); |
05a85b2b JG |
3571 | mempool.queryHashes(vtxid); |
3572 | vector<CInv> vInv; | |
c51694eb MC |
3573 | BOOST_FOREACH(uint256& hash, vtxid) { |
3574 | CInv inv(MSG_TX, hash); | |
3575 | if ((pfrom->pfilter && pfrom->pfilter->IsRelevantAndUpdate(mempool.lookup(hash), hash)) || | |
3576 | (!pfrom->pfilter)) | |
3577 | vInv.push_back(inv); | |
3578 | if (vInv.size() == MAX_INV_SZ) | |
3579 | break; | |
05a85b2b JG |
3580 | } |
3581 | if (vInv.size() > 0) | |
3582 | pfrom->PushMessage("inv", vInv); | |
3583 | } | |
3584 | ||
3585 | ||
0a61b0df | 3586 | else if (strCommand == "ping") |
3587 | { | |
93e447b6 JG |
3588 | if (pfrom->nVersion > BIP0031_VERSION) |
3589 | { | |
3590 | uint64 nonce = 0; | |
3591 | vRecv >> nonce; | |
3592 | // Echo the message back with the nonce. This allows for two useful features: | |
3593 | // | |
3594 | // 1) A remote node can quickly check if the connection is operational | |
3595 | // 2) Remote nodes can measure the latency of the network thread. If this node | |
3596 | // is overloaded it won't respond to pings quickly and the remote node can | |
3597 | // avoid sending us more work, like chain download requests. | |
3598 | // | |
3599 | // The nonce stops the remote getting confused between different pings: without | |
3600 | // it, if the remote node sends a ping once per second and this node takes 5 | |
3601 | // seconds to respond to each, the 5th ping the remote sends would appear to | |
3602 | // return very quickly. | |
3603 | pfrom->PushMessage("pong", nonce); | |
3604 | } | |
0a61b0df | 3605 | } |
3606 | ||
3607 | ||
3608 | else if (strCommand == "alert") | |
3609 | { | |
3610 | CAlert alert; | |
3611 | vRecv >> alert; | |
3612 | ||
d5a52d9b GA |
3613 | uint256 alertHash = alert.GetHash(); |
3614 | if (pfrom->setKnown.count(alertHash) == 0) | |
0a61b0df | 3615 | { |
d5a52d9b | 3616 | if (alert.ProcessAlert()) |
f8dcd5ca | 3617 | { |
d5a52d9b GA |
3618 | // Relay |
3619 | pfrom->setKnown.insert(alertHash); | |
3620 | { | |
3621 | LOCK(cs_vNodes); | |
3622 | BOOST_FOREACH(CNode* pnode, vNodes) | |
3623 | alert.RelayTo(pnode); | |
3624 | } | |
3625 | } | |
3626 | else { | |
3627 | // Small DoS penalty so peers that send us lots of | |
3628 | // duplicate/expired/invalid-signature/whatever alerts | |
3629 | // eventually get banned. | |
3630 | // This isn't a Misbehaving(100) (immediate ban) because the | |
3631 | // peer might be an older or different implementation with | |
3632 | // a different signature key, etc. | |
3633 | pfrom->Misbehaving(10); | |
f8dcd5ca | 3634 | } |
0a61b0df | 3635 | } |
3636 | } | |
3637 | ||
3638 | ||
422d1225 MC |
3639 | else if (strCommand == "filterload") |
3640 | { | |
3641 | CBloomFilter filter; | |
3642 | vRecv >> filter; | |
3643 | ||
3644 | if (!filter.IsWithinSizeConstraints()) | |
3645 | // There is no excuse for sending a too-large filter | |
3646 | pfrom->Misbehaving(100); | |
3647 | else | |
3648 | { | |
3649 | LOCK(pfrom->cs_filter); | |
3650 | delete pfrom->pfilter; | |
3651 | pfrom->pfilter = new CBloomFilter(filter); | |
3652 | } | |
4c8fc1a5 | 3653 | pfrom->fRelayTxes = true; |
422d1225 MC |
3654 | } |
3655 | ||
3656 | ||
3657 | else if (strCommand == "filteradd") | |
3658 | { | |
3659 | vector<unsigned char> vData; | |
3660 | vRecv >> vData; | |
3661 | ||
3662 | // Nodes must NEVER send a data item > 520 bytes (the max size for a script data object, | |
3663 | // and thus, the maximum size any matched object can have) in a filteradd message | |
192cc910 | 3664 | if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE) |
422d1225 MC |
3665 | { |
3666 | pfrom->Misbehaving(100); | |
3667 | } else { | |
3668 | LOCK(pfrom->cs_filter); | |
3669 | if (pfrom->pfilter) | |
3670 | pfrom->pfilter->insert(vData); | |
3671 | else | |
3672 | pfrom->Misbehaving(100); | |
3673 | } | |
3674 | } | |
3675 | ||
3676 | ||
3677 | else if (strCommand == "filterclear") | |
3678 | { | |
3679 | LOCK(pfrom->cs_filter); | |
3680 | delete pfrom->pfilter; | |
3681 | pfrom->pfilter = NULL; | |
4c8fc1a5 | 3682 | pfrom->fRelayTxes = true; |
422d1225 MC |
3683 | } |
3684 | ||
3685 | ||
0a61b0df | 3686 | else |
3687 | { | |
3688 | // Ignore unknown commands for extensibility | |
3689 | } | |
3690 | ||
3691 | ||
3692 | // Update the last seen time for this node's address | |
3693 | if (pfrom->fNetworkNode) | |
3694 | if (strCommand == "version" || strCommand == "addr" || strCommand == "inv" || strCommand == "getdata" || strCommand == "ping") | |
3695 | AddressCurrentlyConnected(pfrom->addr); | |
3696 | ||
3697 | ||
3698 | return true; | |
3699 | } | |
3700 | ||
607dbfde | 3701 | // requires LOCK(cs_vRecvMsg) |
e89b9f6a PW |
3702 | bool ProcessMessages(CNode* pfrom) |
3703 | { | |
e89b9f6a | 3704 | //if (fDebug) |
607dbfde | 3705 | // printf("ProcessMessages(%zu messages)\n", pfrom->vRecvMsg.size()); |
0a61b0df | 3706 | |
e89b9f6a PW |
3707 | // |
3708 | // Message format | |
3709 | // (4) message start | |
3710 | // (12) command | |
3711 | // (4) size | |
3712 | // (4) checksum | |
3713 | // (x) data | |
3714 | // | |
967f2459 | 3715 | bool fOk = true; |
0a61b0df | 3716 | |
c7f039b6 PW |
3717 | if (!pfrom->vRecvGetData.empty()) |
3718 | ProcessGetData(pfrom); | |
3719 | ||
967f2459 | 3720 | std::deque<CNetMessage>::iterator it = pfrom->vRecvMsg.begin(); |
41b052ad | 3721 | while (!pfrom->fDisconnect && it != pfrom->vRecvMsg.end()) { |
9d6cd04b | 3722 | // Don't bother if send buffer is too full to respond anyway |
41b052ad | 3723 | if (pfrom->nSendSize >= SendBufferSize()) |
9d6cd04b MC |
3724 | break; |
3725 | ||
967f2459 PW |
3726 | // get next message |
3727 | CNetMessage& msg = *it; | |
607dbfde JG |
3728 | |
3729 | //if (fDebug) | |
3730 | // printf("ProcessMessages(message %u msgsz, %zu bytes, complete:%s)\n", | |
3731 | // msg.hdr.nMessageSize, msg.vRecv.size(), | |
3732 | // msg.complete() ? "Y" : "N"); | |
3733 | ||
967f2459 | 3734 | // end, if an incomplete message is found |
607dbfde | 3735 | if (!msg.complete()) |
e89b9f6a | 3736 | break; |
607dbfde | 3737 | |
967f2459 PW |
3738 | // at this point, any failure means we can delete the current message |
3739 | it++; | |
3740 | ||
607dbfde JG |
3741 | // Scan for message start |
3742 | if (memcmp(msg.hdr.pchMessageStart, pchMessageStart, sizeof(pchMessageStart)) != 0) { | |
3743 | printf("\n\nPROCESSMESSAGE: INVALID MESSAGESTART\n\n"); | |
967f2459 PW |
3744 | fOk = false; |
3745 | break; | |
e89b9f6a | 3746 | } |
0a61b0df | 3747 | |
e89b9f6a | 3748 | // Read header |
607dbfde | 3749 | CMessageHeader& hdr = msg.hdr; |
e89b9f6a PW |
3750 | if (!hdr.IsValid()) |
3751 | { | |
3752 | printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str()); | |
3753 | continue; | |
3754 | } | |
3755 | string strCommand = hdr.GetCommand(); | |
3756 | ||
3757 | // Message size | |
3758 | unsigned int nMessageSize = hdr.nMessageSize; | |
e89b9f6a PW |
3759 | |
3760 | // Checksum | |
607dbfde | 3761 | CDataStream& vRecv = msg.vRecv; |
18c0fa97 PW |
3762 | uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize); |
3763 | unsigned int nChecksum = 0; | |
3764 | memcpy(&nChecksum, &hash, sizeof(nChecksum)); | |
3765 | if (nChecksum != hdr.nChecksum) | |
e89b9f6a | 3766 | { |
ea591ead | 3767 | printf("ProcessMessages(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", |
18c0fa97 PW |
3768 | strCommand.c_str(), nMessageSize, nChecksum, hdr.nChecksum); |
3769 | continue; | |
e89b9f6a PW |
3770 | } |
3771 | ||
e89b9f6a PW |
3772 | // Process message |
3773 | bool fRet = false; | |
3774 | try | |
3775 | { | |
f8dcd5ca PW |
3776 | { |
3777 | LOCK(cs_main); | |
607dbfde | 3778 | fRet = ProcessMessage(pfrom, strCommand, vRecv); |
f8dcd5ca | 3779 | } |
b31499ec | 3780 | boost::this_thread::interruption_point(); |
e89b9f6a PW |
3781 | } |
3782 | catch (std::ios_base::failure& e) | |
3783 | { | |
3784 | if (strstr(e.what(), "end of data")) | |
3785 | { | |
814efd6f | 3786 | // Allow exceptions from under-length message on vRecv |
ea591ead | 3787 | printf("ProcessMessages(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what()); |
e89b9f6a PW |
3788 | } |
3789 | else if (strstr(e.what(), "size too large")) | |
3790 | { | |
814efd6f | 3791 | // Allow exceptions from over-long size |
ea591ead | 3792 | printf("ProcessMessages(%s, %u bytes) : Exception '%s' caught\n", strCommand.c_str(), nMessageSize, e.what()); |
e89b9f6a PW |
3793 | } |
3794 | else | |
3795 | { | |
ea591ead | 3796 | PrintExceptionContinue(&e, "ProcessMessages()"); |
e89b9f6a PW |
3797 | } |
3798 | } | |
b31499ec GA |
3799 | catch (boost::thread_interrupted) { |
3800 | throw; | |
3801 | } | |
e89b9f6a | 3802 | catch (std::exception& e) { |
ea591ead | 3803 | PrintExceptionContinue(&e, "ProcessMessages()"); |
e89b9f6a | 3804 | } catch (...) { |
ea591ead | 3805 | PrintExceptionContinue(NULL, "ProcessMessages()"); |
e89b9f6a PW |
3806 | } |
3807 | ||
3808 | if (!fRet) | |
3809 | printf("ProcessMessage(%s, %u bytes) FAILED\n", strCommand.c_str(), nMessageSize); | |
3810 | } | |
3811 | ||
41b052ad PW |
3812 | // In case the connection got shut down, its receive buffer was wiped |
3813 | if (!pfrom->fDisconnect) | |
3814 | pfrom->vRecvMsg.erase(pfrom->vRecvMsg.begin(), it); | |
3815 | ||
967f2459 | 3816 | return fOk; |
e89b9f6a | 3817 | } |
0a61b0df | 3818 | |
3819 | ||
0a61b0df | 3820 | bool SendMessages(CNode* pto, bool fSendTrickle) |
3821 | { | |
c581cc16 PW |
3822 | TRY_LOCK(cs_main, lockMain); |
3823 | if (lockMain) { | |
0a61b0df | 3824 | // Don't send anything until we get their version message |
3825 | if (pto->nVersion == 0) | |
3826 | return true; | |
3827 | ||
6d64a0bf | 3828 | // Keep-alive ping. We send a nonce of zero because we don't use it anywhere |
93e447b6 | 3829 | // right now. |
41b052ad | 3830 | if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSendMsg.empty()) { |
c971112d | 3831 | uint64 nonce = 0; |
93e447b6 | 3832 | if (pto->nVersion > BIP0031_VERSION) |
c971112d | 3833 | pto->PushMessage("ping", nonce); |
93e447b6 JG |
3834 | else |
3835 | pto->PushMessage("ping"); | |
3836 | } | |
0a61b0df | 3837 | |
6ed71b5e PW |
3838 | // Start block sync |
3839 | if (pto->fStartSync && !fImporting && !fReindex) { | |
3840 | pto->fStartSync = false; | |
3841 | pto->PushGetBlocks(pindexBest, uint256(0)); | |
3842 | } | |
3843 | ||
c891967b | 3844 | // Resend wallet transactions that haven't gotten in a block yet |
e90b831e RDP |
3845 | // Except during reindex, importing and IBD, when old wallet |
3846 | // transactions become unconfirmed and spams other nodes. | |
3847 | if (!fReindex && !fImporting && !IsInitialBlockDownload()) | |
3848 | { | |
3849 | ResendWalletTransactions(); | |
3850 | } | |
c891967b | 3851 | |
0a61b0df | 3852 | // Address refresh broadcast |
bde280b9 | 3853 | static int64 nLastRebroadcast; |
5d1b8f17 | 3854 | if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60)) |
0a61b0df | 3855 | { |
0a61b0df | 3856 | { |
f8dcd5ca | 3857 | LOCK(cs_vNodes); |
223b6f1b | 3858 | BOOST_FOREACH(CNode* pnode, vNodes) |
0a61b0df | 3859 | { |
3860 | // Periodically clear setAddrKnown to allow refresh broadcasts | |
5d1b8f17 GM |
3861 | if (nLastRebroadcast) |
3862 | pnode->setAddrKnown.clear(); | |
0a61b0df | 3863 | |
3864 | // Rebroadcast our address | |
587f929c | 3865 | if (!fNoListen) |
c891967b | 3866 | { |
39857190 PW |
3867 | CAddress addr = GetLocalAddress(&pnode->addr); |
3868 | if (addr.IsRoutable()) | |
3869 | pnode->PushAddress(addr); | |
c891967b | 3870 | } |
0a61b0df | 3871 | } |
3872 | } | |
5d1b8f17 | 3873 | nLastRebroadcast = GetTime(); |
0a61b0df | 3874 | } |
3875 | ||
0a61b0df | 3876 | // |
3877 | // Message: addr | |
3878 | // | |
3879 | if (fSendTrickle) | |
3880 | { | |
3881 | vector<CAddress> vAddr; | |
3882 | vAddr.reserve(pto->vAddrToSend.size()); | |
223b6f1b | 3883 | BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend) |
0a61b0df | 3884 | { |
3885 | // returns true if wasn't already contained in the set | |
3886 | if (pto->setAddrKnown.insert(addr).second) | |
3887 | { | |
3888 | vAddr.push_back(addr); | |
3889 | // receiver rejects addr messages larger than 1000 | |
3890 | if (vAddr.size() >= 1000) | |
3891 | { | |
3892 | pto->PushMessage("addr", vAddr); | |
3893 | vAddr.clear(); | |
3894 | } | |
3895 | } | |
3896 | } | |
3897 | pto->vAddrToSend.clear(); | |
3898 | if (!vAddr.empty()) | |
3899 | pto->PushMessage("addr", vAddr); | |
3900 | } | |
3901 | ||
3902 | ||
3903 | // | |
3904 | // Message: inventory | |
3905 | // | |
3906 | vector<CInv> vInv; | |
3907 | vector<CInv> vInvWait; | |
0a61b0df | 3908 | { |
f8dcd5ca | 3909 | LOCK(pto->cs_inventory); |
0a61b0df | 3910 | vInv.reserve(pto->vInventoryToSend.size()); |
3911 | vInvWait.reserve(pto->vInventoryToSend.size()); | |
223b6f1b | 3912 | BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend) |
0a61b0df | 3913 | { |
3914 | if (pto->setInventoryKnown.count(inv)) | |
3915 | continue; | |
3916 | ||
3917 | // trickle out tx inv to protect privacy | |
3918 | if (inv.type == MSG_TX && !fSendTrickle) | |
3919 | { | |
3920 | // 1/4 of tx invs blast to all immediately | |
3921 | static uint256 hashSalt; | |
3922 | if (hashSalt == 0) | |
f718aedd | 3923 | hashSalt = GetRandHash(); |
0a61b0df | 3924 | uint256 hashRand = inv.hash ^ hashSalt; |
3925 | hashRand = Hash(BEGIN(hashRand), END(hashRand)); | |
3926 | bool fTrickleWait = ((hashRand & 3) != 0); | |
3927 | ||
3928 | // always trickle our own transactions | |
3929 | if (!fTrickleWait) | |
3930 | { | |
64c7ee7e PW |
3931 | CWalletTx wtx; |
3932 | if (GetTransaction(inv.hash, wtx)) | |
3933 | if (wtx.fFromMe) | |
3934 | fTrickleWait = true; | |
0a61b0df | 3935 | } |
3936 | ||
3937 | if (fTrickleWait) | |
3938 | { | |
3939 | vInvWait.push_back(inv); | |
3940 | continue; | |
3941 | } | |
3942 | } | |
3943 | ||
3944 | // returns true if wasn't already contained in the set | |
3945 | if (pto->setInventoryKnown.insert(inv).second) | |
3946 | { | |
3947 | vInv.push_back(inv); | |
3948 | if (vInv.size() >= 1000) | |
3949 | { | |
3950 | pto->PushMessage("inv", vInv); | |
3951 | vInv.clear(); | |
3952 | } | |
3953 | } | |
3954 | } | |
3955 | pto->vInventoryToSend = vInvWait; | |
3956 | } | |
3957 | if (!vInv.empty()) | |
3958 | pto->PushMessage("inv", vInv); | |
3959 | ||
3960 | ||
3961 | // | |
3962 | // Message: getdata | |
3963 | // | |
3964 | vector<CInv> vGetData; | |
bde280b9 | 3965 | int64 nNow = GetTime() * 1000000; |
0a61b0df | 3966 | while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow) |
3967 | { | |
3968 | const CInv& inv = (*pto->mapAskFor.begin()).second; | |
ae8bfd12 | 3969 | if (!AlreadyHave(inv)) |
0a61b0df | 3970 | { |
d07eaba1 JG |
3971 | if (fDebugNet) |
3972 | printf("sending getdata: %s\n", inv.ToString().c_str()); | |
0a61b0df | 3973 | vGetData.push_back(inv); |
3974 | if (vGetData.size() >= 1000) | |
3975 | { | |
3976 | pto->PushMessage("getdata", vGetData); | |
3977 | vGetData.clear(); | |
3978 | } | |
3979 | } | |
3980 | pto->mapAskFor.erase(pto->mapAskFor.begin()); | |
3981 | } | |
3982 | if (!vGetData.empty()) | |
3983 | pto->PushMessage("getdata", vGetData); | |
3984 | ||
3985 | } | |
3986 | return true; | |
3987 | } | |
3988 | ||
3989 | ||
3990 | ||
3991 | ||
3992 | ||
3993 | ||
3994 | ||
3995 | ||
3996 | ||
3997 | ||
3998 | ||
3999 | ||
4000 | ||
4001 | ||
4002 | ////////////////////////////////////////////////////////////////////////////// | |
4003 | // | |
4004 | // BitcoinMiner | |
4005 | // | |
4006 | ||
64c7ee7e | 4007 | int static FormatHashBlocks(void* pbuffer, unsigned int len) |
3df62878 | 4008 | { |
4009 | unsigned char* pdata = (unsigned char*)pbuffer; | |
4010 | unsigned int blocks = 1 + ((len + 8) / 64); | |
4011 | unsigned char* pend = pdata + 64 * blocks; | |
4012 | memset(pdata + len, 0, 64 * blocks - len); | |
4013 | pdata[len] = 0x80; | |
4014 | unsigned int bits = len * 8; | |
4015 | pend[-1] = (bits >> 0) & 0xff; | |
4016 | pend[-2] = (bits >> 8) & 0xff; | |
4017 | pend[-3] = (bits >> 16) & 0xff; | |
4018 | pend[-4] = (bits >> 24) & 0xff; | |
4019 | return blocks; | |
4020 | } | |
4021 | ||
3df62878 | 4022 | static const unsigned int pSHA256InitState[8] = |
4023 | {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; | |
4024 | ||
6ccff2cb | 4025 | void SHA256Transform(void* pstate, void* pinput, const void* pinit) |
3df62878 | 4026 | { |
6ccff2cb NS |
4027 | SHA256_CTX ctx; |
4028 | unsigned char data[64]; | |
4029 | ||
4030 | SHA256_Init(&ctx); | |
4031 | ||
4032 | for (int i = 0; i < 16; i++) | |
4033 | ((uint32_t*)data)[i] = ByteReverse(((uint32_t*)pinput)[i]); | |
4034 | ||
4035 | for (int i = 0; i < 8; i++) | |
4036 | ctx.h[i] = ((uint32_t*)pinit)[i]; | |
4037 | ||
4038 | SHA256_Update(&ctx, data, sizeof(data)); | |
6d64a0bf | 4039 | for (int i = 0; i < 8; i++) |
6ccff2cb | 4040 | ((uint32_t*)pstate)[i] = ctx.h[i]; |
3df62878 | 4041 | } |
4042 | ||
4043 | // | |
4044 | // ScanHash scans nonces looking for a hash with at least some zero bits. | |
4045 | // It operates on big endian data. Caller does the byte reversing. | |
4046 | // All input buffers are 16-byte aligned. nNonce is usually preserved | |
776d0f34 | 4047 | // between calls, but periodically or if nNonce is 0xffff0000 or above, |
3df62878 | 4048 | // the block is rebuilt and nNonce starts over at zero. |
4049 | // | |
64c7ee7e | 4050 | unsigned int static ScanHash_CryptoPP(char* pmidstate, char* pdata, char* phash1, char* phash, unsigned int& nHashesDone) |
3df62878 | 4051 | { |
776d0f34 | 4052 | unsigned int& nNonce = *(unsigned int*)(pdata + 12); |
3df62878 | 4053 | for (;;) |
4054 | { | |
814efd6f | 4055 | // Crypto++ SHA256 |
776d0f34 | 4056 | // Hash pdata using pmidstate as the starting state into |
814efd6f | 4057 | // pre-formatted buffer phash1, then hash phash1 into phash |
3df62878 | 4058 | nNonce++; |
776d0f34 | 4059 | SHA256Transform(phash1, pdata, pmidstate); |
3df62878 | 4060 | SHA256Transform(phash, phash1, pSHA256InitState); |
4061 | ||
4062 | // Return the nonce if the hash has at least some zero bits, | |
4063 | // caller will check if it has enough to reach the target | |
4064 | if (((unsigned short*)phash)[14] == 0) | |
4065 | return nNonce; | |
4066 | ||
4067 | // If nothing found after trying for a while, return -1 | |
4068 | if ((nNonce & 0xffff) == 0) | |
4069 | { | |
4070 | nHashesDone = 0xffff+1; | |
1d8c7a95 | 4071 | return (unsigned int) -1; |
3df62878 | 4072 | } |
c8c2fbe0 GA |
4073 | if ((nNonce & 0xfff) == 0) |
4074 | boost::this_thread::interruption_point(); | |
3df62878 | 4075 | } |
4076 | } | |
4077 | ||
d0d9486f | 4078 | // Some explaining would be appreciated |
683bcb91 | 4079 | class COrphan |
4080 | { | |
4081 | public: | |
4082 | CTransaction* ptx; | |
4083 | set<uint256> setDependsOn; | |
4084 | double dPriority; | |
c555400c | 4085 | double dFeePerKb; |
683bcb91 | 4086 | |
4087 | COrphan(CTransaction* ptxIn) | |
4088 | { | |
4089 | ptx = ptxIn; | |
c555400c | 4090 | dPriority = dFeePerKb = 0; |
683bcb91 | 4091 | } |
4092 | ||
4093 | void print() const | |
4094 | { | |
c555400c | 4095 | printf("COrphan(hash=%s, dPriority=%.1f, dFeePerKb=%.1f)\n", |
1c06aa98 | 4096 | ptx->GetHash().ToString().c_str(), dPriority, dFeePerKb); |
223b6f1b | 4097 | BOOST_FOREACH(uint256 hash, setDependsOn) |
1c06aa98 | 4098 | printf(" setDependsOn %s\n", hash.ToString().c_str()); |
683bcb91 | 4099 | } |
4100 | }; | |
4101 | ||
4102 | ||
340f0876 LD |
4103 | uint64 nLastBlockTx = 0; |
4104 | uint64 nLastBlockSize = 0; | |
4105 | ||
c555400c GA |
4106 | // We want to sort transactions by priority and fee, so: |
4107 | typedef boost::tuple<double, double, CTransaction*> TxPriority; | |
4108 | class TxPriorityCompare | |
4109 | { | |
4110 | bool byFee; | |
4111 | public: | |
4112 | TxPriorityCompare(bool _byFee) : byFee(_byFee) { } | |
4113 | bool operator()(const TxPriority& a, const TxPriority& b) | |
4114 | { | |
4115 | if (byFee) | |
4116 | { | |
4117 | if (a.get<1>() == b.get<1>()) | |
4118 | return a.get<0>() < b.get<0>(); | |
4119 | return a.get<1>() < b.get<1>(); | |
4120 | } | |
4121 | else | |
4122 | { | |
4123 | if (a.get<0>() == b.get<0>()) | |
4124 | return a.get<1>() < b.get<1>(); | |
4125 | return a.get<0>() < b.get<0>(); | |
4126 | } | |
4127 | } | |
4128 | }; | |
4129 | ||
03cac0bb | 4130 | CBlockTemplate* CreateNewBlock(CReserveKey& reservekey) |
776d0f34 | 4131 | { |
776d0f34 | 4132 | // Create new block |
03cac0bb FV |
4133 | auto_ptr<CBlockTemplate> pblocktemplate(new CBlockTemplate()); |
4134 | if(!pblocktemplate.get()) | |
776d0f34 | 4135 | return NULL; |
03cac0bb | 4136 | CBlock *pblock = &pblocktemplate->block; // pointer for convenience |
776d0f34 | 4137 | |
4138 | // Create coinbase tx | |
4139 | CTransaction txNew; | |
4140 | txNew.vin.resize(1); | |
4141 | txNew.vin[0].prevout.SetNull(); | |
4142 | txNew.vout.resize(1); | |
360cfe14 PW |
4143 | CPubKey pubkey; |
4144 | if (!reservekey.GetReservedKey(pubkey)) | |
4145 | return NULL; | |
4146 | txNew.vout[0].scriptPubKey << pubkey << OP_CHECKSIG; | |
776d0f34 | 4147 | |
4148 | // Add our coinbase tx as first transaction | |
4149 | pblock->vtx.push_back(txNew); | |
03cac0bb FV |
4150 | pblocktemplate->vTxFees.push_back(-1); // updated at end |
4151 | pblocktemplate->vTxSigOps.push_back(-1); // updated at end | |
776d0f34 | 4152 | |
c555400c GA |
4153 | // Largest block you're willing to create: |
4154 | unsigned int nBlockMaxSize = GetArg("-blockmaxsize", MAX_BLOCK_SIZE_GEN/2); | |
4155 | // Limit to betweeen 1K and MAX_BLOCK_SIZE-1K for sanity: | |
4156 | nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize)); | |
4157 | ||
4158 | // How much of the block should be dedicated to high-priority transactions, | |
4159 | // included regardless of the fees they pay | |
4160 | unsigned int nBlockPrioritySize = GetArg("-blockprioritysize", 27000); | |
4161 | nBlockPrioritySize = std::min(nBlockMaxSize, nBlockPrioritySize); | |
4162 | ||
4163 | // Minimum block size you want to create; block will be filled with free transactions | |
4164 | // until there are no more or the block reaches this size: | |
4165 | unsigned int nBlockMinSize = GetArg("-blockminsize", 0); | |
4166 | nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize); | |
4167 | ||
776d0f34 | 4168 | // Collect memory pool transactions into the block |
bde280b9 | 4169 | int64 nFees = 0; |
776d0f34 | 4170 | { |
235507ae | 4171 | LOCK2(cs_main, mempool.cs); |
faff50d1 | 4172 | CBlockIndex* pindexPrev = pindexBest; |
ae8bfd12 | 4173 | CCoinsViewCache view(*pcoinsTip, true); |
776d0f34 | 4174 | |
4175 | // Priority order to process transactions | |
4176 | list<COrphan> vOrphan; // list memory doesn't move | |
4177 | map<uint256, vector<COrphan*> > mapDependers; | |
2646080e | 4178 | bool fPrintPriority = GetBoolArg("-printpriority"); |
c555400c GA |
4179 | |
4180 | // This vector will be sorted into a priority queue: | |
4181 | vector<TxPriority> vecPriority; | |
4182 | vecPriority.reserve(mempool.mapTx.size()); | |
235507ae | 4183 | for (map<uint256, CTransaction>::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi) |
776d0f34 | 4184 | { |
4185 | CTransaction& tx = (*mi).second; | |
4186 | if (tx.IsCoinBase() || !tx.IsFinal()) | |
4187 | continue; | |
4188 | ||
4189 | COrphan* porphan = NULL; | |
4190 | double dPriority = 0; | |
c555400c | 4191 | int64 nTotalIn = 0; |
e0e54740 | 4192 | bool fMissingInputs = false; |
223b6f1b | 4193 | BOOST_FOREACH(const CTxIn& txin, tx.vin) |
776d0f34 | 4194 | { |
4195 | // Read prev transaction | |
2ec349bc | 4196 | if (!view.HaveCoins(txin.prevout.hash)) |
776d0f34 | 4197 | { |
e0e54740 GA |
4198 | // This should never happen; all transactions in the memory |
4199 | // pool should connect to either transactions in the chain | |
4200 | // or other transactions in the memory pool. | |
4201 | if (!mempool.mapTx.count(txin.prevout.hash)) | |
4202 | { | |
4203 | printf("ERROR: mempool transaction missing input\n"); | |
4204 | if (fDebug) assert("mempool transaction missing input" == 0); | |
4205 | fMissingInputs = true; | |
4206 | if (porphan) | |
4207 | vOrphan.pop_back(); | |
4208 | break; | |
4209 | } | |
4210 | ||
776d0f34 | 4211 | // Has to wait for dependencies |
4212 | if (!porphan) | |
4213 | { | |
4214 | // Use list for automatic deletion | |
4215 | vOrphan.push_back(COrphan(&tx)); | |
4216 | porphan = &vOrphan.back(); | |
4217 | } | |
4218 | mapDependers[txin.prevout.hash].push_back(porphan); | |
4219 | porphan->setDependsOn.insert(txin.prevout.hash); | |
c555400c | 4220 | nTotalIn += mempool.mapTx[txin.prevout.hash].vout[txin.prevout.n].nValue; |
776d0f34 | 4221 | continue; |
4222 | } | |
2ec349bc | 4223 | const CCoins &coins = view.GetCoins(txin.prevout.hash); |
450cbb09 PW |
4224 | |
4225 | int64 nValueIn = coins.vout[txin.prevout.n].nValue; | |
c555400c | 4226 | nTotalIn += nValueIn; |
776d0f34 | 4227 | |
1e64c2d5 | 4228 | int nConf = pindexPrev->nHeight - coins.nHeight + 1; |
450cbb09 | 4229 | |
776d0f34 | 4230 | dPriority += (double)nValueIn * nConf; |
776d0f34 | 4231 | } |
e0e54740 | 4232 | if (fMissingInputs) continue; |
776d0f34 | 4233 | |
4234 | // Priority is sum(valuein * age) / txsize | |
c555400c GA |
4235 | unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); |
4236 | dPriority /= nTxSize; | |
776d0f34 | 4237 | |
c555400c GA |
4238 | // This is a more accurate fee-per-kilobyte than is used by the client code, because the |
4239 | // client code rounds up the size to the nearest 1K. That's good, because it gives an | |
4240 | // incentive to create smaller transactions. | |
4241 | double dFeePerKb = double(nTotalIn-tx.GetValueOut()) / (double(nTxSize)/1000.0); | |
776d0f34 | 4242 | |
c555400c | 4243 | if (porphan) |
776d0f34 | 4244 | { |
c555400c GA |
4245 | porphan->dPriority = dPriority; |
4246 | porphan->dFeePerKb = dFeePerKb; | |
776d0f34 | 4247 | } |
c555400c GA |
4248 | else |
4249 | vecPriority.push_back(TxPriority(dPriority, dFeePerKb, &(*mi).second)); | |
776d0f34 | 4250 | } |
4251 | ||
4252 | // Collect transactions into block | |
bde280b9 | 4253 | uint64 nBlockSize = 1000; |
340f0876 | 4254 | uint64 nBlockTx = 0; |
137d0685 | 4255 | int nBlockSigOps = 100; |
c555400c GA |
4256 | bool fSortedByFee = (nBlockPrioritySize <= 0); |
4257 | ||
4258 | TxPriorityCompare comparer(fSortedByFee); | |
4259 | std::make_heap(vecPriority.begin(), vecPriority.end(), comparer); | |
4260 | ||
4261 | while (!vecPriority.empty()) | |
776d0f34 | 4262 | { |
c555400c GA |
4263 | // Take highest priority transaction off the priority queue: |
4264 | double dPriority = vecPriority.front().get<0>(); | |
4265 | double dFeePerKb = vecPriority.front().get<1>(); | |
4266 | CTransaction& tx = *(vecPriority.front().get<2>()); | |
4267 | ||
4268 | std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer); | |
4269 | vecPriority.pop_back(); | |
776d0f34 | 4270 | |
4271 | // Size limits | |
6b6aaa16 | 4272 | unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); |
c555400c | 4273 | if (nBlockSize + nTxSize >= nBlockMaxSize) |
776d0f34 | 4274 | continue; |
776d0f34 | 4275 | |
922e8e29 | 4276 | // Legacy limits on sigOps: |
7bd9c3a3 | 4277 | unsigned int nTxSigOps = tx.GetLegacySigOpCount(); |
137d0685 | 4278 | if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) |
922e8e29 GA |
4279 | continue; |
4280 | ||
c555400c | 4281 | // Skip free transactions if we're past the minimum block size: |
000dc551 | 4282 | if (fSortedByFee && (dFeePerKb < CTransaction::nMinTxFee) && (nBlockSize + nTxSize >= nBlockMinSize)) |
c555400c GA |
4283 | continue; |
4284 | ||
4285 | // Prioritize by fee once past the priority size or we run out of high-priority | |
4286 | // transactions: | |
4287 | if (!fSortedByFee && | |
4288 | ((nBlockSize + nTxSize >= nBlockPrioritySize) || (dPriority < COIN * 144 / 250))) | |
4289 | { | |
4290 | fSortedByFee = true; | |
4291 | comparer = TxPriorityCompare(fSortedByFee); | |
4292 | std::make_heap(vecPriority.begin(), vecPriority.end(), comparer); | |
4293 | } | |
776d0f34 | 4294 | |
2ec349bc | 4295 | if (!tx.HaveInputs(view)) |
e679ec96 | 4296 | continue; |
922e8e29 | 4297 | |
2ec349bc | 4298 | int64 nTxFees = tx.GetValueIn(view)-tx.GetValueOut(); |
8d7849b6 | 4299 | |
2ec349bc | 4300 | nTxSigOps += tx.GetP2SHSigOpCount(view); |
137d0685 | 4301 | if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) |
776d0f34 | 4302 | continue; |
8d7849b6 | 4303 | |
ef3988ca | 4304 | CValidationState state; |
2ec349bc | 4305 | if (!tx.CheckInputs(state, view, true, SCRIPT_VERIFY_P2SH)) |
13c51f20 PW |
4306 | continue; |
4307 | ||
450cbb09 | 4308 | CTxUndo txundo; |
64dd46fd | 4309 | uint256 hash = tx.GetHash(); |
2ec349bc | 4310 | tx.UpdateCoins(state, view, txundo, pindexPrev->nHeight+1, hash); |
776d0f34 | 4311 | |
4312 | // Added | |
4313 | pblock->vtx.push_back(tx); | |
03cac0bb FV |
4314 | pblocktemplate->vTxFees.push_back(nTxFees); |
4315 | pblocktemplate->vTxSigOps.push_back(nTxSigOps); | |
776d0f34 | 4316 | nBlockSize += nTxSize; |
340f0876 | 4317 | ++nBlockTx; |
137d0685 | 4318 | nBlockSigOps += nTxSigOps; |
68649bef | 4319 | nFees += nTxFees; |
776d0f34 | 4320 | |
2646080e | 4321 | if (fPrintPriority) |
c555400c GA |
4322 | { |
4323 | printf("priority %.1f feeperkb %.1f txid %s\n", | |
4324 | dPriority, dFeePerKb, tx.GetHash().ToString().c_str()); | |
4325 | } | |
4326 | ||
776d0f34 | 4327 | // Add transactions that depend on this one to the priority queue |
776d0f34 | 4328 | if (mapDependers.count(hash)) |
4329 | { | |
223b6f1b | 4330 | BOOST_FOREACH(COrphan* porphan, mapDependers[hash]) |
776d0f34 | 4331 | { |
4332 | if (!porphan->setDependsOn.empty()) | |
4333 | { | |
4334 | porphan->setDependsOn.erase(hash); | |
4335 | if (porphan->setDependsOn.empty()) | |
c555400c GA |
4336 | { |
4337 | vecPriority.push_back(TxPriority(porphan->dPriority, porphan->dFeePerKb, porphan->ptx)); | |
4338 | std::push_heap(vecPriority.begin(), vecPriority.end(), comparer); | |
4339 | } | |
776d0f34 | 4340 | } |
4341 | } | |
4342 | } | |
4343 | } | |
340f0876 LD |
4344 | |
4345 | nLastBlockTx = nBlockTx; | |
4346 | nLastBlockSize = nBlockSize; | |
d210f4f5 | 4347 | printf("CreateNewBlock(): total size %"PRI64u"\n", nBlockSize); |
340f0876 | 4348 | |
450cbb09 | 4349 | pblock->vtx[0].vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees); |
03cac0bb | 4350 | pblocktemplate->vTxFees[0] = -nFees; |
776d0f34 | 4351 | |
450cbb09 PW |
4352 | // Fill in header |
4353 | pblock->hashPrevBlock = pindexPrev->GetBlockHash(); | |
4354 | pblock->UpdateTime(pindexPrev); | |
03cac0bb | 4355 | pblock->nBits = GetNextWorkRequired(pindexPrev, pblock); |
450cbb09 | 4356 | pblock->nNonce = 0; |
4fbad912 | 4357 | pblock->vtx[0].vin[0].scriptSig = CScript() << OP_0 << OP_0; |
03cac0bb | 4358 | pblocktemplate->vTxSigOps[0] = pblock->vtx[0].GetLegacySigOpCount(); |
450cbb09 | 4359 | |
630fd8dc | 4360 | CBlockIndex indexDummy(*pblock); |
3cd01fdf LD |
4361 | indexDummy.pprev = pindexPrev; |
4362 | indexDummy.nHeight = pindexPrev->nHeight + 1; | |
ae8bfd12 | 4363 | CCoinsViewCache viewNew(*pcoinsTip, true); |
ef3988ca PW |
4364 | CValidationState state; |
4365 | if (!pblock->ConnectBlock(state, &indexDummy, viewNew, true)) | |
3cd01fdf LD |
4366 | throw std::runtime_error("CreateNewBlock() : ConnectBlock failed"); |
4367 | } | |
4368 | ||
03cac0bb | 4369 | return pblocktemplate.release(); |
776d0f34 | 4370 | } |
4371 | ||
4372 | ||
83f4cd15 | 4373 | void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce) |
776d0f34 | 4374 | { |
4375 | // Update nExtraNonce | |
02d87b3a LD |
4376 | static uint256 hashPrevBlock; |
4377 | if (hashPrevBlock != pblock->hashPrevBlock) | |
776d0f34 | 4378 | { |
02d87b3a LD |
4379 | nExtraNonce = 0; |
4380 | hashPrevBlock = pblock->hashPrevBlock; | |
776d0f34 | 4381 | } |
02d87b3a | 4382 | ++nExtraNonce; |
de237cbf GA |
4383 | unsigned int nHeight = pindexPrev->nHeight+1; // Height first in coinbase required for block.version=2 |
4384 | pblock->vtx[0].vin[0].scriptSig = (CScript() << nHeight << CBigNum(nExtraNonce)) + COINBASE_FLAGS; | |
d7062ef1 GA |
4385 | assert(pblock->vtx[0].vin[0].scriptSig.size() <= 100); |
4386 | ||
776d0f34 | 4387 | pblock->hashMerkleRoot = pblock->BuildMerkleTree(); |
4388 | } | |
4389 | ||
4390 | ||
4391 | void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1) | |
4392 | { | |
4393 | // | |
814efd6f | 4394 | // Pre-build hash buffers |
776d0f34 | 4395 | // |
4396 | struct | |
4397 | { | |
4398 | struct unnamed2 | |
4399 | { | |
4400 | int nVersion; | |
4401 | uint256 hashPrevBlock; | |
4402 | uint256 hashMerkleRoot; | |
4403 | unsigned int nTime; | |
4404 | unsigned int nBits; | |
4405 | unsigned int nNonce; | |
4406 | } | |
4407 | block; | |
4408 | unsigned char pchPadding0[64]; | |
4409 | uint256 hash1; | |
4410 | unsigned char pchPadding1[64]; | |
4411 | } | |
4412 | tmp; | |
4413 | memset(&tmp, 0, sizeof(tmp)); | |
4414 | ||
4415 | tmp.block.nVersion = pblock->nVersion; | |
4416 | tmp.block.hashPrevBlock = pblock->hashPrevBlock; | |
4417 | tmp.block.hashMerkleRoot = pblock->hashMerkleRoot; | |
4418 | tmp.block.nTime = pblock->nTime; | |
4419 | tmp.block.nBits = pblock->nBits; | |
4420 | tmp.block.nNonce = pblock->nNonce; | |
4421 | ||
4422 | FormatHashBlocks(&tmp.block, sizeof(tmp.block)); | |
4423 | FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1)); | |
4424 | ||
4425 | // Byte swap all the input buffer | |
c376ac35 | 4426 | for (unsigned int i = 0; i < sizeof(tmp)/4; i++) |
776d0f34 | 4427 | ((unsigned int*)&tmp)[i] = ByteReverse(((unsigned int*)&tmp)[i]); |
4428 | ||
4429 | // Precalc the first half of the first hash, which stays constant | |
4430 | SHA256Transform(pmidstate, &tmp.block, pSHA256InitState); | |
4431 | ||
4432 | memcpy(pdata, &tmp.block, 128); | |
4433 | memcpy(phash1, &tmp.hash1, 64); | |
4434 | } | |
4435 | ||
4436 | ||
64c7ee7e | 4437 | bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) |
776d0f34 | 4438 | { |
4439 | uint256 hash = pblock->GetHash(); | |
4440 | uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); | |
4441 | ||
4442 | if (hash > hashTarget) | |
4443 | return false; | |
4444 | ||
4445 | //// debug print | |
4446 | printf("BitcoinMiner:\n"); | |
4447 | printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); | |
4448 | pblock->print(); | |
776d0f34 | 4449 | printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str()); |
4450 | ||
4451 | // Found a solution | |
776d0f34 | 4452 | { |
f8dcd5ca | 4453 | LOCK(cs_main); |
776d0f34 | 4454 | if (pblock->hashPrevBlock != hashBestChain) |
4455 | return error("BitcoinMiner : generated block is stale"); | |
4456 | ||
4457 | // Remove key from key pool | |
4458 | reservekey.KeepKey(); | |
4459 | ||
4460 | // Track how many getdata requests this block gets | |
f8dcd5ca PW |
4461 | { |
4462 | LOCK(wallet.cs_wallet); | |
64c7ee7e | 4463 | wallet.mapRequestCount[pblock->GetHash()] = 0; |
f8dcd5ca | 4464 | } |
776d0f34 | 4465 | |
4466 | // Process this block the same as if we had received it from another node | |
ef3988ca PW |
4467 | CValidationState state; |
4468 | if (!ProcessBlock(state, NULL, pblock)) | |
776d0f34 | 4469 | return error("BitcoinMiner : ProcessBlock, block not accepted"); |
4470 | } | |
4471 | ||
776d0f34 | 4472 | return true; |
4473 | } | |
4474 | ||
64c7ee7e | 4475 | void static BitcoinMiner(CWallet *pwallet) |
0a61b0df | 4476 | { |
4477 | printf("BitcoinMiner started\n"); | |
4478 | SetThreadPriority(THREAD_PRIORITY_LOWEST); | |
9f46ab62 | 4479 | RenameThread("bitcoin-miner"); |
96931d6f | 4480 | |
776d0f34 | 4481 | // Each thread has its own key and counter |
64c7ee7e | 4482 | CReserveKey reservekey(pwallet); |
5cbf7532 | 4483 | unsigned int nExtraNonce = 0; |
776d0f34 | 4484 | |
c8c2fbe0 GA |
4485 | try { loop { |
4486 | while (vNodes.empty()) | |
1b43bf0d | 4487 | MilliSleep(1000); |
0a61b0df | 4488 | |
4489 | // | |
4490 | // Create new block | |
4491 | // | |
776d0f34 | 4492 | unsigned int nTransactionsUpdatedLast = nTransactionsUpdated; |
4493 | CBlockIndex* pindexPrev = pindexBest; | |
4494 | ||
03cac0bb FV |
4495 | auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(reservekey)); |
4496 | if (!pblocktemplate.get()) | |
0a61b0df | 4497 | return; |
03cac0bb FV |
4498 | CBlock *pblock = &pblocktemplate->block; |
4499 | IncrementExtraNonce(pblock, pindexPrev, nExtraNonce); | |
0a61b0df | 4500 | |
d210f4f5 | 4501 | printf("Running BitcoinMiner with %"PRIszu" transactions in block (%u bytes)\n", pblock->vtx.size(), |
c555400c | 4502 | ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION)); |
0a61b0df | 4503 | |
0a61b0df | 4504 | // |
814efd6f | 4505 | // Pre-build hash buffers |
0a61b0df | 4506 | // |
776d0f34 | 4507 | char pmidstatebuf[32+16]; char* pmidstate = alignup<16>(pmidstatebuf); |
4508 | char pdatabuf[128+16]; char* pdata = alignup<16>(pdatabuf); | |
4509 | char phash1buf[64+16]; char* phash1 = alignup<16>(phash1buf); | |
4510 | ||
03cac0bb | 4511 | FormatHashBuffers(pblock, pmidstate, pdata, phash1); |
776d0f34 | 4512 | |
4513 | unsigned int& nBlockTime = *(unsigned int*)(pdata + 64 + 4); | |
0f8cb5db | 4514 | unsigned int& nBlockBits = *(unsigned int*)(pdata + 64 + 8); |
776d0f34 | 4515 | unsigned int& nBlockNonce = *(unsigned int*)(pdata + 64 + 12); |
0a61b0df | 4516 | |
4517 | ||
4518 | // | |
4519 | // Search | |
4520 | // | |
bde280b9 | 4521 | int64 nStart = GetTime(); |
0a61b0df | 4522 | uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); |
4523 | uint256 hashbuf[2]; | |
4524 | uint256& hash = *alignup<16>(hashbuf); | |
4525 | loop | |
4526 | { | |
3df62878 | 4527 | unsigned int nHashesDone = 0; |
4528 | unsigned int nNonceFound; | |
4529 | ||
814efd6f | 4530 | // Crypto++ SHA256 |
b26141e2 JG |
4531 | nNonceFound = ScanHash_CryptoPP(pmidstate, pdata + 64, phash1, |
4532 | (char*)&hash, nHashesDone); | |
0a61b0df | 4533 | |
3df62878 | 4534 | // Check if something found |
1d8c7a95 | 4535 | if (nNonceFound != (unsigned int) -1) |
0a61b0df | 4536 | { |
c376ac35 | 4537 | for (unsigned int i = 0; i < sizeof(hash)/4; i++) |
0a61b0df | 4538 | ((unsigned int*)&hash)[i] = ByteReverse(((unsigned int*)&hash)[i]); |
4539 | ||
4540 | if (hash <= hashTarget) | |
4541 | { | |
3df62878 | 4542 | // Found a solution |
4543 | pblock->nNonce = ByteReverse(nNonceFound); | |
0a61b0df | 4544 | assert(hash == pblock->GetHash()); |
4545 | ||
0a61b0df | 4546 | SetThreadPriority(THREAD_PRIORITY_NORMAL); |
03cac0bb | 4547 | CheckWork(pblock, *pwalletMain, reservekey); |
0a61b0df | 4548 | SetThreadPriority(THREAD_PRIORITY_LOWEST); |
0a61b0df | 4549 | break; |
4550 | } | |
4551 | } | |
4552 | ||
3df62878 | 4553 | // Meter hashes/sec |
bde280b9 | 4554 | static int64 nHashCounter; |
3df62878 | 4555 | if (nHPSTimerStart == 0) |
0a61b0df | 4556 | { |
3df62878 | 4557 | nHPSTimerStart = GetTimeMillis(); |
4558 | nHashCounter = 0; | |
4559 | } | |
4560 | else | |
4561 | nHashCounter += nHashesDone; | |
4562 | if (GetTimeMillis() - nHPSTimerStart > 4000) | |
4563 | { | |
4564 | static CCriticalSection cs; | |
0a61b0df | 4565 | { |
f8dcd5ca | 4566 | LOCK(cs); |
3df62878 | 4567 | if (GetTimeMillis() - nHPSTimerStart > 4000) |
0a61b0df | 4568 | { |
3df62878 | 4569 | dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart); |
4570 | nHPSTimerStart = GetTimeMillis(); | |
4571 | nHashCounter = 0; | |
bde280b9 | 4572 | static int64 nLogTime; |
3df62878 | 4573 | if (GetTime() - nLogTime > 30 * 60) |
0a61b0df | 4574 | { |
3df62878 | 4575 | nLogTime = GetTime(); |
c8c2fbe0 | 4576 | printf("hashmeter %6.0f khash/s\n", dHashesPerSec/1000.0); |
0a61b0df | 4577 | } |
4578 | } | |
4579 | } | |
3df62878 | 4580 | } |
0a61b0df | 4581 | |
3df62878 | 4582 | // Check for stop or if block needs to be rebuilt |
c8c2fbe0 | 4583 | boost::this_thread::interruption_point(); |
3df62878 | 4584 | if (vNodes.empty()) |
4585 | break; | |
776d0f34 | 4586 | if (nBlockNonce >= 0xffff0000) |
3df62878 | 4587 | break; |
4588 | if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60) | |
4589 | break; | |
4590 | if (pindexPrev != pindexBest) | |
4591 | break; | |
0a61b0df | 4592 | |
3df62878 | 4593 | // Update nTime every few seconds |
0f8cb5db | 4594 | pblock->UpdateTime(pindexPrev); |
776d0f34 | 4595 | nBlockTime = ByteReverse(pblock->nTime); |
0f8cb5db GA |
4596 | if (fTestNet) |
4597 | { | |
4598 | // Changing pblock->nTime can change work required on testnet: | |
4599 | nBlockBits = ByteReverse(pblock->nBits); | |
4600 | hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); | |
4601 | } | |
0a61b0df | 4602 | } |
c8c2fbe0 GA |
4603 | } } |
4604 | catch (boost::thread_interrupted) | |
0a61b0df | 4605 | { |
c8c2fbe0 GA |
4606 | printf("BitcoinMiner terminated\n"); |
4607 | throw; | |
4608 | } | |
e2a186af | 4609 | } |
4610 | ||
64c7ee7e | 4611 | void GenerateBitcoins(bool fGenerate, CWallet* pwallet) |
0a61b0df | 4612 | { |
c8c2fbe0 | 4613 | static boost::thread_group* minerThreads = NULL; |
972060ce | 4614 | |
c8c2fbe0 GA |
4615 | int nThreads = GetArg("-genproclimit", -1); |
4616 | if (nThreads < 0) | |
4617 | nThreads = boost::thread::hardware_concurrency(); | |
972060ce | 4618 | |
c8c2fbe0 | 4619 | if (minerThreads != NULL) |
0a61b0df | 4620 | { |
c8c2fbe0 GA |
4621 | minerThreads->interrupt_all(); |
4622 | delete minerThreads; | |
4623 | minerThreads = NULL; | |
f5f1878b | 4624 | } |
c8c2fbe0 GA |
4625 | |
4626 | if (nThreads == 0 || !fGenerate) | |
4627 | return; | |
4628 | ||
4629 | minerThreads = new boost::thread_group(); | |
4630 | for (int i = 0; i < nThreads; i++) | |
4631 | minerThreads->create_thread(boost::bind(&BitcoinMiner, pwallet)); | |
0a61b0df | 4632 | } |
0fa593d0 PW |
4633 | |
4634 | // Amount compression: | |
4635 | // * If the amount is 0, output 0 | |
4636 | // * first, divide the amount (in base units) by the largest power of 10 possible; call the exponent e (e is max 9) | |
4637 | // * if e<9, the last digit of the resulting number cannot be 0; store it as d, and drop it (divide by 10) | |
4638 | // * call the result n | |
4639 | // * output 1 + 10*(9*n + d - 1) + e | |
4640 | // * if e==9, we only know the resulting number is not zero, so output 1 + 10*(n - 1) + 9 | |
4641 | // (this is decodable, as d is in [1-9] and e is in [0-9]) | |
4642 | ||
4643 | uint64 CTxOutCompressor::CompressAmount(uint64 n) | |
4644 | { | |
4645 | if (n == 0) | |
4646 | return 0; | |
4647 | int e = 0; | |
4648 | while (((n % 10) == 0) && e < 9) { | |
4649 | n /= 10; | |
4650 | e++; | |
4651 | } | |
4652 | if (e < 9) { | |
4653 | int d = (n % 10); | |
4654 | assert(d >= 1 && d <= 9); | |
4655 | n /= 10; | |
4656 | return 1 + (n*9 + d - 1)*10 + e; | |
4657 | } else { | |
4658 | return 1 + (n - 1)*10 + 9; | |
4659 | } | |
4660 | } | |
4661 | ||
4662 | uint64 CTxOutCompressor::DecompressAmount(uint64 x) | |
4663 | { | |
4664 | // x = 0 OR x = 1+10*(9*n + d - 1) + e OR x = 1+10*(n - 1) + 9 | |
4665 | if (x == 0) | |
4666 | return 0; | |
4667 | x--; | |
4668 | // x = 10*(9*n + d - 1) + e | |
4669 | int e = x % 10; | |
4670 | x /= 10; | |
4671 | uint64 n = 0; | |
4672 | if (e < 9) { | |
4673 | // x = 9*n + d - 1 | |
4674 | int d = (x % 9) + 1; | |
4675 | x /= 9; | |
4676 | // x = n | |
4677 | n = x*10 + d; | |
4678 | } else { | |
4679 | n = x+1; | |
4680 | } | |
4681 | while (e) { | |
4682 | n *= 10; | |
4683 | e--; | |
4684 | } | |
4685 | return n; | |
4686 | } | |
3427517d PW |
4687 | |
4688 | ||
4689 | class CMainCleanup | |
4690 | { | |
4691 | public: | |
4692 | CMainCleanup() {} | |
4693 | ~CMainCleanup() { | |
4694 | // block headers | |
4695 | std::map<uint256, CBlockIndex*>::iterator it1 = mapBlockIndex.begin(); | |
4696 | for (; it1 != mapBlockIndex.end(); it1++) | |
4697 | delete (*it1).second; | |
4698 | mapBlockIndex.clear(); | |
4699 | ||
4700 | // orphan blocks | |
4701 | std::map<uint256, CBlock*>::iterator it2 = mapOrphanBlocks.begin(); | |
4702 | for (; it2 != mapOrphanBlocks.end(); it2++) | |
4703 | delete (*it2).second; | |
4704 | mapOrphanBlocks.clear(); | |
4705 | ||
4706 | // orphan transactions | |
4707 | std::map<uint256, CDataStream*>::iterator it3 = mapOrphanTransactions.begin(); | |
4708 | for (; it3 != mapOrphanTransactions.end(); it3++) | |
4709 | delete (*it3).second; | |
4710 | mapOrphanTransactions.clear(); | |
4711 | } | |
4712 | } instance_of_cmaincleanup; |