Projects : bitcoin : bitcoin_getblockindex_etc

bitcoin/src/main.h

Dir - Raw

1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-2012 The Bitcoin developers
3// Distributed under the MIT/X11 software license, see the accompanying
4// file license.txt or http://www.opensource.org/licenses/mit-license.php.
5#ifndef BITCOIN_MAIN_H
6#define BITCOIN_MAIN_H
7
8#include "bignum.h"
9#include "net.h"
10#include "key.h"
11#include "script.h"
12#include "db.h"
13
14#include <list>
15
16class CBlock;
17class CBlockIndex;
18class CWalletTx;
19class CWallet;
20class CKeyItem;
21class CReserveKey;
22class CWalletDB;
23
24class CAddress;
25class CInv;
26class CRequestTracker;
27class CNode;
28class CBlockIndex;
29
30static const unsigned int MAX_BLOCK_SIZE = 1000000;
31static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
32static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
33static const int64 COIN = 100000000;
34static const int64 CENT = 1000000;
35static const int64 MAX_MONEY = 21000000 * COIN;
36inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
37static const int COINBASE_MATURITY = 100;
38// Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp.
39static const int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC
40
41
42
43
44
45
46extern CCriticalSection cs_main;
47extern std::map<uint256, CBlockIndex*> mapBlockIndex;
48extern uint256 hashGenesisBlock;
49extern CBlockIndex* pindexGenesisBlock;
50extern int nBestHeight;
51extern CBigNum bnBestChainWork;
52extern CBigNum bnBestInvalidWork;
53extern uint256 hashBestChain;
54extern CBlockIndex* pindexBest;
55extern unsigned int nTransactionsUpdated;
56extern double dHashesPerSec;
57extern int64 nHPSTimerStart;
58extern int64 nTimeBestReceived;
59extern CCriticalSection cs_setpwalletRegistered;
60extern std::set<CWallet*> setpwalletRegistered;
61
62// Settings
63extern int fGenerateBitcoins;
64extern int fLimitProcessors;
65extern int nLimitProcessors;
66extern int fMinimizeToTray;
67extern int fMinimizeOnClose;
68extern int nCheckBlocks;
69
70int64 GetTransactionFee();
71void SetTransactionFee(int64 nFee);
72int64 GetMinRelayTxFee();
73void SetMinRelayTxFee(int64 nFee);
74
75// Fees are now defined in BTC per binary kilobyte without premature rounding.
76int64 ScaleTxFee(int64 nFeePerKB, unsigned int nBytes);
77
78
79
80class CReserveKey;
81class CTxDB;
82class CTxIndex;
83
84bool GetMempoolTx(const uint256 &hash, CTransaction &tx);
85bool MempoolContainsTx(const uint256 &hash);
86void RegisterWallet(CWallet* pwalletIn);
87void UnregisterWallet(CWallet* pwalletIn);
88void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL, bool fUpdate = false);
89bool ProcessBlock(CNode* pfrom, CBlock* pblock);
90bool CheckDiskSpace(uint64 nAdditionalBytes=0);
91FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
92FILE* AppendBlockFile(unsigned int& nFileRet);
93bool LoadBlockIndex(bool fAllowNew=true);
94void PrintBlockTree();
95bool ProcessMessages(CNode* pfrom);
96bool SendMessages(CNode* pto, bool fSendTrickle);
97void GenerateBitcoins(bool fGenerate, CWallet* pwallet);
98CBlock* CreateNewBlock(CReserveKey& reservekey);
99void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
100void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
101bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
102bool CheckProofOfWork(uint256 hash, unsigned int nBits);
103unsigned int ComputeMinWork(unsigned int nBase, int64 nTime);
104int GetNumBlocksOfPeers();
105bool IsInitialBlockDownload();
106std::string GetWarnings(std::string strFor);
107
108
109
110
111
112
113
114
115
116
117
118
119bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
120
121template<typename T>
122bool WriteSetting(const std::string& strKey, const T& value)
123{
124 bool fOk = false;
125 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
126 {
127 std::string strWalletFile;
128 if (!GetWalletFile(pwallet, strWalletFile))
129 continue;
130 fOk |= CWalletDB(strWalletFile).WriteSetting(strKey, value);
131 }
132 return fOk;
133}
134
135
136class CDiskTxPos
137{
138public:
139 unsigned int nFile;
140 unsigned int nBlockPos;
141 unsigned int nTxPos;
142
143 CDiskTxPos()
144 {
145 SetNull();
146 }
147
148 CDiskTxPos(unsigned int nFileIn, unsigned int nBlockPosIn, unsigned int nTxPosIn)
149 {
150 nFile = nFileIn;
151 nBlockPos = nBlockPosIn;
152 nTxPos = nTxPosIn;
153 }
154
155 IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
156 void SetNull() { nFile = -1; nBlockPos = 0; nTxPos = 0; }
157 bool IsNull() const { return (nFile == -1); }
158
159 friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b)
160 {
161 return (a.nFile == b.nFile &&
162 a.nBlockPos == b.nBlockPos &&
163 a.nTxPos == b.nTxPos);
164 }
165
166 friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b)
167 {
168 return !(a == b);
169 }
170
171 std::string ToString() const
172 {
173 if (IsNull())
174 return strprintf("null");
175 else
176 return strprintf("(nFile=%d, nBlockPos=%d, nTxPos=%d)", nFile, nBlockPos, nTxPos);
177 }
178
179 void print() const
180 {
181 printf("%s", ToString().c_str());
182 }
183};
184
185
186
187
188class CInPoint
189{
190public:
191 CTransaction* ptx;
192 unsigned int n;
193
194 CInPoint() { SetNull(); }
195 CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; }
196 void SetNull() { ptx = NULL; n = -1; }
197 bool IsNull() const { return (ptx == NULL && n == -1); }
198};
199
200
201
202
203class COutPoint
204{
205public:
206 uint256 hash;
207 unsigned int n;
208
209 COutPoint() { SetNull(); }
210 COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; }
211 IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
212 void SetNull() { hash = 0; n = -1; }
213 bool IsNull() const { return (hash == 0 && n == -1); }
214
215 friend bool operator<(const COutPoint& a, const COutPoint& b)
216 {
217 return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n));
218 }
219
220 friend bool operator==(const COutPoint& a, const COutPoint& b)
221 {
222 return (a.hash == b.hash && a.n == b.n);
223 }
224
225 friend bool operator!=(const COutPoint& a, const COutPoint& b)
226 {
227 return !(a == b);
228 }
229
230 std::string ToString() const
231 {
232 return strprintf("COutPoint(%s, %d)", hash.ToString().c_str(), n);
233 }
234
235 void print() const
236 {
237 printf("%s\n", ToString().c_str());
238 }
239};
240
241
242
243
244//
245// An input of a transaction. It contains the location of the previous
246// transaction's output that it claims and a signature that matches the
247// output's public key.
248//
249class CTxIn
250{
251public:
252 COutPoint prevout;
253 CScript scriptSig;
254 unsigned int nSequence;
255
256 CTxIn()
257 {
258 nSequence = UINT_MAX;
259 }
260
261 explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
262 {
263 prevout = prevoutIn;
264 scriptSig = scriptSigIn;
265 nSequence = nSequenceIn;
266 }
267
268 CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX)
269 {
270 prevout = COutPoint(hashPrevTx, nOut);
271 scriptSig = scriptSigIn;
272 nSequence = nSequenceIn;
273 }
274
275 IMPLEMENT_SERIALIZE
276 (
277 READWRITE(prevout);
278 READWRITE(scriptSig);
279 READWRITE(nSequence);
280 )
281
282 bool IsFinal() const
283 {
284 return (nSequence == UINT_MAX);
285 }
286
287 friend bool operator==(const CTxIn& a, const CTxIn& b)
288 {
289 return (a.prevout == b.prevout &&
290 a.scriptSig == b.scriptSig &&
291 a.nSequence == b.nSequence);
292 }
293
294 friend bool operator!=(const CTxIn& a, const CTxIn& b)
295 {
296 return !(a == b);
297 }
298
299 std::string ToString() const
300 {
301 std::string str;
302 str += strprintf("CTxIn(");
303 str += prevout.ToString();
304 if (prevout.IsNull())
305 str += strprintf(", coinbase %s", HexStr(scriptSig).c_str());
306 else
307 str += strprintf(", scriptSig=%s", scriptSig.ToString().c_str());
308 if (nSequence != UINT_MAX)
309 str += strprintf(", nSequence=%u", nSequence);
310 str += ")";
311 return str;
312 }
313
314 void print() const
315 {
316 printf("%s\n", ToString().c_str());
317 }
318};
319
320
321
322
323//
324// An output of a transaction. It contains the public key that the next input
325// must be able to sign with to claim it.
326//
327class CTxOut
328{
329public:
330 int64 nValue;
331 CScript scriptPubKey;
332
333 CTxOut()
334 {
335 SetNull();
336 }
337
338 CTxOut(int64 nValueIn, CScript scriptPubKeyIn)
339 {
340 nValue = nValueIn;
341 scriptPubKey = scriptPubKeyIn;
342 }
343
344 IMPLEMENT_SERIALIZE
345 (
346 READWRITE(nValue);
347 READWRITE(scriptPubKey);
348 )
349
350 void SetNull()
351 {
352 nValue = -1;
353 scriptPubKey.clear();
354 }
355
356 bool IsNull()
357 {
358 return (nValue == -1);
359 }
360
361 uint256 GetHash() const
362 {
363 return SerializeHash(*this);
364 }
365
366 friend bool operator==(const CTxOut& a, const CTxOut& b)
367 {
368 return (a.nValue == b.nValue &&
369 a.scriptPubKey == b.scriptPubKey);
370 }
371
372 friend bool operator!=(const CTxOut& a, const CTxOut& b)
373 {
374 return !(a == b);
375 }
376
377 std::string ToString() const
378 {
379 if (scriptPubKey.size() < 6)
380 return "CTxOut(error)";
381 return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().c_str());
382 }
383
384 void print() const
385 {
386 printf("%s\n", ToString().c_str());
387 }
388};
389
390
391
392
393//
394// The basic transaction that is broadcasted on the network and contained in
395// blocks. A transaction can contain multiple inputs and outputs.
396//
397class CTransaction
398{
399public:
400 int nVersion;
401 std::vector<CTxIn> vin;
402 std::vector<CTxOut> vout;
403 unsigned int nLockTime;
404
405 // Denial-of-service detection:
406 mutable int nDoS;
407 bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
408
409 CTransaction()
410 {
411 SetNull();
412 }
413
414 IMPLEMENT_SERIALIZE
415 (
416 READWRITE(this->nVersion);
417 nVersion = this->nVersion;
418 READWRITE(vin);
419 READWRITE(vout);
420 READWRITE(nLockTime);
421 )
422
423 void SetNull()
424 {
425 nVersion = 1;
426 vin.clear();
427 vout.clear();
428 nLockTime = 0;
429 nDoS = 0; // Denial-of-service prevention
430 }
431
432 bool IsNull() const
433 {
434 return (vin.empty() && vout.empty());
435 }
436
437 uint256 GetHash() const
438 {
439 return SerializeHash(*this);
440 }
441
442 bool IsFinal(int nBlockHeight=0, int64 nBlockTime=0) const
443 {
444 // Time based nLockTime implemented in 0.1.6
445 if (nLockTime == 0)
446 return true;
447 if (nBlockHeight == 0)
448 nBlockHeight = nBestHeight;
449 if (nBlockTime == 0)
450 nBlockTime = GetAdjustedTime();
451 if ((int64)nLockTime < (nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime))
452 return true;
453 BOOST_FOREACH(const CTxIn& txin, vin)
454 if (!txin.IsFinal())
455 return false;
456 return true;
457 }
458
459 bool IsNewerThan(const CTransaction& old) const
460 {
461 if (vin.size() != old.vin.size())
462 return false;
463 for (int i = 0; i < vin.size(); i++)
464 if (vin[i].prevout != old.vin[i].prevout)
465 return false;
466
467 bool fNewer = false;
468 unsigned int nLowest = UINT_MAX;
469 for (int i = 0; i < vin.size(); i++)
470 {
471 if (vin[i].nSequence != old.vin[i].nSequence)
472 {
473 if (vin[i].nSequence <= nLowest)
474 {
475 fNewer = false;
476 nLowest = vin[i].nSequence;
477 }
478 if (old.vin[i].nSequence < nLowest)
479 {
480 fNewer = true;
481 nLowest = old.vin[i].nSequence;
482 }
483 }
484 }
485 return fNewer;
486 }
487
488 bool IsCoinBase() const
489 {
490 return (vin.size() == 1 && vin[0].prevout.IsNull());
491 }
492
493 int GetSigOpCount() const
494 {
495 int n = 0;
496 BOOST_FOREACH(const CTxIn& txin, vin)
497 n += txin.scriptSig.GetSigOpCount();
498 BOOST_FOREACH(const CTxOut& txout, vout)
499 n += txout.scriptPubKey.GetSigOpCount();
500 return n;
501 }
502
503 bool IsStandard() const
504 {
505 BOOST_FOREACH(const CTxIn& txin, vin)
506 if (!txin.scriptSig.IsPushOnly())
507 return error("nonstandard txin: %s", txin.scriptSig.ToString().c_str());
508 BOOST_FOREACH(const CTxOut& txout, vout)
509 if (!::IsStandard(txout.scriptPubKey))
510 return error("nonstandard txout: %s", txout.scriptPubKey.ToString().c_str());
511 return true;
512 }
513
514 int64 GetValueOut() const
515 {
516 int64 nValueOut = 0;
517 BOOST_FOREACH(const CTxOut& txout, vout)
518 {
519 nValueOut += txout.nValue;
520 if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut))
521 throw std::runtime_error("CTransaction::GetValueOut() : value out of range");
522 }
523 return nValueOut;
524 }
525
526 int64 GetMinFee() const
527 {
528 unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);
529 return ScaleTxFee(GetMinRelayTxFee(), nBytes);
530 }
531
532
533 bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
534 {
535 CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb");
536 if (!filein)
537 return error("CTransaction::ReadFromDisk() : OpenBlockFile failed");
538
539 // Read transaction
540 if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
541 return error("CTransaction::ReadFromDisk() : fseek failed");
542 filein >> *this;
543
544 // Return file pointer
545 if (pfileRet)
546 {
547 if (fseek(filein, pos.nTxPos, SEEK_SET) != 0)
548 return error("CTransaction::ReadFromDisk() : second fseek failed");
549 *pfileRet = filein.release();
550 }
551 return true;
552 }
553
554 friend bool operator==(const CTransaction& a, const CTransaction& b)
555 {
556 return (a.nVersion == b.nVersion &&
557 a.vin == b.vin &&
558 a.vout == b.vout &&
559 a.nLockTime == b.nLockTime);
560 }
561
562 friend bool operator!=(const CTransaction& a, const CTransaction& b)
563 {
564 return !(a == b);
565 }
566
567
568 std::string ToString() const
569 {
570 std::string str;
571 str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",
572 GetHash().ToString().c_str(),
573 nVersion,
574 vin.size(),
575 vout.size(),
576 nLockTime);
577 for (int i = 0; i < vin.size(); i++)
578 str += " " + vin[i].ToString() + "\n";
579 for (int i = 0; i < vout.size(); i++)
580 str += " " + vout[i].ToString() + "\n";
581 return str;
582 }
583
584 void print() const
585 {
586 printf("%s", ToString().c_str());
587 }
588
589
590 bool ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet);
591 bool ReadFromDisk(CTxDB& txdb, COutPoint prevout);
592 bool ReadFromDisk(COutPoint prevout);
593 bool DisconnectInputs(CTxDB& txdb);
594 bool ConnectInputs(CTxDB& txdb, std::map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
595 CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee,
596 bool& fInvalid);
597 bool ClientConnectInputs();
598 bool CheckTransaction() const;
599 bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
600 bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL);
601protected:
602 bool AddToMemoryPoolUnchecked();
603public:
604 bool RemoveFromMemoryPool();
605};
606
607
608
609
610
611//
612// A transaction with a merkle branch linking it to the block chain
613//
614class CMerkleTx : public CTransaction
615{
616public:
617 uint256 hashBlock;
618 std::vector<uint256> vMerkleBranch;
619 int nIndex;
620
621 // memory only
622 mutable char fMerkleVerified;
623
624
625 CMerkleTx()
626 {
627 Init();
628 }
629
630 CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
631 {
632 Init();
633 }
634
635 void Init()
636 {
637 hashBlock = 0;
638 nIndex = -1;
639 fMerkleVerified = false;
640 }
641
642
643 IMPLEMENT_SERIALIZE
644 (
645 nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action);
646 nVersion = this->nVersion;
647 READWRITE(hashBlock);
648 READWRITE(vMerkleBranch);
649 READWRITE(nIndex);
650 )
651
652
653 int SetMerkleBranch(const CBlock* pblock=NULL);
654 int GetDepthInMainChain(int& nHeightRet) const;
655 int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); }
656 bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
657 int GetBlocksToMaturity() const;
658 bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true);
659 bool AcceptToMemoryPool();
660};
661
662
663
664
665//
666// A txdb record that contains the disk location of a transaction and the
667// locations of transactions that spend its outputs. vSpent is really only
668// used as a flag, but having the location is very helpful for debugging.
669//
670class CTxIndex
671{
672public:
673 CDiskTxPos pos;
674 std::vector<CDiskTxPos> vSpent;
675
676 CTxIndex()
677 {
678 SetNull();
679 }
680
681 CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs)
682 {
683 pos = posIn;
684 vSpent.resize(nOutputs);
685 }
686
687 IMPLEMENT_SERIALIZE
688 (
689 if (!(nType & SER_GETHASH))
690 READWRITE(nVersion);
691 READWRITE(pos);
692 READWRITE(vSpent);
693 )
694
695 void SetNull()
696 {
697 pos.SetNull();
698 vSpent.clear();
699 }
700
701 bool IsNull()
702 {
703 return pos.IsNull();
704 }
705
706 friend bool operator==(const CTxIndex& a, const CTxIndex& b)
707 {
708 return (a.pos == b.pos &&
709 a.vSpent == b.vSpent);
710 }
711
712 friend bool operator!=(const CTxIndex& a, const CTxIndex& b)
713 {
714 return !(a == b);
715 }
716 int GetDepthInMainChain() const;
717};
718
719
720
721
722
723//
724// Nodes collect new transactions into a block, hash them into a hash tree,
725// and scan through nonce values to make the block's hash satisfy proof-of-work
726// requirements. When they solve the proof-of-work, they broadcast the block
727// to everyone and the block is added to the block chain. The first transaction
728// in the block is a special one that creates a new coin owned by the creator
729// of the block.
730//
731// Blocks are appended to blk0001.dat files on disk. Their location on disk
732// is indexed by CBlockIndex objects in memory.
733//
734class CBlock
735{
736public:
737 // header
738 int nVersion;
739 uint256 hashPrevBlock;
740 uint256 hashMerkleRoot;
741 unsigned int nTime;
742 unsigned int nBits;
743 unsigned int nNonce;
744
745 // network and disk
746 std::vector<CTransaction> vtx;
747
748 // memory only
749 mutable std::vector<uint256> vMerkleTree;
750
751 // Denial-of-service detection:
752 mutable int nDoS;
753 bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
754
755 CBlock()
756 {
757 SetNull();
758 }
759
760 IMPLEMENT_SERIALIZE
761 (
762 READWRITE(this->nVersion);
763 nVersion = this->nVersion;
764 READWRITE(hashPrevBlock);
765 READWRITE(hashMerkleRoot);
766 READWRITE(nTime);
767 READWRITE(nBits);
768 READWRITE(nNonce);
769
770 // ConnectBlock depends on vtx being last so it can calculate offset
771 if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY)))
772 READWRITE(vtx);
773 else if (fRead)
774 const_cast<CBlock*>(this)->vtx.clear();
775 )
776
777 void SetNull()
778 {
779 nVersion = 1;
780 hashPrevBlock = 0;
781 hashMerkleRoot = 0;
782 nTime = 0;
783 nBits = 0;
784 nNonce = 0;
785 vtx.clear();
786 vMerkleTree.clear();
787 nDoS = 0;
788 }
789
790 bool IsNull() const
791 {
792 return (nBits == 0);
793 }
794
795 uint256 GetHash() const
796 {
797 return Hash(BEGIN(nVersion), END(nNonce));
798 }
799
800 int64 GetBlockTime() const
801 {
802 return (int64)nTime;
803 }
804
805 int GetSigOpCount() const
806 {
807 int n = 0;
808 BOOST_FOREACH(const CTransaction& tx, vtx)
809 n += tx.GetSigOpCount();
810 return n;
811 }
812
813
814 uint256 BuildMerkleTree() const
815 {
816 vMerkleTree.clear();
817 BOOST_FOREACH(const CTransaction& tx, vtx)
818 vMerkleTree.push_back(tx.GetHash());
819 int j = 0;
820 for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
821 {
822 for (int i = 0; i < nSize; i += 2)
823 {
824 int i2 = std::min(i+1, nSize-1);
825 vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]),
826 BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
827 }
828 j += nSize;
829 }
830 return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
831 }
832
833 std::vector<uint256> GetMerkleBranch(int nIndex) const
834 {
835 if (vMerkleTree.empty())
836 BuildMerkleTree();
837 std::vector<uint256> vMerkleBranch;
838 int j = 0;
839 for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
840 {
841 int i = std::min(nIndex^1, nSize-1);
842 vMerkleBranch.push_back(vMerkleTree[j+i]);
843 nIndex >>= 1;
844 j += nSize;
845 }
846 return vMerkleBranch;
847 }
848
849 static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
850 {
851 if (nIndex == -1)
852 return 0;
853 BOOST_FOREACH(const uint256& otherside, vMerkleBranch)
854 {
855 if (nIndex & 1)
856 hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
857 else
858 hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));
859 nIndex >>= 1;
860 }
861 return hash;
862 }
863
864
865 bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet)
866 {
867 // Open history file to append
868 CAutoFile fileout = AppendBlockFile(nFileRet);
869 if (!fileout)
870 return error("CBlock::WriteToDisk() : AppendBlockFile failed");
871
872 // Write index header
873 unsigned int nSize = fileout.GetSerializeSize(*this);
874 fileout << FLATDATA(pchMessageStart) << nSize;
875
876 // Write block
877 nBlockPosRet = ftell(fileout);
878 if (nBlockPosRet == -1)
879 return error("CBlock::WriteToDisk() : ftell failed");
880 fileout << *this;
881
882 // Flush stdio buffers and commit to disk before returning
883 fflush(fileout);
884 fsync(fileno(fileout));
885
886 return true;
887 }
888
889 bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true)
890 {
891 SetNull();
892
893 // Open history file to read
894 CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");
895 if (!filein)
896 return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
897 if (!fReadTransactions)
898 filein.nType |= SER_BLOCKHEADERONLY;
899
900 // Read block
901 filein >> *this;
902
903 // Check the header
904 if (!CheckProofOfWork(GetHash(), nBits))
905 return error("CBlock::ReadFromDisk() : errors in block header");
906
907 return true;
908 }
909
910
911
912 void print() const
913 {
914 printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",
915 GetHash().ToString().c_str(),
916 nVersion,
917 hashPrevBlock.ToString().c_str(),
918 hashMerkleRoot.ToString().c_str(),
919 nTime, nBits, nNonce,
920 vtx.size());
921 for (int i = 0; i < vtx.size(); i++)
922 {
923 printf(" ");
924 vtx[i].print();
925 }
926 printf(" vMerkleTree: ");
927 for (int i = 0; i < vMerkleTree.size(); i++)
928 printf("%s ", vMerkleTree[i].ToString().c_str());
929 printf("\n");
930 }
931
932
933 bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex);
934 bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex);
935 bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true);
936 bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew);
937 bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
938 bool CheckBlock() const;
939 bool AcceptBlock();
940};
941
942
943
944
945
946
947//
948// The block chain is a tree shaped structure starting with the
949// genesis block at the root, with each block potentially having multiple
950// candidates to be the next block. pprev and pnext link a path through the
951// main/longest chain. A blockindex may have multiple pprev pointing back
952// to it, but pnext will only point forward to the longest branch, or will
953// be null if the block is not part of the longest chain.
954//
955class CBlockIndex
956{
957public:
958 const uint256* phashBlock;
959 CBlockIndex* pprev;
960 CBlockIndex* pnext;
961 unsigned int nFile;
962 unsigned int nBlockPos;
963 int nHeight;
964 CBigNum bnChainWork;
965
966 // block header
967 int nVersion;
968 uint256 hashMerkleRoot;
969 unsigned int nTime;
970 unsigned int nBits;
971 unsigned int nNonce;
972
973
974 CBlockIndex()
975 {
976 phashBlock = NULL;
977 pprev = NULL;
978 pnext = NULL;
979 nFile = 0;
980 nBlockPos = 0;
981 nHeight = 0;
982 bnChainWork = 0;
983
984 nVersion = 0;
985 hashMerkleRoot = 0;
986 nTime = 0;
987 nBits = 0;
988 nNonce = 0;
989 }
990
991 CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block)
992 {
993 phashBlock = NULL;
994 pprev = NULL;
995 pnext = NULL;
996 nFile = nFileIn;
997 nBlockPos = nBlockPosIn;
998 nHeight = 0;
999 bnChainWork = 0;
1000
1001 nVersion = block.nVersion;
1002 hashMerkleRoot = block.hashMerkleRoot;
1003 nTime = block.nTime;
1004 nBits = block.nBits;
1005 nNonce = block.nNonce;
1006 }
1007
1008 CBlock GetBlockHeader() const
1009 {
1010 CBlock block;
1011 block.nVersion = nVersion;
1012 if (pprev)
1013 block.hashPrevBlock = pprev->GetBlockHash();
1014 block.hashMerkleRoot = hashMerkleRoot;
1015 block.nTime = nTime;
1016 block.nBits = nBits;
1017 block.nNonce = nNonce;
1018 return block;
1019 }
1020
1021 uint256 GetBlockHash() const
1022 {
1023 return *phashBlock;
1024 }
1025
1026 int64 GetBlockTime() const
1027 {
1028 return (int64)nTime;
1029 }
1030
1031 CBigNum GetBlockWork() const
1032 {
1033 CBigNum bnTarget;
1034 bnTarget.SetCompact(nBits);
1035 if (bnTarget <= 0)
1036 return 0;
1037 return (CBigNum(1)<<256) / (bnTarget+1);
1038 }
1039
1040 bool IsInMainChain() const
1041 {
1042 return (pnext || this == pindexBest);
1043 }
1044
1045 bool CheckIndex() const
1046 {
1047 return CheckProofOfWork(GetBlockHash(), nBits);
1048 }
1049
1050 bool EraseBlockFromDisk()
1051 {
1052 // Open history file
1053 CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+");
1054 if (!fileout)
1055 return false;
1056
1057 // Overwrite with empty null block
1058 CBlock block;
1059 block.SetNull();
1060 fileout << block;
1061
1062 return true;
1063 }
1064
1065 enum { nMedianTimeSpan=11 };
1066
1067 int64 GetMedianTimePast() const
1068 {
1069 int64 pmedian[nMedianTimeSpan];
1070 int64* pbegin = &pmedian[nMedianTimeSpan];
1071 int64* pend = &pmedian[nMedianTimeSpan];
1072
1073 const CBlockIndex* pindex = this;
1074 for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
1075 *(--pbegin) = pindex->GetBlockTime();
1076
1077 std::sort(pbegin, pend);
1078 return pbegin[(pend - pbegin)/2];
1079 }
1080
1081 int64 GetMedianTime() const
1082 {
1083 const CBlockIndex* pindex = this;
1084 for (int i = 0; i < nMedianTimeSpan/2; i++)
1085 {
1086 if (!pindex->pnext)
1087 return GetBlockTime();
1088 pindex = pindex->pnext;
1089 }
1090 return pindex->GetMedianTimePast();
1091 }
1092
1093
1094
1095 std::string ToString() const
1096 {
1097 return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
1098 pprev, pnext, nFile, nBlockPos, nHeight,
1099 hashMerkleRoot.ToString().c_str(),
1100 GetBlockHash().ToString().c_str());
1101 }
1102
1103 void print() const
1104 {
1105 printf("%s\n", ToString().c_str());
1106 }
1107};
1108
1109
1110
1111//
1112// Used to marshal pointers into hashes for db storage.
1113//
1114class CDiskBlockIndex : public CBlockIndex
1115{
1116public:
1117 uint256 hashPrev;
1118 uint256 hashNext;
1119
1120 CDiskBlockIndex()
1121 {
1122 hashPrev = 0;
1123 hashNext = 0;
1124 }
1125
1126 explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex)
1127 {
1128 hashPrev = (pprev ? pprev->GetBlockHash() : 0);
1129 hashNext = (pnext ? pnext->GetBlockHash() : 0);
1130 }
1131
1132 IMPLEMENT_SERIALIZE
1133 (
1134 if (!(nType & SER_GETHASH))
1135 READWRITE(nVersion);
1136
1137 READWRITE(hashNext);
1138 READWRITE(nFile);
1139 READWRITE(nBlockPos);
1140 READWRITE(nHeight);
1141
1142 // block header
1143 READWRITE(this->nVersion);
1144 READWRITE(hashPrev);
1145 READWRITE(hashMerkleRoot);
1146 READWRITE(nTime);
1147 READWRITE(nBits);
1148 READWRITE(nNonce);
1149 )
1150
1151 uint256 GetBlockHash() const
1152 {
1153 CBlock block;
1154 block.nVersion = nVersion;
1155 block.hashPrevBlock = hashPrev;
1156 block.hashMerkleRoot = hashMerkleRoot;
1157 block.nTime = nTime;
1158 block.nBits = nBits;
1159 block.nNonce = nNonce;
1160 return block.GetHash();
1161 }
1162
1163
1164 std::string ToString() const
1165 {
1166 std::string str = "CDiskBlockIndex(";
1167 str += CBlockIndex::ToString();
1168 str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)",
1169 GetBlockHash().ToString().c_str(),
1170 hashPrev.ToString().c_str(),
1171 hashNext.ToString().c_str());
1172 return str;
1173 }
1174
1175 void print() const
1176 {
1177 printf("%s\n", ToString().c_str());
1178 }
1179};
1180
1181
1182
1183
1184
1185
1186
1187
1188//
1189// Describes a place in the block chain to another node such that if the
1190// other node doesn't have the same branch, it can find a recent common trunk.
1191// The further back it is, the further before the fork it may be.
1192//
1193class CBlockLocator
1194{
1195protected:
1196 std::vector<uint256> vHave;
1197public:
1198
1199 CBlockLocator()
1200 {
1201 }
1202
1203 explicit CBlockLocator(const CBlockIndex* pindex)
1204 {
1205 Set(pindex);
1206 }
1207
1208 explicit CBlockLocator(uint256 hashBlock)
1209 {
1210 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
1211 if (mi != mapBlockIndex.end())
1212 Set((*mi).second);
1213 }
1214
1215 IMPLEMENT_SERIALIZE
1216 (
1217 if (!(nType & SER_GETHASH))
1218 READWRITE(nVersion);
1219 READWRITE(vHave);
1220 )
1221
1222 void SetNull()
1223 {
1224 vHave.clear();
1225 }
1226
1227 bool IsNull()
1228 {
1229 return vHave.empty();
1230 }
1231
1232 void Set(const CBlockIndex* pindex)
1233 {
1234 vHave.clear();
1235 int nStep = 1;
1236 while (pindex)
1237 {
1238 vHave.push_back(pindex->GetBlockHash());
1239
1240 // Exponentially larger steps back
1241 for (int i = 0; pindex && i < nStep; i++)
1242 pindex = pindex->pprev;
1243 if (vHave.size() > 10)
1244 nStep *= 2;
1245 }
1246 vHave.push_back(hashGenesisBlock);
1247 }
1248
1249 int GetDistanceBack()
1250 {
1251 // Retrace how far back it was in the sender's branch
1252 int nDistance = 0;
1253 int nStep = 1;
1254 BOOST_FOREACH(const uint256& hash, vHave)
1255 {
1256 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1257 if (mi != mapBlockIndex.end())
1258 {
1259 CBlockIndex* pindex = (*mi).second;
1260 if (pindex->IsInMainChain())
1261 return nDistance;
1262 }
1263 nDistance += nStep;
1264 if (nDistance > 10)
1265 nStep *= 2;
1266 }
1267 return nDistance;
1268 }
1269
1270 CBlockIndex* GetBlockIndex()
1271 {
1272 // Find the first block the caller has in the main chain
1273 BOOST_FOREACH(const uint256& hash, vHave)
1274 {
1275 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1276 if (mi != mapBlockIndex.end())
1277 {
1278 CBlockIndex* pindex = (*mi).second;
1279 if (pindex->IsInMainChain())
1280 return pindex;
1281 }
1282 }
1283 return pindexGenesisBlock;
1284 }
1285
1286 uint256 GetBlockHash()
1287 {
1288 // Find the first block the caller has in the main chain
1289 BOOST_FOREACH(const uint256& hash, vHave)
1290 {
1291 std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
1292 if (mi != mapBlockIndex.end())
1293 {
1294 CBlockIndex* pindex = (*mi).second;
1295 if (pindex->IsInMainChain())
1296 return hash;
1297 }
1298 }
1299 return hashGenesisBlock;
1300 }
1301
1302 int GetHeight()
1303 {
1304 CBlockIndex* pindex = GetBlockIndex();
1305 if (!pindex)
1306 return 0;
1307 return pindex->nHeight;
1308 }
1309};
1310
1311#endif