]>
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 |
4 | // file license.txt or http://www.opensource.org/licenses/mit-license.php. | |
223b6f1b WL |
5 | #ifndef BITCOIN_MAIN_H |
6 | #define BITCOIN_MAIN_H | |
7 | ||
8 | #include "bignum.h" | |
9 | #include "net.h" | |
10 | #include "key.h" | |
223b6f1b | 11 | #include "script.h" |
a20c0d0f | 12 | #include "version.h" |
223b6f1b | 13 | |
52d3a481 WL |
14 | #ifdef WIN32 |
15 | #include <io.h> /* for _commit */ | |
16 | #endif | |
17 | ||
223b6f1b | 18 | #include <list> |
0a61b0df | 19 | |
0a61b0df | 20 | class CBlock; |
21 | class CBlockIndex; | |
22 | class CWalletTx; | |
e89b9f6a | 23 | class CWallet; |
0a61b0df | 24 | class CKeyItem; |
64c7ee7e PW |
25 | class CReserveKey; |
26 | class CWalletDB; | |
0a61b0df | 27 | |
40c2614e JL |
28 | class CAddress; |
29 | class CInv; | |
30 | class CRequestTracker; | |
31 | class CNode; | |
40c2614e | 32 | |
0a61b0df | 33 | static const unsigned int MAX_BLOCK_SIZE = 1000000; |
3df62878 | 34 | static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2; |
f1e1fb4b | 35 | static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; |
142e6041 | 36 | static const int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100; |
bde280b9 WL |
37 | static const int64 MIN_TX_FEE = 50000; |
38 | static const int64 MIN_RELAY_TX_FEE = 10000; | |
39 | static const int64 MAX_MONEY = 21000000 * COIN; | |
40 | inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } | |
0a61b0df | 41 | static const int COINBASE_MATURITY = 100; |
aa496b75 WL |
42 | // Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp. |
43 | static const int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC | |
8bb5edc1 MC |
44 | #ifdef USE_UPNP |
45 | static const int fHaveUPnP = true; | |
46 | #else | |
47 | static const int fHaveUPnP = false; | |
48 | #endif | |
0a61b0df | 49 | |
50 | ||
7bf8b7c2 | 51 | extern CScript COINBASE_FLAGS; |
52a3d263 FV |
52 | |
53 | ||
0a61b0df | 54 | |
55 | ||
56 | ||
57 | ||
58 | extern CCriticalSection cs_main; | |
223b6f1b | 59 | extern std::map<uint256, CBlockIndex*> mapBlockIndex; |
5cbf7532 | 60 | extern uint256 hashGenesisBlock; |
0a61b0df | 61 | extern CBlockIndex* pindexGenesisBlock; |
62 | extern int nBestHeight; | |
63 | extern CBigNum bnBestChainWork; | |
64 | extern CBigNum bnBestInvalidWork; | |
65 | extern uint256 hashBestChain; | |
66 | extern CBlockIndex* pindexBest; | |
340f0876 | 67 | extern uint64 nPooledTx; |
0a61b0df | 68 | extern unsigned int nTransactionsUpdated; |
340f0876 LD |
69 | extern uint64 nLastBlockTx; |
70 | extern uint64 nLastBlockSize; | |
2bc4fd60 | 71 | extern const std::string strMessageMagic; |
0a61b0df | 72 | extern double dHashesPerSec; |
bde280b9 WL |
73 | extern int64 nHPSTimerStart; |
74 | extern int64 nTimeBestReceived; | |
64c7ee7e PW |
75 | extern CCriticalSection cs_setpwalletRegistered; |
76 | extern std::set<CWallet*> setpwalletRegistered; | |
0a61b0df | 77 | |
78 | // Settings | |
bde280b9 | 79 | extern int64 nTransactionFee; |
0a61b0df | 80 | |
81 | ||
82 | ||
83 | ||
84 | ||
1512d5ce JL |
85 | class CReserveKey; |
86 | class CTxDB; | |
87 | class CTxIndex; | |
0a61b0df | 88 | |
64c7ee7e PW |
89 | void RegisterWallet(CWallet* pwalletIn); |
90 | void UnregisterWallet(CWallet* pwalletIn); | |
074d584a | 91 | bool ProcessBlock(CNode* pfrom, CBlock* pblock); |
bde280b9 | 92 | bool CheckDiskSpace(uint64 nAdditionalBytes=0); |
0a61b0df | 93 | FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb"); |
94 | FILE* AppendBlockFile(unsigned int& nFileRet); | |
0a61b0df | 95 | bool LoadBlockIndex(bool fAllowNew=true); |
96 | void PrintBlockTree(); | |
97 | bool ProcessMessages(CNode* pfrom); | |
0a61b0df | 98 | bool SendMessages(CNode* pto, bool fSendTrickle); |
64c7ee7e | 99 | void GenerateBitcoins(bool fGenerate, CWallet* pwallet); |
776d0f34 | 100 | CBlock* CreateNewBlock(CReserveKey& reservekey); |
83f4cd15 | 101 | void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); |
776d0f34 | 102 | void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1); |
64c7ee7e | 103 | bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey); |
0a61b0df | 104 | bool CheckProofOfWork(uint256 hash, unsigned int nBits); |
bde280b9 | 105 | unsigned int ComputeMinWork(unsigned int nBase, int64 nTime); |
d33cc2b5 | 106 | int GetNumBlocksOfPeers(); |
0a61b0df | 107 | bool IsInitialBlockDownload(); |
223b6f1b | 108 | std::string GetWarnings(std::string strFor); |
0a61b0df | 109 | |
110 | ||
111 | ||
112 | ||
113 | ||
114 | ||
115 | ||
116 | ||
117 | ||
118 | ||
119 | ||
120 | ||
64c7ee7e PW |
121 | bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut); |
122 | ||
6b8de05d | 123 | /** Position on disk for a particular transaction. */ |
0a61b0df | 124 | class CDiskTxPos |
125 | { | |
126 | public: | |
127 | unsigned int nFile; | |
128 | unsigned int nBlockPos; | |
129 | unsigned int nTxPos; | |
130 | ||
131 | CDiskTxPos() | |
132 | { | |
133 | SetNull(); | |
134 | } | |
135 | ||
136 | CDiskTxPos(unsigned int nFileIn, unsigned int nBlockPosIn, unsigned int nTxPosIn) | |
137 | { | |
138 | nFile = nFileIn; | |
139 | nBlockPos = nBlockPosIn; | |
140 | nTxPos = nTxPosIn; | |
141 | } | |
142 | ||
143 | IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); ) | |
144 | void SetNull() { nFile = -1; nBlockPos = 0; nTxPos = 0; } | |
145 | bool IsNull() const { return (nFile == -1); } | |
146 | ||
147 | friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b) | |
148 | { | |
149 | return (a.nFile == b.nFile && | |
150 | a.nBlockPos == b.nBlockPos && | |
151 | a.nTxPos == b.nTxPos); | |
152 | } | |
153 | ||
154 | friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b) | |
155 | { | |
156 | return !(a == b); | |
157 | } | |
158 | ||
223b6f1b | 159 | std::string ToString() const |
0a61b0df | 160 | { |
161 | if (IsNull()) | |
52d3a481 | 162 | return "null"; |
0a61b0df | 163 | else |
164 | return strprintf("(nFile=%d, nBlockPos=%d, nTxPos=%d)", nFile, nBlockPos, nTxPos); | |
165 | } | |
166 | ||
167 | void print() const | |
168 | { | |
169 | printf("%s", ToString().c_str()); | |
170 | } | |
171 | }; | |
172 | ||
173 | ||
174 | ||
6b8de05d | 175 | /** An inpoint - a combination of a transaction and an index n into its vin */ |
0a61b0df | 176 | class CInPoint |
177 | { | |
178 | public: | |
179 | CTransaction* ptx; | |
180 | unsigned int n; | |
181 | ||
182 | CInPoint() { SetNull(); } | |
183 | CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; } | |
184 | void SetNull() { ptx = NULL; n = -1; } | |
185 | bool IsNull() const { return (ptx == NULL && n == -1); } | |
186 | }; | |
187 | ||
188 | ||
189 | ||
6b8de05d | 190 | /** An outpoint - a combination of a transaction hash and an index n into its vout */ |
0a61b0df | 191 | class COutPoint |
192 | { | |
193 | public: | |
194 | uint256 hash; | |
195 | unsigned int n; | |
196 | ||
197 | COutPoint() { SetNull(); } | |
198 | COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; } | |
199 | IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); ) | |
200 | void SetNull() { hash = 0; n = -1; } | |
201 | bool IsNull() const { return (hash == 0 && n == -1); } | |
202 | ||
203 | friend bool operator<(const COutPoint& a, const COutPoint& b) | |
204 | { | |
205 | return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n)); | |
206 | } | |
207 | ||
208 | friend bool operator==(const COutPoint& a, const COutPoint& b) | |
209 | { | |
210 | return (a.hash == b.hash && a.n == b.n); | |
211 | } | |
212 | ||
213 | friend bool operator!=(const COutPoint& a, const COutPoint& b) | |
214 | { | |
215 | return !(a == b); | |
216 | } | |
217 | ||
223b6f1b | 218 | std::string ToString() const |
0a61b0df | 219 | { |
b22c8842 | 220 | return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,10).c_str(), n); |
0a61b0df | 221 | } |
222 | ||
223 | void print() const | |
224 | { | |
225 | printf("%s\n", ToString().c_str()); | |
226 | } | |
227 | }; | |
228 | ||
229 | ||
230 | ||
231 | ||
6b8de05d PW |
232 | /** An input of a transaction. It contains the location of the previous |
233 | * transaction's output that it claims and a signature that matches the | |
234 | * output's public key. | |
235 | */ | |
0a61b0df | 236 | class CTxIn |
237 | { | |
238 | public: | |
239 | COutPoint prevout; | |
240 | CScript scriptSig; | |
241 | unsigned int nSequence; | |
242 | ||
243 | CTxIn() | |
244 | { | |
26ce92b3 | 245 | nSequence = std::numeric_limits<unsigned int>::max(); |
0a61b0df | 246 | } |
247 | ||
26ce92b3 | 248 | explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=std::numeric_limits<unsigned int>::max()) |
0a61b0df | 249 | { |
250 | prevout = prevoutIn; | |
251 | scriptSig = scriptSigIn; | |
252 | nSequence = nSequenceIn; | |
253 | } | |
254 | ||
26ce92b3 | 255 | CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=std::numeric_limits<unsigned int>::max()) |
0a61b0df | 256 | { |
257 | prevout = COutPoint(hashPrevTx, nOut); | |
258 | scriptSig = scriptSigIn; | |
259 | nSequence = nSequenceIn; | |
260 | } | |
261 | ||
262 | IMPLEMENT_SERIALIZE | |
263 | ( | |
264 | READWRITE(prevout); | |
265 | READWRITE(scriptSig); | |
266 | READWRITE(nSequence); | |
267 | ) | |
268 | ||
269 | bool IsFinal() const | |
270 | { | |
26ce92b3 | 271 | return (nSequence == std::numeric_limits<unsigned int>::max()); |
0a61b0df | 272 | } |
273 | ||
274 | friend bool operator==(const CTxIn& a, const CTxIn& b) | |
275 | { | |
276 | return (a.prevout == b.prevout && | |
277 | a.scriptSig == b.scriptSig && | |
278 | a.nSequence == b.nSequence); | |
279 | } | |
280 | ||
281 | friend bool operator!=(const CTxIn& a, const CTxIn& b) | |
282 | { | |
283 | return !(a == b); | |
284 | } | |
285 | ||
223b6f1b | 286 | std::string ToString() const |
0a61b0df | 287 | { |
223b6f1b | 288 | std::string str; |
52d3a481 | 289 | str += "CTxIn("; |
0a61b0df | 290 | str += prevout.ToString(); |
291 | if (prevout.IsNull()) | |
f1e1fb4b | 292 | str += strprintf(", coinbase %s", HexStr(scriptSig).c_str()); |
0a61b0df | 293 | else |
294 | str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str()); | |
26ce92b3 | 295 | if (nSequence != std::numeric_limits<unsigned int>::max()) |
0a61b0df | 296 | str += strprintf(", nSequence=%u", nSequence); |
297 | str += ")"; | |
298 | return str; | |
299 | } | |
300 | ||
301 | void print() const | |
302 | { | |
303 | printf("%s\n", ToString().c_str()); | |
304 | } | |
0a61b0df | 305 | }; |
306 | ||
307 | ||
308 | ||
309 | ||
6b8de05d PW |
310 | /** An output of a transaction. It contains the public key that the next input |
311 | * must be able to sign with to claim it. | |
312 | */ | |
0a61b0df | 313 | class CTxOut |
314 | { | |
315 | public: | |
bde280b9 | 316 | int64 nValue; |
0a61b0df | 317 | CScript scriptPubKey; |
318 | ||
319 | CTxOut() | |
320 | { | |
321 | SetNull(); | |
322 | } | |
323 | ||
bde280b9 | 324 | CTxOut(int64 nValueIn, CScript scriptPubKeyIn) |
0a61b0df | 325 | { |
326 | nValue = nValueIn; | |
327 | scriptPubKey = scriptPubKeyIn; | |
328 | } | |
329 | ||
330 | IMPLEMENT_SERIALIZE | |
331 | ( | |
332 | READWRITE(nValue); | |
333 | READWRITE(scriptPubKey); | |
334 | ) | |
335 | ||
336 | void SetNull() | |
337 | { | |
338 | nValue = -1; | |
339 | scriptPubKey.clear(); | |
340 | } | |
341 | ||
342 | bool IsNull() | |
343 | { | |
344 | return (nValue == -1); | |
345 | } | |
346 | ||
347 | uint256 GetHash() const | |
348 | { | |
349 | return SerializeHash(*this); | |
350 | } | |
351 | ||
0a61b0df | 352 | friend bool operator==(const CTxOut& a, const CTxOut& b) |
353 | { | |
354 | return (a.nValue == b.nValue && | |
355 | a.scriptPubKey == b.scriptPubKey); | |
356 | } | |
357 | ||
358 | friend bool operator!=(const CTxOut& a, const CTxOut& b) | |
359 | { | |
360 | return !(a == b); | |
361 | } | |
362 | ||
223b6f1b | 363 | std::string ToString() const |
0a61b0df | 364 | { |
365 | if (scriptPubKey.size() < 6) | |
366 | return "CTxOut(error)"; | |
10384941 | 367 | return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30).c_str()); |
0a61b0df | 368 | } |
369 | ||
370 | void print() const | |
371 | { | |
372 | printf("%s\n", ToString().c_str()); | |
373 | } | |
374 | }; | |
375 | ||
376 | ||
377 | ||
378 | ||
dbbf1d4a LD |
379 | enum GetMinFee_mode |
380 | { | |
381 | GMF_BLOCK, | |
382 | GMF_RELAY, | |
383 | GMF_SEND, | |
384 | }; | |
385 | ||
8d7849b6 GA |
386 | typedef std::map<uint256, std::pair<CTxIndex, CTransaction> > MapPrevTx; |
387 | ||
6b8de05d PW |
388 | /** The basic transaction that is broadcasted on the network and contained in |
389 | * blocks. A transaction can contain multiple inputs and outputs. | |
390 | */ | |
0a61b0df | 391 | class CTransaction |
392 | { | |
393 | public: | |
394 | int nVersion; | |
223b6f1b WL |
395 | std::vector<CTxIn> vin; |
396 | std::vector<CTxOut> vout; | |
0a61b0df | 397 | unsigned int nLockTime; |
398 | ||
3e52aaf2 GA |
399 | // Denial-of-service detection: |
400 | mutable int nDoS; | |
401 | bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; } | |
0a61b0df | 402 | |
403 | CTransaction() | |
404 | { | |
405 | SetNull(); | |
406 | } | |
407 | ||
408 | IMPLEMENT_SERIALIZE | |
409 | ( | |
410 | READWRITE(this->nVersion); | |
411 | nVersion = this->nVersion; | |
412 | READWRITE(vin); | |
413 | READWRITE(vout); | |
414 | READWRITE(nLockTime); | |
415 | ) | |
416 | ||
417 | void SetNull() | |
418 | { | |
419 | nVersion = 1; | |
420 | vin.clear(); | |
421 | vout.clear(); | |
422 | nLockTime = 0; | |
3e52aaf2 | 423 | nDoS = 0; // Denial-of-service prevention |
0a61b0df | 424 | } |
425 | ||
426 | bool IsNull() const | |
427 | { | |
428 | return (vin.empty() && vout.empty()); | |
429 | } | |
430 | ||
431 | uint256 GetHash() const | |
432 | { | |
433 | return SerializeHash(*this); | |
434 | } | |
435 | ||
bde280b9 | 436 | bool IsFinal(int nBlockHeight=0, int64 nBlockTime=0) const |
0a61b0df | 437 | { |
438 | // Time based nLockTime implemented in 0.1.6 | |
439 | if (nLockTime == 0) | |
440 | return true; | |
441 | if (nBlockHeight == 0) | |
442 | nBlockHeight = nBestHeight; | |
443 | if (nBlockTime == 0) | |
444 | nBlockTime = GetAdjustedTime(); | |
bde280b9 | 445 | if ((int64)nLockTime < (nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime)) |
0a61b0df | 446 | return true; |
223b6f1b | 447 | BOOST_FOREACH(const CTxIn& txin, vin) |
0a61b0df | 448 | if (!txin.IsFinal()) |
449 | return false; | |
450 | return true; | |
451 | } | |
452 | ||
453 | bool IsNewerThan(const CTransaction& old) const | |
454 | { | |
455 | if (vin.size() != old.vin.size()) | |
456 | return false; | |
c376ac35 | 457 | for (unsigned int i = 0; i < vin.size(); i++) |
0a61b0df | 458 | if (vin[i].prevout != old.vin[i].prevout) |
459 | return false; | |
460 | ||
461 | bool fNewer = false; | |
26ce92b3 | 462 | unsigned int nLowest = std::numeric_limits<unsigned int>::max(); |
c376ac35 | 463 | for (unsigned int i = 0; i < vin.size(); i++) |
0a61b0df | 464 | { |
465 | if (vin[i].nSequence != old.vin[i].nSequence) | |
466 | { | |
467 | if (vin[i].nSequence <= nLowest) | |
468 | { | |
469 | fNewer = false; | |
470 | nLowest = vin[i].nSequence; | |
471 | } | |
472 | if (old.vin[i].nSequence < nLowest) | |
473 | { | |
474 | fNewer = true; | |
475 | nLowest = old.vin[i].nSequence; | |
476 | } | |
477 | } | |
478 | } | |
479 | return fNewer; | |
480 | } | |
481 | ||
482 | bool IsCoinBase() const | |
483 | { | |
484 | return (vin.size() == 1 && vin[0].prevout.IsNull()); | |
485 | } | |
486 | ||
8d7849b6 GA |
487 | /** Check for standard transaction types |
488 | @return True if all outputs (scriptPubKeys) use only standard transaction forms | |
489 | */ | |
e679ec96 | 490 | bool IsStandard() const; |
922e8e29 | 491 | |
8d7849b6 GA |
492 | /** Check for standard transaction types |
493 | @param[in] mapInputs Map of previous transactions that have outputs we're spending | |
494 | @return True if all inputs (scriptSigs) use only standard transaction forms | |
495 | @see CTransaction::FetchInputs | |
496 | */ | |
497 | bool AreInputsStandard(const MapPrevTx& mapInputs) const; | |
498 | ||
499 | /** Count ECDSA signature operations the old-fashioned (pre-0.6) way | |
500 | @return number of sigops this transaction's outputs will produce when spent | |
501 | @see CTransaction::FetchInputs | |
502 | */ | |
922e8e29 | 503 | int GetLegacySigOpCount() const; |
a206a239 | 504 | |
137d0685 | 505 | /** Count ECDSA signature operations in pay-to-script-hash inputs. |
8d7849b6 GA |
506 | |
507 | @param[in] mapInputs Map of previous transactions that have outputs we're spending | |
508 | @return maximum number of sigops required to validate this transaction's inputs | |
509 | @see CTransaction::FetchInputs | |
510 | */ | |
137d0685 | 511 | int GetP2SHSigOpCount(const MapPrevTx& mapInputs) const; |
8d7849b6 GA |
512 | |
513 | /** Amount of bitcoins spent by this transaction. | |
514 | @return sum of all outputs (note: does not include fees) | |
515 | */ | |
bde280b9 | 516 | int64 GetValueOut() const |
0a61b0df | 517 | { |
bde280b9 | 518 | int64 nValueOut = 0; |
223b6f1b | 519 | BOOST_FOREACH(const CTxOut& txout, vout) |
0a61b0df | 520 | { |
521 | nValueOut += txout.nValue; | |
522 | if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut)) | |
223b6f1b | 523 | throw std::runtime_error("CTransaction::GetValueOut() : value out of range"); |
0a61b0df | 524 | } |
525 | return nValueOut; | |
526 | } | |
527 | ||
8d7849b6 GA |
528 | /** Amount of bitcoins coming in to this transaction |
529 | Note that lightweight clients may not know anything besides the hash of previous transactions, | |
530 | so may not be able to calculate this. | |
531 | ||
532 | @param[in] mapInputs Map of previous transactions that have outputs we're spending | |
533 | @return Sum of value of all inputs (scriptSigs) | |
534 | @see CTransaction::FetchInputs | |
535 | */ | |
536 | int64 GetValueIn(const MapPrevTx& mapInputs) const; | |
537 | ||
395c1f44 GA |
538 | static bool AllowFree(double dPriority) |
539 | { | |
540 | // Large (in bytes) low-priority (new, small-coin) transactions | |
541 | // need a fee. | |
542 | return dPriority > COIN * 144 / 250; | |
543 | } | |
544 | ||
bde280b9 | 545 | int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true, enum GetMinFee_mode mode=GMF_BLOCK) const |
0a61b0df | 546 | { |
2bfda1be | 547 | // Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE |
bde280b9 | 548 | int64 nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_TX_FEE; |
2bfda1be | 549 | |
0a61b0df | 550 | unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK); |
9b8eb4d6 | 551 | unsigned int nNewBlockSize = nBlockSize + nBytes; |
bde280b9 | 552 | int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee; |
0a61b0df | 553 | |
f35e21e2 | 554 | if (fAllowFree) |
555 | { | |
298a7714 | 556 | if (nBlockSize == 1) |
557 | { | |
558 | // Transactions under 10K are free | |
559 | // (about 4500bc if made of 50bc inputs) | |
560 | if (nBytes < 10000) | |
561 | nMinFee = 0; | |
562 | } | |
563 | else | |
564 | { | |
565 | // Free transaction area | |
566 | if (nNewBlockSize < 27000) | |
567 | nMinFee = 0; | |
568 | } | |
f35e21e2 | 569 | } |
0a61b0df | 570 | |
2bfda1be PW |
571 | // To limit dust spam, require MIN_TX_FEE/MIN_RELAY_TX_FEE if any output is less than 0.01 |
572 | if (nMinFee < nBaseFee) | |
da7bbd9d | 573 | { |
223b6f1b | 574 | BOOST_FOREACH(const CTxOut& txout, vout) |
0a61b0df | 575 | if (txout.nValue < CENT) |
2bfda1be | 576 | nMinFee = nBaseFee; |
da7bbd9d | 577 | } |
0a61b0df | 578 | |
f1e1fb4b | 579 | // Raise the price as the block approaches full |
9b8eb4d6 | 580 | if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2) |
581 | { | |
582 | if (nNewBlockSize >= MAX_BLOCK_SIZE_GEN) | |
583 | return MAX_MONEY; | |
584 | nMinFee *= MAX_BLOCK_SIZE_GEN / (MAX_BLOCK_SIZE_GEN - nNewBlockSize); | |
585 | } | |
586 | ||
f1e1fb4b | 587 | if (!MoneyRange(nMinFee)) |
588 | nMinFee = MAX_MONEY; | |
0a61b0df | 589 | return nMinFee; |
590 | } | |
591 | ||
592 | ||
0a61b0df | 593 | bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL) |
594 | { | |
595 | CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb"); | |
596 | if (!filein) | |
597 | return error("CTransaction::ReadFromDisk() : OpenBlockFile failed"); | |
598 | ||
599 | // Read transaction | |
600 | if (fseek(filein, pos.nTxPos, SEEK_SET) != 0) | |
601 | return error("CTransaction::ReadFromDisk() : fseek failed"); | |
602 | filein >> *this; | |
603 | ||
604 | // Return file pointer | |
605 | if (pfileRet) | |
606 | { | |
607 | if (fseek(filein, pos.nTxPos, SEEK_SET) != 0) | |
608 | return error("CTransaction::ReadFromDisk() : second fseek failed"); | |
609 | *pfileRet = filein.release(); | |
610 | } | |
611 | return true; | |
612 | } | |
613 | ||
0a61b0df | 614 | friend bool operator==(const CTransaction& a, const CTransaction& b) |
615 | { | |
616 | return (a.nVersion == b.nVersion && | |
617 | a.vin == b.vin && | |
618 | a.vout == b.vout && | |
619 | a.nLockTime == b.nLockTime); | |
620 | } | |
621 | ||
622 | friend bool operator!=(const CTransaction& a, const CTransaction& b) | |
623 | { | |
624 | return !(a == b); | |
625 | } | |
626 | ||
627 | ||
223b6f1b | 628 | std::string ToString() const |
0a61b0df | 629 | { |
223b6f1b | 630 | std::string str; |
0a61b0df | 631 | str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n", |
b22c8842 | 632 | GetHash().ToString().substr(0,10).c_str(), |
0a61b0df | 633 | nVersion, |
634 | vin.size(), | |
635 | vout.size(), | |
636 | nLockTime); | |
c376ac35 | 637 | for (unsigned int i = 0; i < vin.size(); i++) |
0a61b0df | 638 | str += " " + vin[i].ToString() + "\n"; |
c376ac35 | 639 | for (unsigned int i = 0; i < vout.size(); i++) |
0a61b0df | 640 | str += " " + vout[i].ToString() + "\n"; |
641 | return str; | |
642 | } | |
643 | ||
644 | void print() const | |
645 | { | |
646 | printf("%s", ToString().c_str()); | |
647 | } | |
648 | ||
649 | ||
461764cb | 650 | bool ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet); |
651 | bool ReadFromDisk(CTxDB& txdb, COutPoint prevout); | |
652 | bool ReadFromDisk(COutPoint prevout); | |
0a61b0df | 653 | bool DisconnectInputs(CTxDB& txdb); |
2a45a494 | 654 | |
8d7849b6 GA |
655 | /** Fetch from memory and/or disk. inputsRet keys are transaction hashes. |
656 | ||
657 | @param[in] txdb Transaction database | |
658 | @param[in] mapTestPool List of pending changes to the transaction index database | |
659 | @param[in] fBlock True if being called to add a new best-block to the chain | |
660 | @param[in] fMiner True if being called by CreateNewBlock | |
661 | @param[out] inputsRet Pointers to this transaction's inputs | |
149f580c | 662 | @param[out] fInvalid returns true if transaction is invalid |
8d7849b6 GA |
663 | @return Returns true if all inputs are in txdb or mapTestPool |
664 | */ | |
e679ec96 | 665 | bool FetchInputs(CTxDB& txdb, const std::map<uint256, CTxIndex>& mapTestPool, |
149f580c | 666 | bool fBlock, bool fMiner, MapPrevTx& inputsRet, bool& fInvalid); |
8d7849b6 GA |
667 | |
668 | /** Sanity check previous transactions, then, if all checks succeed, | |
669 | mark them as spent by this transaction. | |
670 | ||
671 | @param[in] inputs Previous transactions (from FetchInputs) | |
672 | @param[out] mapTestPool Keeps track of inputs that need to be updated on disk | |
673 | @param[in] posThisTx Position of this transaction on disk | |
674 | @param[in] pindexBlock | |
675 | @param[in] fBlock true if called from ConnectBlock | |
676 | @param[in] fMiner true if called from CreateNewBlock | |
137d0685 | 677 | @param[in] fStrictPayToScriptHash true if fully validating p2sh transactions |
8d7849b6 GA |
678 | @return Returns true if all checks succeed |
679 | */ | |
680 | bool ConnectInputs(MapPrevTx inputs, | |
922e8e29 | 681 | std::map<uint256, CTxIndex>& mapTestPool, const CDiskTxPos& posThisTx, |
137d0685 | 682 | const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, bool fStrictPayToScriptHash=true); |
0a61b0df | 683 | bool ClientConnectInputs(); |
a790fa46 | 684 | bool CheckTransaction() const; |
f1e1fb4b | 685 | bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL); |
8d7849b6 | 686 | |
0a61b0df | 687 | protected: |
8d7849b6 | 688 | const CTxOut& GetOutputFor(const CTxIn& input, const MapPrevTx& inputs) const; |
f1e1fb4b | 689 | bool AddToMemoryPoolUnchecked(); |
0a61b0df | 690 | public: |
691 | bool RemoveFromMemoryPool(); | |
692 | }; | |
693 | ||
694 | ||
695 | ||
696 | ||
697 | ||
6b8de05d | 698 | /** A transaction with a merkle branch linking it to the block chain. */ |
0a61b0df | 699 | class CMerkleTx : public CTransaction |
700 | { | |
701 | public: | |
702 | uint256 hashBlock; | |
223b6f1b | 703 | std::vector<uint256> vMerkleBranch; |
0a61b0df | 704 | int nIndex; |
705 | ||
706 | // memory only | |
a790fa46 | 707 | mutable char fMerkleVerified; |
0a61b0df | 708 | |
709 | ||
710 | CMerkleTx() | |
711 | { | |
712 | Init(); | |
713 | } | |
714 | ||
715 | CMerkleTx(const CTransaction& txIn) : CTransaction(txIn) | |
716 | { | |
717 | Init(); | |
718 | } | |
719 | ||
720 | void Init() | |
721 | { | |
722 | hashBlock = 0; | |
723 | nIndex = -1; | |
724 | fMerkleVerified = false; | |
0a61b0df | 725 | } |
726 | ||
335e878b | 727 | |
0a61b0df | 728 | IMPLEMENT_SERIALIZE |
729 | ( | |
730 | nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action); | |
731 | nVersion = this->nVersion; | |
732 | READWRITE(hashBlock); | |
733 | READWRITE(vMerkleBranch); | |
734 | READWRITE(nIndex); | |
735 | ) | |
736 | ||
0a61b0df | 737 | |
738 | int SetMerkleBranch(const CBlock* pblock=NULL); | |
30ab2c9c PW |
739 | int GetDepthInMainChain(CBlockIndex* &pindexRet) const; |
740 | int GetDepthInMainChain() const { CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); } | |
0a61b0df | 741 | bool IsInMainChain() const { return GetDepthInMainChain() > 0; } |
742 | int GetBlocksToMaturity() const; | |
f1e1fb4b | 743 | bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true); |
e89b9f6a | 744 | bool AcceptToMemoryPool(); |
0a61b0df | 745 | }; |
746 | ||
747 | ||
748 | ||
749 | ||
6b8de05d PW |
750 | /** A txdb record that contains the disk location of a transaction and the |
751 | * locations of transactions that spend its outputs. vSpent is really only | |
752 | * used as a flag, but having the location is very helpful for debugging. | |
753 | */ | |
0a61b0df | 754 | class CTxIndex |
755 | { | |
756 | public: | |
757 | CDiskTxPos pos; | |
223b6f1b | 758 | std::vector<CDiskTxPos> vSpent; |
0a61b0df | 759 | |
760 | CTxIndex() | |
761 | { | |
762 | SetNull(); | |
763 | } | |
764 | ||
765 | CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs) | |
766 | { | |
767 | pos = posIn; | |
768 | vSpent.resize(nOutputs); | |
769 | } | |
770 | ||
771 | IMPLEMENT_SERIALIZE | |
772 | ( | |
773 | if (!(nType & SER_GETHASH)) | |
774 | READWRITE(nVersion); | |
775 | READWRITE(pos); | |
776 | READWRITE(vSpent); | |
777 | ) | |
778 | ||
779 | void SetNull() | |
780 | { | |
781 | pos.SetNull(); | |
782 | vSpent.clear(); | |
783 | } | |
784 | ||
785 | bool IsNull() | |
786 | { | |
787 | return pos.IsNull(); | |
788 | } | |
789 | ||
790 | friend bool operator==(const CTxIndex& a, const CTxIndex& b) | |
791 | { | |
f1e1fb4b | 792 | return (a.pos == b.pos && |
793 | a.vSpent == b.vSpent); | |
0a61b0df | 794 | } |
795 | ||
796 | friend bool operator!=(const CTxIndex& a, const CTxIndex& b) | |
797 | { | |
798 | return !(a == b); | |
799 | } | |
395c1f44 | 800 | int GetDepthInMainChain() const; |
30ab2c9c | 801 | |
0a61b0df | 802 | }; |
803 | ||
804 | ||
805 | ||
806 | ||
807 | ||
6b8de05d PW |
808 | /** Nodes collect new transactions into a block, hash them into a hash tree, |
809 | * and scan through nonce values to make the block's hash satisfy proof-of-work | |
810 | * requirements. When they solve the proof-of-work, they broadcast the block | |
811 | * to everyone and the block is added to the block chain. The first transaction | |
812 | * in the block is a special one that creates a new coin owned by the creator | |
813 | * of the block. | |
814 | * | |
815 | * Blocks are appended to blk0001.dat files on disk. Their location on disk | |
816 | * is indexed by CBlockIndex objects in memory. | |
817 | */ | |
0a61b0df | 818 | class CBlock |
819 | { | |
820 | public: | |
821 | // header | |
822 | int nVersion; | |
823 | uint256 hashPrevBlock; | |
824 | uint256 hashMerkleRoot; | |
825 | unsigned int nTime; | |
826 | unsigned int nBits; | |
827 | unsigned int nNonce; | |
828 | ||
829 | // network and disk | |
223b6f1b | 830 | std::vector<CTransaction> vtx; |
0a61b0df | 831 | |
832 | // memory only | |
223b6f1b | 833 | mutable std::vector<uint256> vMerkleTree; |
0a61b0df | 834 | |
3e52aaf2 GA |
835 | // Denial-of-service detection: |
836 | mutable int nDoS; | |
837 | bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; } | |
0a61b0df | 838 | |
839 | CBlock() | |
840 | { | |
841 | SetNull(); | |
842 | } | |
843 | ||
844 | IMPLEMENT_SERIALIZE | |
845 | ( | |
846 | READWRITE(this->nVersion); | |
847 | nVersion = this->nVersion; | |
848 | READWRITE(hashPrevBlock); | |
849 | READWRITE(hashMerkleRoot); | |
850 | READWRITE(nTime); | |
851 | READWRITE(nBits); | |
852 | READWRITE(nNonce); | |
853 | ||
854 | // ConnectBlock depends on vtx being last so it can calculate offset | |
855 | if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY))) | |
856 | READWRITE(vtx); | |
857 | else if (fRead) | |
858 | const_cast<CBlock*>(this)->vtx.clear(); | |
859 | ) | |
860 | ||
861 | void SetNull() | |
862 | { | |
863 | nVersion = 1; | |
864 | hashPrevBlock = 0; | |
865 | hashMerkleRoot = 0; | |
866 | nTime = 0; | |
867 | nBits = 0; | |
868 | nNonce = 0; | |
869 | vtx.clear(); | |
870 | vMerkleTree.clear(); | |
3e52aaf2 | 871 | nDoS = 0; |
0a61b0df | 872 | } |
873 | ||
874 | bool IsNull() const | |
875 | { | |
876 | return (nBits == 0); | |
877 | } | |
878 | ||
879 | uint256 GetHash() const | |
880 | { | |
881 | return Hash(BEGIN(nVersion), END(nNonce)); | |
882 | } | |
883 | ||
bde280b9 | 884 | int64 GetBlockTime() const |
0a61b0df | 885 | { |
bde280b9 | 886 | return (int64)nTime; |
0a61b0df | 887 | } |
888 | ||
0f8cb5db | 889 | void UpdateTime(const CBlockIndex* pindexPrev); |
f1e1fb4b | 890 | |
0a61b0df | 891 | |
892 | uint256 BuildMerkleTree() const | |
893 | { | |
894 | vMerkleTree.clear(); | |
223b6f1b | 895 | BOOST_FOREACH(const CTransaction& tx, vtx) |
0a61b0df | 896 | vMerkleTree.push_back(tx.GetHash()); |
897 | int j = 0; | |
898 | for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) | |
899 | { | |
900 | for (int i = 0; i < nSize; i += 2) | |
901 | { | |
223b6f1b | 902 | int i2 = std::min(i+1, nSize-1); |
0a61b0df | 903 | vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]), |
904 | BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2]))); | |
905 | } | |
906 | j += nSize; | |
907 | } | |
908 | return (vMerkleTree.empty() ? 0 : vMerkleTree.back()); | |
909 | } | |
910 | ||
223b6f1b | 911 | std::vector<uint256> GetMerkleBranch(int nIndex) const |
0a61b0df | 912 | { |
913 | if (vMerkleTree.empty()) | |
914 | BuildMerkleTree(); | |
223b6f1b | 915 | std::vector<uint256> vMerkleBranch; |
0a61b0df | 916 | int j = 0; |
917 | for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) | |
918 | { | |
223b6f1b | 919 | int i = std::min(nIndex^1, nSize-1); |
0a61b0df | 920 | vMerkleBranch.push_back(vMerkleTree[j+i]); |
921 | nIndex >>= 1; | |
922 | j += nSize; | |
923 | } | |
924 | return vMerkleBranch; | |
925 | } | |
926 | ||
223b6f1b | 927 | static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex) |
0a61b0df | 928 | { |
929 | if (nIndex == -1) | |
930 | return 0; | |
223b6f1b | 931 | BOOST_FOREACH(const uint256& otherside, vMerkleBranch) |
0a61b0df | 932 | { |
933 | if (nIndex & 1) | |
934 | hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash)); | |
935 | else | |
936 | hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside)); | |
937 | nIndex >>= 1; | |
938 | } | |
939 | return hash; | |
940 | } | |
941 | ||
942 | ||
f03304a9 | 943 | bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet) |
0a61b0df | 944 | { |
945 | // Open history file to append | |
946 | CAutoFile fileout = AppendBlockFile(nFileRet); | |
947 | if (!fileout) | |
948 | return error("CBlock::WriteToDisk() : AppendBlockFile failed"); | |
0a61b0df | 949 | |
950 | // Write index header | |
951 | unsigned int nSize = fileout.GetSerializeSize(*this); | |
952 | fileout << FLATDATA(pchMessageStart) << nSize; | |
953 | ||
954 | // Write block | |
955 | nBlockPosRet = ftell(fileout); | |
956 | if (nBlockPosRet == -1) | |
957 | return error("CBlock::WriteToDisk() : ftell failed"); | |
958 | fileout << *this; | |
959 | ||
960 | // Flush stdio buffers and commit to disk before returning | |
961 | fflush(fileout); | |
962 | if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0) | |
963 | { | |
6853e627 | 964 | #ifdef WIN32 |
0a61b0df | 965 | _commit(_fileno(fileout)); |
966 | #else | |
967 | fsync(fileno(fileout)); | |
968 | #endif | |
969 | } | |
970 | ||
971 | return true; | |
972 | } | |
973 | ||
974 | bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true) | |
975 | { | |
976 | SetNull(); | |
977 | ||
978 | // Open history file to read | |
979 | CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb"); | |
980 | if (!filein) | |
981 | return error("CBlock::ReadFromDisk() : OpenBlockFile failed"); | |
982 | if (!fReadTransactions) | |
983 | filein.nType |= SER_BLOCKHEADERONLY; | |
984 | ||
985 | // Read block | |
986 | filein >> *this; | |
987 | ||
988 | // Check the header | |
989 | if (!CheckProofOfWork(GetHash(), nBits)) | |
990 | return error("CBlock::ReadFromDisk() : errors in block header"); | |
991 | ||
992 | return true; | |
993 | } | |
994 | ||
995 | ||
996 | ||
997 | void print() const | |
998 | { | |
999 | printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n", | |
1000 | GetHash().ToString().substr(0,20).c_str(), | |
1001 | nVersion, | |
1002 | hashPrevBlock.ToString().substr(0,20).c_str(), | |
b22c8842 | 1003 | hashMerkleRoot.ToString().substr(0,10).c_str(), |
0a61b0df | 1004 | nTime, nBits, nNonce, |
1005 | vtx.size()); | |
c376ac35 | 1006 | for (unsigned int i = 0; i < vtx.size(); i++) |
0a61b0df | 1007 | { |
1008 | printf(" "); | |
1009 | vtx[i].print(); | |
1010 | } | |
1011 | printf(" vMerkleTree: "); | |
c376ac35 | 1012 | for (unsigned int i = 0; i < vMerkleTree.size(); i++) |
b22c8842 | 1013 | printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str()); |
0a61b0df | 1014 | printf("\n"); |
1015 | } | |
1016 | ||
1017 | ||
0a61b0df | 1018 | bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex); |
1019 | bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex); | |
1020 | bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true); | |
1021 | bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew); | |
1022 | bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos); | |
1023 | bool CheckBlock() const; | |
1024 | bool AcceptBlock(); | |
d68dcf74 PW |
1025 | |
1026 | private: | |
1027 | bool SetBestChainInner(CTxDB& txdb, CBlockIndex *pindexNew); | |
0a61b0df | 1028 | }; |
1029 | ||
1030 | ||
1031 | ||
1032 | ||
1033 | ||
1034 | ||
6b8de05d PW |
1035 | /** The block chain is a tree shaped structure starting with the |
1036 | * genesis block at the root, with each block potentially having multiple | |
1037 | * candidates to be the next block. pprev and pnext link a path through the | |
1038 | * main/longest chain. A blockindex may have multiple pprev pointing back | |
1039 | * to it, but pnext will only point forward to the longest branch, or will | |
1040 | * be null if the block is not part of the longest chain. | |
1041 | */ | |
0a61b0df | 1042 | class CBlockIndex |
1043 | { | |
1044 | public: | |
1045 | const uint256* phashBlock; | |
1046 | CBlockIndex* pprev; | |
1047 | CBlockIndex* pnext; | |
1048 | unsigned int nFile; | |
1049 | unsigned int nBlockPos; | |
1050 | int nHeight; | |
1051 | CBigNum bnChainWork; | |
1052 | ||
1053 | // block header | |
1054 | int nVersion; | |
1055 | uint256 hashMerkleRoot; | |
1056 | unsigned int nTime; | |
1057 | unsigned int nBits; | |
1058 | unsigned int nNonce; | |
1059 | ||
1060 | ||
1061 | CBlockIndex() | |
1062 | { | |
1063 | phashBlock = NULL; | |
1064 | pprev = NULL; | |
1065 | pnext = NULL; | |
1066 | nFile = 0; | |
1067 | nBlockPos = 0; | |
1068 | nHeight = 0; | |
1069 | bnChainWork = 0; | |
1070 | ||
1071 | nVersion = 0; | |
1072 | hashMerkleRoot = 0; | |
1073 | nTime = 0; | |
1074 | nBits = 0; | |
1075 | nNonce = 0; | |
1076 | } | |
1077 | ||
1078 | CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block) | |
1079 | { | |
1080 | phashBlock = NULL; | |
1081 | pprev = NULL; | |
1082 | pnext = NULL; | |
1083 | nFile = nFileIn; | |
1084 | nBlockPos = nBlockPosIn; | |
1085 | nHeight = 0; | |
1086 | bnChainWork = 0; | |
1087 | ||
1088 | nVersion = block.nVersion; | |
1089 | hashMerkleRoot = block.hashMerkleRoot; | |
1090 | nTime = block.nTime; | |
1091 | nBits = block.nBits; | |
1092 | nNonce = block.nNonce; | |
1093 | } | |
1094 | ||
f03304a9 | 1095 | CBlock GetBlockHeader() const |
1096 | { | |
1097 | CBlock block; | |
1098 | block.nVersion = nVersion; | |
1099 | if (pprev) | |
1100 | block.hashPrevBlock = pprev->GetBlockHash(); | |
1101 | block.hashMerkleRoot = hashMerkleRoot; | |
1102 | block.nTime = nTime; | |
1103 | block.nBits = nBits; | |
1104 | block.nNonce = nNonce; | |
1105 | return block; | |
1106 | } | |
1107 | ||
0a61b0df | 1108 | uint256 GetBlockHash() const |
1109 | { | |
1110 | return *phashBlock; | |
1111 | } | |
1112 | ||
bde280b9 | 1113 | int64 GetBlockTime() const |
0a61b0df | 1114 | { |
bde280b9 | 1115 | return (int64)nTime; |
0a61b0df | 1116 | } |
1117 | ||
1118 | CBigNum GetBlockWork() const | |
1119 | { | |
9b8eb4d6 | 1120 | CBigNum bnTarget; |
1121 | bnTarget.SetCompact(nBits); | |
1122 | if (bnTarget <= 0) | |
0a61b0df | 1123 | return 0; |
9b8eb4d6 | 1124 | return (CBigNum(1)<<256) / (bnTarget+1); |
0a61b0df | 1125 | } |
1126 | ||
1127 | bool IsInMainChain() const | |
1128 | { | |
1129 | return (pnext || this == pindexBest); | |
1130 | } | |
1131 | ||
1132 | bool CheckIndex() const | |
1133 | { | |
1134 | return CheckProofOfWork(GetBlockHash(), nBits); | |
1135 | } | |
1136 | ||
1137 | bool EraseBlockFromDisk() | |
1138 | { | |
1139 | // Open history file | |
1140 | CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+"); | |
1141 | if (!fileout) | |
1142 | return false; | |
1143 | ||
1144 | // Overwrite with empty null block | |
1145 | CBlock block; | |
1146 | block.SetNull(); | |
1147 | fileout << block; | |
1148 | ||
1149 | return true; | |
1150 | } | |
1151 | ||
1152 | enum { nMedianTimeSpan=11 }; | |
1153 | ||
bde280b9 | 1154 | int64 GetMedianTimePast() const |
0a61b0df | 1155 | { |
bde280b9 WL |
1156 | int64 pmedian[nMedianTimeSpan]; |
1157 | int64* pbegin = &pmedian[nMedianTimeSpan]; | |
1158 | int64* pend = &pmedian[nMedianTimeSpan]; | |
0a61b0df | 1159 | |
1160 | const CBlockIndex* pindex = this; | |
1161 | for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev) | |
1162 | *(--pbegin) = pindex->GetBlockTime(); | |
1163 | ||
223b6f1b | 1164 | std::sort(pbegin, pend); |
0a61b0df | 1165 | return pbegin[(pend - pbegin)/2]; |
1166 | } | |
1167 | ||
bde280b9 | 1168 | int64 GetMedianTime() const |
0a61b0df | 1169 | { |
1170 | const CBlockIndex* pindex = this; | |
1171 | for (int i = 0; i < nMedianTimeSpan/2; i++) | |
1172 | { | |
1173 | if (!pindex->pnext) | |
1174 | return GetBlockTime(); | |
1175 | pindex = pindex->pnext; | |
1176 | } | |
1177 | return pindex->GetMedianTimePast(); | |
1178 | } | |
1179 | ||
1180 | ||
1181 | ||
223b6f1b | 1182 | std::string ToString() const |
0a61b0df | 1183 | { |
1184 | return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)", | |
1185 | pprev, pnext, nFile, nBlockPos, nHeight, | |
b22c8842 | 1186 | hashMerkleRoot.ToString().substr(0,10).c_str(), |
0a61b0df | 1187 | GetBlockHash().ToString().substr(0,20).c_str()); |
1188 | } | |
1189 | ||
1190 | void print() const | |
1191 | { | |
1192 | printf("%s\n", ToString().c_str()); | |
1193 | } | |
1194 | }; | |
1195 | ||
1196 | ||
1197 | ||
6b8de05d | 1198 | /** Used to marshal pointers into hashes for db storage. */ |
0a61b0df | 1199 | class CDiskBlockIndex : public CBlockIndex |
1200 | { | |
1201 | public: | |
1202 | uint256 hashPrev; | |
1203 | uint256 hashNext; | |
1204 | ||
1205 | CDiskBlockIndex() | |
1206 | { | |
1207 | hashPrev = 0; | |
1208 | hashNext = 0; | |
1209 | } | |
1210 | ||
1211 | explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex) | |
1212 | { | |
1213 | hashPrev = (pprev ? pprev->GetBlockHash() : 0); | |
1214 | hashNext = (pnext ? pnext->GetBlockHash() : 0); | |
1215 | } | |
1216 | ||
1217 | IMPLEMENT_SERIALIZE | |
1218 | ( | |
1219 | if (!(nType & SER_GETHASH)) | |
1220 | READWRITE(nVersion); | |
1221 | ||
1222 | READWRITE(hashNext); | |
1223 | READWRITE(nFile); | |
1224 | READWRITE(nBlockPos); | |
1225 | READWRITE(nHeight); | |
1226 | ||
1227 | // block header | |
1228 | READWRITE(this->nVersion); | |
1229 | READWRITE(hashPrev); | |
1230 | READWRITE(hashMerkleRoot); | |
1231 | READWRITE(nTime); | |
1232 | READWRITE(nBits); | |
1233 | READWRITE(nNonce); | |
1234 | ) | |
1235 | ||
1236 | uint256 GetBlockHash() const | |
1237 | { | |
1238 | CBlock block; | |
1239 | block.nVersion = nVersion; | |
1240 | block.hashPrevBlock = hashPrev; | |
1241 | block.hashMerkleRoot = hashMerkleRoot; | |
1242 | block.nTime = nTime; | |
1243 | block.nBits = nBits; | |
1244 | block.nNonce = nNonce; | |
1245 | return block.GetHash(); | |
1246 | } | |
1247 | ||
1248 | ||
223b6f1b | 1249 | std::string ToString() const |
0a61b0df | 1250 | { |
223b6f1b | 1251 | std::string str = "CDiskBlockIndex("; |
0a61b0df | 1252 | str += CBlockIndex::ToString(); |
1253 | str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)", | |
1254 | GetBlockHash().ToString().c_str(), | |
1255 | hashPrev.ToString().substr(0,20).c_str(), | |
1256 | hashNext.ToString().substr(0,20).c_str()); | |
1257 | return str; | |
1258 | } | |
1259 | ||
1260 | void print() const | |
1261 | { | |
1262 | printf("%s\n", ToString().c_str()); | |
1263 | } | |
1264 | }; | |
1265 | ||
1266 | ||
1267 | ||
1268 | ||
1269 | ||
1270 | ||
1271 | ||
1272 | ||
6b8de05d PW |
1273 | /** Describes a place in the block chain to another node such that if the |
1274 | * other node doesn't have the same branch, it can find a recent common trunk. | |
1275 | * The further back it is, the further before the fork it may be. | |
1276 | */ | |
0a61b0df | 1277 | class CBlockLocator |
1278 | { | |
1279 | protected: | |
223b6f1b | 1280 | std::vector<uint256> vHave; |
0a61b0df | 1281 | public: |
1282 | ||
1283 | CBlockLocator() | |
1284 | { | |
1285 | } | |
1286 | ||
1287 | explicit CBlockLocator(const CBlockIndex* pindex) | |
1288 | { | |
1289 | Set(pindex); | |
1290 | } | |
1291 | ||
1292 | explicit CBlockLocator(uint256 hashBlock) | |
1293 | { | |
223b6f1b | 1294 | std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); |
0a61b0df | 1295 | if (mi != mapBlockIndex.end()) |
1296 | Set((*mi).second); | |
1297 | } | |
1298 | ||
30ab2c9c PW |
1299 | CBlockLocator(const std::vector<uint256>& vHaveIn) |
1300 | { | |
1301 | vHave = vHaveIn; | |
1302 | } | |
1303 | ||
0a61b0df | 1304 | IMPLEMENT_SERIALIZE |
1305 | ( | |
1306 | if (!(nType & SER_GETHASH)) | |
1307 | READWRITE(nVersion); | |
1308 | READWRITE(vHave); | |
1309 | ) | |
1310 | ||
f03304a9 | 1311 | void SetNull() |
1312 | { | |
1313 | vHave.clear(); | |
1314 | } | |
1315 | ||
1316 | bool IsNull() | |
1317 | { | |
1318 | return vHave.empty(); | |
1319 | } | |
1320 | ||
0a61b0df | 1321 | void Set(const CBlockIndex* pindex) |
1322 | { | |
1323 | vHave.clear(); | |
1324 | int nStep = 1; | |
1325 | while (pindex) | |
1326 | { | |
1327 | vHave.push_back(pindex->GetBlockHash()); | |
1328 | ||
1329 | // Exponentially larger steps back | |
1330 | for (int i = 0; pindex && i < nStep; i++) | |
1331 | pindex = pindex->pprev; | |
1332 | if (vHave.size() > 10) | |
1333 | nStep *= 2; | |
1334 | } | |
1335 | vHave.push_back(hashGenesisBlock); | |
1336 | } | |
1337 | ||
1338 | int GetDistanceBack() | |
1339 | { | |
1340 | // Retrace how far back it was in the sender's branch | |
1341 | int nDistance = 0; | |
1342 | int nStep = 1; | |
223b6f1b | 1343 | BOOST_FOREACH(const uint256& hash, vHave) |
0a61b0df | 1344 | { |
223b6f1b | 1345 | std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash); |
0a61b0df | 1346 | if (mi != mapBlockIndex.end()) |
1347 | { | |
1348 | CBlockIndex* pindex = (*mi).second; | |
1349 | if (pindex->IsInMainChain()) | |
1350 | return nDistance; | |
1351 | } | |
1352 | nDistance += nStep; | |
1353 | if (nDistance > 10) | |
1354 | nStep *= 2; | |
1355 | } | |
1356 | return nDistance; | |
1357 | } | |
1358 | ||
1359 | CBlockIndex* GetBlockIndex() | |
1360 | { | |
1361 | // Find the first block the caller has in the main chain | |
223b6f1b | 1362 | BOOST_FOREACH(const uint256& hash, vHave) |
0a61b0df | 1363 | { |
223b6f1b | 1364 | std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash); |
0a61b0df | 1365 | if (mi != mapBlockIndex.end()) |
1366 | { | |
1367 | CBlockIndex* pindex = (*mi).second; | |
1368 | if (pindex->IsInMainChain()) | |
1369 | return pindex; | |
1370 | } | |
1371 | } | |
1372 | return pindexGenesisBlock; | |
1373 | } | |
1374 | ||
1375 | uint256 GetBlockHash() | |
1376 | { | |
1377 | // Find the first block the caller has in the main chain | |
223b6f1b | 1378 | BOOST_FOREACH(const uint256& hash, vHave) |
0a61b0df | 1379 | { |
223b6f1b | 1380 | std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash); |
0a61b0df | 1381 | if (mi != mapBlockIndex.end()) |
1382 | { | |
1383 | CBlockIndex* pindex = (*mi).second; | |
1384 | if (pindex->IsInMainChain()) | |
1385 | return hash; | |
1386 | } | |
1387 | } | |
1388 | return hashGenesisBlock; | |
1389 | } | |
1390 | ||
1391 | int GetHeight() | |
1392 | { | |
1393 | CBlockIndex* pindex = GetBlockIndex(); | |
1394 | if (!pindex) | |
1395 | return 0; | |
1396 | return pindex->nHeight; | |
1397 | } | |
1398 | }; | |
1399 | ||
1400 | ||
1401 | ||
1402 | ||
1403 | ||
1404 | ||
e4ff4e68 | 1405 | |
1406 | ||
1407 | ||
6b8de05d PW |
1408 | /** Alerts are for notifying old versions if they become too obsolete and |
1409 | * need to upgrade. The message is displayed in the status bar. | |
1410 | * Alert messages are broadcast as a vector of signed data. Unserializing may | |
1411 | * not read the entire buffer if the alert is for a newer version, but older | |
1412 | * versions can still relay the original data. | |
1413 | */ | |
0a61b0df | 1414 | class CUnsignedAlert |
1415 | { | |
1416 | public: | |
1417 | int nVersion; | |
bde280b9 WL |
1418 | int64 nRelayUntil; // when newer nodes stop relaying to newer nodes |
1419 | int64 nExpiration; | |
0a61b0df | 1420 | int nID; |
1421 | int nCancel; | |
223b6f1b | 1422 | std::set<int> setCancel; |
0a61b0df | 1423 | int nMinVer; // lowest version inclusive |
1424 | int nMaxVer; // highest version inclusive | |
223b6f1b | 1425 | std::set<std::string> setSubVer; // empty matches all |
0a61b0df | 1426 | int nPriority; |
1427 | ||
1428 | // Actions | |
223b6f1b WL |
1429 | std::string strComment; |
1430 | std::string strStatusBar; | |
1431 | std::string strReserved; | |
0a61b0df | 1432 | |
1433 | IMPLEMENT_SERIALIZE | |
1434 | ( | |
1435 | READWRITE(this->nVersion); | |
1436 | nVersion = this->nVersion; | |
1437 | READWRITE(nRelayUntil); | |
1438 | READWRITE(nExpiration); | |
1439 | READWRITE(nID); | |
1440 | READWRITE(nCancel); | |
1441 | READWRITE(setCancel); | |
1442 | READWRITE(nMinVer); | |
1443 | READWRITE(nMaxVer); | |
1444 | READWRITE(setSubVer); | |
1445 | READWRITE(nPriority); | |
1446 | ||
1447 | READWRITE(strComment); | |
1448 | READWRITE(strStatusBar); | |
986b5e25 | 1449 | READWRITE(strReserved); |
0a61b0df | 1450 | ) |
1451 | ||
1452 | void SetNull() | |
1453 | { | |
1454 | nVersion = 1; | |
1455 | nRelayUntil = 0; | |
1456 | nExpiration = 0; | |
1457 | nID = 0; | |
1458 | nCancel = 0; | |
1459 | setCancel.clear(); | |
1460 | nMinVer = 0; | |
1461 | nMaxVer = 0; | |
1462 | setSubVer.clear(); | |
1463 | nPriority = 0; | |
1464 | ||
1465 | strComment.clear(); | |
1466 | strStatusBar.clear(); | |
986b5e25 | 1467 | strReserved.clear(); |
0a61b0df | 1468 | } |
1469 | ||
223b6f1b | 1470 | std::string ToString() const |
0a61b0df | 1471 | { |
223b6f1b WL |
1472 | std::string strSetCancel; |
1473 | BOOST_FOREACH(int n, setCancel) | |
0a61b0df | 1474 | strSetCancel += strprintf("%d ", n); |
223b6f1b WL |
1475 | std::string strSetSubVer; |
1476 | BOOST_FOREACH(std::string str, setSubVer) | |
0a61b0df | 1477 | strSetSubVer += "\"" + str + "\" "; |
1478 | return strprintf( | |
1479 | "CAlert(\n" | |
1480 | " nVersion = %d\n" | |
1481 | " nRelayUntil = %"PRI64d"\n" | |
1482 | " nExpiration = %"PRI64d"\n" | |
1483 | " nID = %d\n" | |
1484 | " nCancel = %d\n" | |
1485 | " setCancel = %s\n" | |
1486 | " nMinVer = %d\n" | |
1487 | " nMaxVer = %d\n" | |
1488 | " setSubVer = %s\n" | |
1489 | " nPriority = %d\n" | |
1490 | " strComment = \"%s\"\n" | |
1491 | " strStatusBar = \"%s\"\n" | |
0a61b0df | 1492 | ")\n", |
1493 | nVersion, | |
1494 | nRelayUntil, | |
1495 | nExpiration, | |
1496 | nID, | |
1497 | nCancel, | |
1498 | strSetCancel.c_str(), | |
1499 | nMinVer, | |
1500 | nMaxVer, | |
1501 | strSetSubVer.c_str(), | |
1502 | nPriority, | |
1503 | strComment.c_str(), | |
986b5e25 | 1504 | strStatusBar.c_str()); |
0a61b0df | 1505 | } |
1506 | ||
1507 | void print() const | |
1508 | { | |
1509 | printf("%s", ToString().c_str()); | |
1510 | } | |
1511 | }; | |
1512 | ||
6b8de05d | 1513 | /** An alert is a combination of a serialized CUnsignedAlert and a signature. */ |
0a61b0df | 1514 | class CAlert : public CUnsignedAlert |
1515 | { | |
1516 | public: | |
223b6f1b WL |
1517 | std::vector<unsigned char> vchMsg; |
1518 | std::vector<unsigned char> vchSig; | |
0a61b0df | 1519 | |
1520 | CAlert() | |
1521 | { | |
1522 | SetNull(); | |
1523 | } | |
1524 | ||
1525 | IMPLEMENT_SERIALIZE | |
1526 | ( | |
1527 | READWRITE(vchMsg); | |
1528 | READWRITE(vchSig); | |
1529 | ) | |
1530 | ||
1531 | void SetNull() | |
1532 | { | |
1533 | CUnsignedAlert::SetNull(); | |
1534 | vchMsg.clear(); | |
1535 | vchSig.clear(); | |
1536 | } | |
1537 | ||
1538 | bool IsNull() const | |
1539 | { | |
1540 | return (nExpiration == 0); | |
1541 | } | |
1542 | ||
1543 | uint256 GetHash() const | |
1544 | { | |
1545 | return SerializeHash(*this); | |
1546 | } | |
1547 | ||
1548 | bool IsInEffect() const | |
1549 | { | |
1550 | return (GetAdjustedTime() < nExpiration); | |
1551 | } | |
1552 | ||
1553 | bool Cancels(const CAlert& alert) const | |
1554 | { | |
1555 | if (!IsInEffect()) | |
461764cb | 1556 | return false; // this was a no-op before 31403 |
0a61b0df | 1557 | return (alert.nID <= nCancel || setCancel.count(alert.nID)); |
1558 | } | |
1559 | ||
223b6f1b | 1560 | bool AppliesTo(int nVersion, std::string strSubVerIn) const |
0a61b0df | 1561 | { |
f8ded588 | 1562 | // TODO: rework for client-version-embedded-in-strSubVer ? |
0a61b0df | 1563 | return (IsInEffect() && |
1564 | nMinVer <= nVersion && nVersion <= nMaxVer && | |
1565 | (setSubVer.empty() || setSubVer.count(strSubVerIn))); | |
1566 | } | |
1567 | ||
1568 | bool AppliesToMe() const | |
1569 | { | |
f8ded588 | 1570 | return AppliesTo(PROTOCOL_VERSION, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<std::string>())); |
0a61b0df | 1571 | } |
1572 | ||
1573 | bool RelayTo(CNode* pnode) const | |
1574 | { | |
1575 | if (!IsInEffect()) | |
1576 | return false; | |
1577 | // returns true if wasn't already contained in the set | |
1578 | if (pnode->setKnown.insert(GetHash()).second) | |
1579 | { | |
1580 | if (AppliesTo(pnode->nVersion, pnode->strSubVer) || | |
1581 | AppliesToMe() || | |
1582 | GetAdjustedTime() < nRelayUntil) | |
1583 | { | |
1584 | pnode->PushMessage("alert", *this); | |
1585 | return true; | |
1586 | } | |
1587 | } | |
1588 | return false; | |
1589 | } | |
1590 | ||
1591 | bool CheckSignature() | |
1592 | { | |
1593 | CKey key; | |
1594 | if (!key.SetPubKey(ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"))) | |
1595 | return error("CAlert::CheckSignature() : SetPubKey failed"); | |
1596 | if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig)) | |
1597 | return error("CAlert::CheckSignature() : verify signature failed"); | |
1598 | ||
1599 | // Now unserialize the data | |
1600 | CDataStream sMsg(vchMsg); | |
1601 | sMsg >> *(CUnsignedAlert*)this; | |
1602 | return true; | |
1603 | } | |
1604 | ||
1605 | bool ProcessAlert(); | |
1606 | }; | |
1607 | ||
223b6f1b | 1608 | #endif |