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