diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2013-03-28 23:51:50 +0100 |
---|---|---|
committer | Pieter Wuille <pieterw@google.com> | 2013-04-12 12:17:28 +0200 |
commit | 1657c4bc495815febc2137972c3c63b99d2b0189 (patch) | |
tree | 57798b51f7014c88f11b1e5bfe11edc123977098 | |
parent | 2aa462ec30c3960ae546e4d8d50fdbaffefef718 (diff) |
Use a uint256 for bnChainWork
Every block index entry currently requires a separately-allocated
CBigNum. By replacing them with uint256, it's just 32 bytes extra
in CBlockIndex itself.
This should save us a few megabytes in RAM, and less allocation
overhead.
-rw-r--r-- | contrib/test-patches/bitcoind-comparison.patch | 10 | ||||
-rw-r--r-- | src/bignum.h | 2 | ||||
-rw-r--r-- | src/main.cpp | 48 | ||||
-rw-r--r-- | src/main.h | 14 | ||||
-rw-r--r-- | src/uint256.h | 10 |
5 files changed, 48 insertions, 36 deletions
diff --git a/contrib/test-patches/bitcoind-comparison.patch b/contrib/test-patches/bitcoind-comparison.patch index 04a8618286..7464349b3c 100644 --- a/contrib/test-patches/bitcoind-comparison.patch +++ b/contrib/test-patches/bitcoind-comparison.patch @@ -1,5 +1,5 @@ -diff --git a/src/main.cpp b/src/main.cpp -index 8c115c2..1e70ff2 100644 +diff --git a/contrib/test-patches/bitcoind-comparison.patch b/contrib/test-patches/bitcoind-comparison.patch +index 04a8618..519429a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -31,8 +31,8 @@ CTxMemPool mempool; @@ -12,7 +12,7 @@ index 8c115c2..1e70ff2 100644 +static CBigNum bnProofOfWorkLimit(~uint256(0) >> 1); CBlockIndex* pindexGenesisBlock = NULL; int nBestHeight = -1; - CBigNum bnBestChainWork = 0; + uint256 nBestChainWork = 0; @@ -1055,7 +1055,7 @@ int64 static GetBlockValue(int nHeight, int64 nFees) int64 nSubsidy = 50 * COIN; @@ -22,7 +22,7 @@ index 8c115c2..1e70ff2 100644 return nSubsidy + nFees; } -@@ -2706,9 +2706,9 @@ bool InitBlockIndex() { +@@ -2736,9 +2736,9 @@ bool InitBlockIndex() { block.hashPrevBlock = 0; block.hashMerkleRoot = block.BuildMerkleTree(); block.nVersion = 1; @@ -35,7 +35,7 @@ index 8c115c2..1e70ff2 100644 if (fTestNet) { -@@ -3007,7 +3007,7 @@ bool static AlreadyHave(const CInv& inv) +@@ -3024,7 +3024,7 @@ bool static AlreadyHave(const CInv& inv) // The message start string is designed to be unlikely to occur in normal data. // The characters are rarely used upper ASCII, not valid as UTF-8, and produce // a large 4-byte int at any alignment. diff --git a/src/bignum.h b/src/bignum.h index 1ee7a99934..0881807d70 100644 --- a/src/bignum.h +++ b/src/bignum.h @@ -222,7 +222,7 @@ public: BN_mpi2bn(pch, p - pch, this); } - uint256 getuint256() + uint256 getuint256() const { unsigned int nSize = BN_bn2mpi(this, NULL); if (nSize < 4) diff --git a/src/main.cpp b/src/main.cpp index 8284d54c7c..bf13e79151 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -35,8 +35,8 @@ uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3 static CBigNum bnProofOfWorkLimit(~uint256(0) >> 32); CBlockIndex* pindexGenesisBlock = NULL; int nBestHeight = -1; -CBigNum bnBestChainWork = 0; -CBigNum bnBestInvalidWork = 0; +uint256 nBestChainWork = 0; +uint256 nBestInvalidWork = 0; uint256 hashBestChain = 0; CBlockIndex* pindexBest = NULL; set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexValid; // may contain all CBlockIndex*'s that have validness >=BLOCK_VALID_TRANSACTIONS, and must contain those who aren't failed @@ -1191,20 +1191,20 @@ bool IsInitialBlockDownload() void static InvalidChainFound(CBlockIndex* pindexNew) { - if (pindexNew->bnChainWork > bnBestInvalidWork) + if (pindexNew->nChainWork > nBestInvalidWork) { - bnBestInvalidWork = pindexNew->bnChainWork; - pblocktree->WriteBestInvalidWork(bnBestInvalidWork); + nBestInvalidWork = pindexNew->nChainWork; + pblocktree->WriteBestInvalidWork(CBigNum(nBestInvalidWork)); uiInterface.NotifyBlocksChanged(); } - printf("InvalidChainFound: invalid block=%s height=%d work=%s date=%s\n", + printf("InvalidChainFound: invalid block=%s height=%d log2_work=%.8g date=%s\n", pindexNew->GetBlockHash().ToString().c_str(), pindexNew->nHeight, - pindexNew->bnChainWork.ToString().c_str(), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", + log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexNew->GetBlockTime()).c_str()); - printf("InvalidChainFound: current best=%s height=%d work=%s date=%s\n", - hashBestChain.ToString().c_str(), nBestHeight, bnBestChainWork.ToString().c_str(), + printf("InvalidChainFound: current best=%s height=%d log2_work=%.8g date=%s\n", + hashBestChain.ToString().c_str(), nBestHeight, log(nBestChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexBest->GetBlockTime()).c_str()); - if (pindexBest && bnBestInvalidWork > bnBestChainWork + pindexBest->GetBlockWork() * 6) + if (pindexBest && nBestInvalidWork > nBestChainWork + (pindexBest->GetBlockWork() * 6).getuint256()) printf("InvalidChainFound: Warning: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.\n"); } @@ -1230,7 +1230,7 @@ bool ConnectBestBlock(CValidationState &state) { pindexNewBest = *it; } - if (pindexNewBest == pindexBest || (pindexBest && pindexNewBest->bnChainWork == pindexBest->bnChainWork)) + if (pindexNewBest == pindexBest || (pindexBest && pindexNewBest->nChainWork == pindexBest->nChainWork)) return true; // nothing to do // check ancestry @@ -1250,7 +1250,7 @@ bool ConnectBestBlock(CValidationState &state) { break; } - if (pindexBest == NULL || pindexTest->bnChainWork > pindexBest->bnChainWork) + if (pindexBest == NULL || pindexTest->nChainWork > pindexBest->nChainWork) vAttach.push_back(pindexTest); if (pindexTest->pprev == NULL || pindexTest->pnext != NULL) { @@ -1858,11 +1858,11 @@ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew) pindexBest = pindexNew; pblockindexFBBHLast = NULL; nBestHeight = pindexBest->nHeight; - bnBestChainWork = pindexNew->bnChainWork; + nBestChainWork = pindexNew->nChainWork; nTimeBestReceived = GetTime(); nTransactionsUpdated++; - printf("SetBestChain: new best=%s height=%d work=%s tx=%lu date=%s progress=%f\n", - hashBestChain.ToString().c_str(), nBestHeight, bnBestChainWork.ToString().c_str(), (unsigned long)pindexNew->nChainTx, + printf("SetBestChain: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f\n", + hashBestChain.ToString().c_str(), nBestHeight, log(nBestChainWork.getdouble())/log(2.0), (unsigned long)pindexNew->nChainTx, DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexBest->GetBlockTime()).c_str(), Checkpoints::GuessVerificationProgress(pindexBest)); @@ -1915,7 +1915,7 @@ bool CBlock::AddToBlockIndex(CValidationState &state, const CDiskBlockPos &pos) pindexNew->nHeight = pindexNew->pprev->nHeight + 1; } pindexNew->nTx = vtx.size(); - pindexNew->bnChainWork = (pindexNew->pprev ? pindexNew->pprev->bnChainWork : 0) + pindexNew->GetBlockWork(); + pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + pindexNew->GetBlockWork().getuint256(); pindexNew->nChainTx = (pindexNew->pprev ? pindexNew->pprev->nChainTx : 0) + pindexNew->nTx; pindexNew->nFile = pos.nFile; pindexNew->nDataPos = pos.nPos; @@ -2537,7 +2537,7 @@ bool static LoadBlockIndexDB() boost::this_thread::interruption_point(); - // Calculate bnChainWork + // Calculate nChainWork vector<pair<int, CBlockIndex*> > vSortedByHeight; vSortedByHeight.reserve(mapBlockIndex.size()); BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex) @@ -2549,7 +2549,7 @@ bool static LoadBlockIndexDB() BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight) { CBlockIndex* pindex = item.second; - pindex->bnChainWork = (pindex->pprev ? pindex->pprev->bnChainWork : 0) + pindex->GetBlockWork(); + pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + pindex->GetBlockWork().getuint256(); pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx; if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS && !(pindex->nStatus & BLOCK_FAILED_MASK)) setBlockIndexValid.insert(pindex); @@ -2561,8 +2561,10 @@ bool static LoadBlockIndexDB() if (pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile)) printf("LoadBlockIndexDB(): last block file info: %s\n", infoLastBlockFile.ToString().c_str()); - // Load bnBestInvalidWork, OK if it doesn't exist + // Load nBestInvalidWork, OK if it doesn't exist + CBigNum bnBestInvalidWork; pblocktree->ReadBestInvalidWork(bnBestInvalidWork); + nBestInvalidWork = bnBestInvalidWork.getuint256(); // Check whether we need to continue reindexing bool fReindexing = false; @@ -2579,7 +2581,7 @@ bool static LoadBlockIndexDB() return true; hashBestChain = pindexBest->GetBlockHash(); nBestHeight = pindexBest->nHeight; - bnBestChainWork = pindexBest->bnChainWork; + nBestChainWork = pindexBest->nChainWork; // set 'next' pointers in best chain CBlockIndex *pindex = pindexBest; @@ -2675,8 +2677,8 @@ void UnloadBlockIndex() setBlockIndexValid.clear(); pindexGenesisBlock = NULL; nBestHeight = 0; - bnBestChainWork = 0; - bnBestInvalidWork = 0; + nBestChainWork = 0; + nBestInvalidWork = 0; hashBestChain = 0; pindexBest = NULL; } @@ -2953,7 +2955,7 @@ string GetWarnings(string strFor) } // Longer invalid proof-of-work chain - if (pindexBest && bnBestInvalidWork > bnBestChainWork + pindexBest->GetBlockWork() * 6) + if (pindexBest && nBestInvalidWork > nBestChainWork + (pindexBest->GetBlockWork() * 6).getuint256()) { nPriority = 2000; strStatusBar = strRPC = _("Warning: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade."); diff --git a/src/main.h b/src/main.h index 9a3664a437..24b2cb2aa6 100644 --- a/src/main.h +++ b/src/main.h @@ -77,8 +77,8 @@ extern std::set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexValid; extern uint256 hashGenesisBlock; extern CBlockIndex* pindexGenesisBlock; extern int nBestHeight; -extern CBigNum bnBestChainWork; -extern CBigNum bnBestInvalidWork; +extern uint256 nBestChainWork; +extern uint256 nBestInvalidWork; extern uint256 hashBestChain; extern CBlockIndex* pindexBest; extern unsigned int nTransactionsUpdated; @@ -1619,7 +1619,7 @@ public: unsigned int nUndoPos; // (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block - CBigNum bnChainWork; + uint256 nChainWork; // Number of transactions in this block. // Note: in a potential headers-first mode, this number cannot be relied upon @@ -1648,7 +1648,7 @@ public: nFile = 0; nDataPos = 0; nUndoPos = 0; - bnChainWork = 0; + nChainWork = 0; nTx = 0; nChainTx = 0; nStatus = 0; @@ -1669,7 +1669,7 @@ public: nFile = 0; nDataPos = 0; nUndoPos = 0; - bnChainWork = 0; + nChainWork = 0; nTx = 0; nChainTx = 0; nStatus = 0; @@ -1793,8 +1793,8 @@ public: struct CBlockIndexWorkComparator { bool operator()(CBlockIndex *pa, CBlockIndex *pb) { - if (pa->bnChainWork > pb->bnChainWork) return false; - if (pa->bnChainWork < pb->bnChainWork) return true; + if (pa->nChainWork > pb->nChainWork) return false; + if (pa->nChainWork < pb->nChainWork) return true; if (pa->GetBlockHash() < pb->GetBlockHash()) return false; if (pa->GetBlockHash() > pb->GetBlockHash()) return true; diff --git a/src/uint256.h b/src/uint256.h index eb0066fa27..8a9af8ba04 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -55,6 +55,16 @@ public: return ret; } + double getdouble() const + { + double ret = 0.0; + double fact = 1.0; + for (int i = 0; i < WIDTH; i++) { + ret += fact * pn[i]; + fact *= 4294967296.0; + } + return ret; + } base_uint& operator=(uint64 b) { |