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.
This commit is contained in:
parent
2aa462ec30
commit
1657c4bc49
@ -1,5 +1,5 @@
|
|||||||
diff --git a/src/main.cpp b/src/main.cpp
|
diff --git a/contrib/test-patches/bitcoind-comparison.patch b/contrib/test-patches/bitcoind-comparison.patch
|
||||||
index 8c115c2..1e70ff2 100644
|
index 04a8618..519429a 100644
|
||||||
--- a/src/main.cpp
|
--- a/src/main.cpp
|
||||||
+++ b/src/main.cpp
|
+++ b/src/main.cpp
|
||||||
@@ -31,8 +31,8 @@ CTxMemPool mempool;
|
@@ -31,8 +31,8 @@ CTxMemPool mempool;
|
||||||
@ -12,7 +12,7 @@ index 8c115c2..1e70ff2 100644
|
|||||||
+static CBigNum bnProofOfWorkLimit(~uint256(0) >> 1);
|
+static CBigNum bnProofOfWorkLimit(~uint256(0) >> 1);
|
||||||
CBlockIndex* pindexGenesisBlock = NULL;
|
CBlockIndex* pindexGenesisBlock = NULL;
|
||||||
int nBestHeight = -1;
|
int nBestHeight = -1;
|
||||||
CBigNum bnBestChainWork = 0;
|
uint256 nBestChainWork = 0;
|
||||||
@@ -1055,7 +1055,7 @@ int64 static GetBlockValue(int nHeight, int64 nFees)
|
@@ -1055,7 +1055,7 @@ int64 static GetBlockValue(int nHeight, int64 nFees)
|
||||||
int64 nSubsidy = 50 * COIN;
|
int64 nSubsidy = 50 * COIN;
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ index 8c115c2..1e70ff2 100644
|
|||||||
|
|
||||||
return nSubsidy + nFees;
|
return nSubsidy + nFees;
|
||||||
}
|
}
|
||||||
@@ -2706,9 +2706,9 @@ bool InitBlockIndex() {
|
@@ -2736,9 +2736,9 @@ bool InitBlockIndex() {
|
||||||
block.hashPrevBlock = 0;
|
block.hashPrevBlock = 0;
|
||||||
block.hashMerkleRoot = block.BuildMerkleTree();
|
block.hashMerkleRoot = block.BuildMerkleTree();
|
||||||
block.nVersion = 1;
|
block.nVersion = 1;
|
||||||
@ -35,7 +35,7 @@ index 8c115c2..1e70ff2 100644
|
|||||||
|
|
||||||
if (fTestNet)
|
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 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
|
// The characters are rarely used upper ASCII, not valid as UTF-8, and produce
|
||||||
// a large 4-byte int at any alignment.
|
// a large 4-byte int at any alignment.
|
||||||
|
@ -222,7 +222,7 @@ public:
|
|||||||
BN_mpi2bn(pch, p - pch, this);
|
BN_mpi2bn(pch, p - pch, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 getuint256()
|
uint256 getuint256() const
|
||||||
{
|
{
|
||||||
unsigned int nSize = BN_bn2mpi(this, NULL);
|
unsigned int nSize = BN_bn2mpi(this, NULL);
|
||||||
if (nSize < 4)
|
if (nSize < 4)
|
||||||
|
48
src/main.cpp
48
src/main.cpp
@ -35,8 +35,8 @@ uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3
|
|||||||
static CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
|
static CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
|
||||||
CBlockIndex* pindexGenesisBlock = NULL;
|
CBlockIndex* pindexGenesisBlock = NULL;
|
||||||
int nBestHeight = -1;
|
int nBestHeight = -1;
|
||||||
CBigNum bnBestChainWork = 0;
|
uint256 nBestChainWork = 0;
|
||||||
CBigNum bnBestInvalidWork = 0;
|
uint256 nBestInvalidWork = 0;
|
||||||
uint256 hashBestChain = 0;
|
uint256 hashBestChain = 0;
|
||||||
CBlockIndex* pindexBest = NULL;
|
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
|
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)
|
void static InvalidChainFound(CBlockIndex* pindexNew)
|
||||||
{
|
{
|
||||||
if (pindexNew->bnChainWork > bnBestInvalidWork)
|
if (pindexNew->nChainWork > nBestInvalidWork)
|
||||||
{
|
{
|
||||||
bnBestInvalidWork = pindexNew->bnChainWork;
|
nBestInvalidWork = pindexNew->nChainWork;
|
||||||
pblocktree->WriteBestInvalidWork(bnBestInvalidWork);
|
pblocktree->WriteBestInvalidWork(CBigNum(nBestInvalidWork));
|
||||||
uiInterface.NotifyBlocksChanged();
|
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->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());
|
pindexNew->GetBlockTime()).c_str());
|
||||||
printf("InvalidChainFound: current best=%s height=%d work=%s date=%s\n",
|
printf("InvalidChainFound: current best=%s height=%d log2_work=%.8g date=%s\n",
|
||||||
hashBestChain.ToString().c_str(), nBestHeight, bnBestChainWork.ToString().c_str(),
|
hashBestChain.ToString().c_str(), nBestHeight, log(nBestChainWork.getdouble())/log(2.0),
|
||||||
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexBest->GetBlockTime()).c_str());
|
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");
|
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;
|
pindexNewBest = *it;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pindexNewBest == pindexBest || (pindexBest && pindexNewBest->bnChainWork == pindexBest->bnChainWork))
|
if (pindexNewBest == pindexBest || (pindexBest && pindexNewBest->nChainWork == pindexBest->nChainWork))
|
||||||
return true; // nothing to do
|
return true; // nothing to do
|
||||||
|
|
||||||
// check ancestry
|
// check ancestry
|
||||||
@ -1250,7 +1250,7 @@ bool ConnectBestBlock(CValidationState &state) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pindexBest == NULL || pindexTest->bnChainWork > pindexBest->bnChainWork)
|
if (pindexBest == NULL || pindexTest->nChainWork > pindexBest->nChainWork)
|
||||||
vAttach.push_back(pindexTest);
|
vAttach.push_back(pindexTest);
|
||||||
|
|
||||||
if (pindexTest->pprev == NULL || pindexTest->pnext != NULL) {
|
if (pindexTest->pprev == NULL || pindexTest->pnext != NULL) {
|
||||||
@ -1858,11 +1858,11 @@ bool SetBestChain(CValidationState &state, CBlockIndex* pindexNew)
|
|||||||
pindexBest = pindexNew;
|
pindexBest = pindexNew;
|
||||||
pblockindexFBBHLast = NULL;
|
pblockindexFBBHLast = NULL;
|
||||||
nBestHeight = pindexBest->nHeight;
|
nBestHeight = pindexBest->nHeight;
|
||||||
bnBestChainWork = pindexNew->bnChainWork;
|
nBestChainWork = pindexNew->nChainWork;
|
||||||
nTimeBestReceived = GetTime();
|
nTimeBestReceived = GetTime();
|
||||||
nTransactionsUpdated++;
|
nTransactionsUpdated++;
|
||||||
printf("SetBestChain: new best=%s height=%d work=%s tx=%lu date=%s progress=%f\n",
|
printf("SetBestChain: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f\n",
|
||||||
hashBestChain.ToString().c_str(), nBestHeight, bnBestChainWork.ToString().c_str(), (unsigned long)pindexNew->nChainTx,
|
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(),
|
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexBest->GetBlockTime()).c_str(),
|
||||||
Checkpoints::GuessVerificationProgress(pindexBest));
|
Checkpoints::GuessVerificationProgress(pindexBest));
|
||||||
|
|
||||||
@ -1915,7 +1915,7 @@ bool CBlock::AddToBlockIndex(CValidationState &state, const CDiskBlockPos &pos)
|
|||||||
pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
|
pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
|
||||||
}
|
}
|
||||||
pindexNew->nTx = vtx.size();
|
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->nChainTx = (pindexNew->pprev ? pindexNew->pprev->nChainTx : 0) + pindexNew->nTx;
|
||||||
pindexNew->nFile = pos.nFile;
|
pindexNew->nFile = pos.nFile;
|
||||||
pindexNew->nDataPos = pos.nPos;
|
pindexNew->nDataPos = pos.nPos;
|
||||||
@ -2537,7 +2537,7 @@ bool static LoadBlockIndexDB()
|
|||||||
|
|
||||||
boost::this_thread::interruption_point();
|
boost::this_thread::interruption_point();
|
||||||
|
|
||||||
// Calculate bnChainWork
|
// Calculate nChainWork
|
||||||
vector<pair<int, CBlockIndex*> > vSortedByHeight;
|
vector<pair<int, CBlockIndex*> > vSortedByHeight;
|
||||||
vSortedByHeight.reserve(mapBlockIndex.size());
|
vSortedByHeight.reserve(mapBlockIndex.size());
|
||||||
BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
|
BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
|
||||||
@ -2549,7 +2549,7 @@ bool static LoadBlockIndexDB()
|
|||||||
BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight)
|
BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight)
|
||||||
{
|
{
|
||||||
CBlockIndex* pindex = item.second;
|
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;
|
pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
|
||||||
if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS && !(pindex->nStatus & BLOCK_FAILED_MASK))
|
if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS && !(pindex->nStatus & BLOCK_FAILED_MASK))
|
||||||
setBlockIndexValid.insert(pindex);
|
setBlockIndexValid.insert(pindex);
|
||||||
@ -2561,8 +2561,10 @@ bool static LoadBlockIndexDB()
|
|||||||
if (pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile))
|
if (pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile))
|
||||||
printf("LoadBlockIndexDB(): last block file info: %s\n", infoLastBlockFile.ToString().c_str());
|
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);
|
pblocktree->ReadBestInvalidWork(bnBestInvalidWork);
|
||||||
|
nBestInvalidWork = bnBestInvalidWork.getuint256();
|
||||||
|
|
||||||
// Check whether we need to continue reindexing
|
// Check whether we need to continue reindexing
|
||||||
bool fReindexing = false;
|
bool fReindexing = false;
|
||||||
@ -2579,7 +2581,7 @@ bool static LoadBlockIndexDB()
|
|||||||
return true;
|
return true;
|
||||||
hashBestChain = pindexBest->GetBlockHash();
|
hashBestChain = pindexBest->GetBlockHash();
|
||||||
nBestHeight = pindexBest->nHeight;
|
nBestHeight = pindexBest->nHeight;
|
||||||
bnBestChainWork = pindexBest->bnChainWork;
|
nBestChainWork = pindexBest->nChainWork;
|
||||||
|
|
||||||
// set 'next' pointers in best chain
|
// set 'next' pointers in best chain
|
||||||
CBlockIndex *pindex = pindexBest;
|
CBlockIndex *pindex = pindexBest;
|
||||||
@ -2675,8 +2677,8 @@ void UnloadBlockIndex()
|
|||||||
setBlockIndexValid.clear();
|
setBlockIndexValid.clear();
|
||||||
pindexGenesisBlock = NULL;
|
pindexGenesisBlock = NULL;
|
||||||
nBestHeight = 0;
|
nBestHeight = 0;
|
||||||
bnBestChainWork = 0;
|
nBestChainWork = 0;
|
||||||
bnBestInvalidWork = 0;
|
nBestInvalidWork = 0;
|
||||||
hashBestChain = 0;
|
hashBestChain = 0;
|
||||||
pindexBest = NULL;
|
pindexBest = NULL;
|
||||||
}
|
}
|
||||||
@ -2953,7 +2955,7 @@ string GetWarnings(string strFor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Longer invalid proof-of-work chain
|
// Longer invalid proof-of-work chain
|
||||||
if (pindexBest && bnBestInvalidWork > bnBestChainWork + pindexBest->GetBlockWork() * 6)
|
if (pindexBest && nBestInvalidWork > nBestChainWork + (pindexBest->GetBlockWork() * 6).getuint256())
|
||||||
{
|
{
|
||||||
nPriority = 2000;
|
nPriority = 2000;
|
||||||
strStatusBar = strRPC = _("Warning: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.");
|
strStatusBar = strRPC = _("Warning: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.");
|
||||||
|
14
src/main.h
14
src/main.h
@ -77,8 +77,8 @@ extern std::set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexValid;
|
|||||||
extern uint256 hashGenesisBlock;
|
extern uint256 hashGenesisBlock;
|
||||||
extern CBlockIndex* pindexGenesisBlock;
|
extern CBlockIndex* pindexGenesisBlock;
|
||||||
extern int nBestHeight;
|
extern int nBestHeight;
|
||||||
extern CBigNum bnBestChainWork;
|
extern uint256 nBestChainWork;
|
||||||
extern CBigNum bnBestInvalidWork;
|
extern uint256 nBestInvalidWork;
|
||||||
extern uint256 hashBestChain;
|
extern uint256 hashBestChain;
|
||||||
extern CBlockIndex* pindexBest;
|
extern CBlockIndex* pindexBest;
|
||||||
extern unsigned int nTransactionsUpdated;
|
extern unsigned int nTransactionsUpdated;
|
||||||
@ -1619,7 +1619,7 @@ public:
|
|||||||
unsigned int nUndoPos;
|
unsigned int nUndoPos;
|
||||||
|
|
||||||
// (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block
|
// (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.
|
// Number of transactions in this block.
|
||||||
// Note: in a potential headers-first mode, this number cannot be relied upon
|
// Note: in a potential headers-first mode, this number cannot be relied upon
|
||||||
@ -1648,7 +1648,7 @@ public:
|
|||||||
nFile = 0;
|
nFile = 0;
|
||||||
nDataPos = 0;
|
nDataPos = 0;
|
||||||
nUndoPos = 0;
|
nUndoPos = 0;
|
||||||
bnChainWork = 0;
|
nChainWork = 0;
|
||||||
nTx = 0;
|
nTx = 0;
|
||||||
nChainTx = 0;
|
nChainTx = 0;
|
||||||
nStatus = 0;
|
nStatus = 0;
|
||||||
@ -1669,7 +1669,7 @@ public:
|
|||||||
nFile = 0;
|
nFile = 0;
|
||||||
nDataPos = 0;
|
nDataPos = 0;
|
||||||
nUndoPos = 0;
|
nUndoPos = 0;
|
||||||
bnChainWork = 0;
|
nChainWork = 0;
|
||||||
nTx = 0;
|
nTx = 0;
|
||||||
nChainTx = 0;
|
nChainTx = 0;
|
||||||
nStatus = 0;
|
nStatus = 0;
|
||||||
@ -1793,8 +1793,8 @@ public:
|
|||||||
struct CBlockIndexWorkComparator
|
struct CBlockIndexWorkComparator
|
||||||
{
|
{
|
||||||
bool operator()(CBlockIndex *pa, CBlockIndex *pb) {
|
bool operator()(CBlockIndex *pa, CBlockIndex *pb) {
|
||||||
if (pa->bnChainWork > pb->bnChainWork) return false;
|
if (pa->nChainWork > pb->nChainWork) return false;
|
||||||
if (pa->bnChainWork < pb->bnChainWork) return true;
|
if (pa->nChainWork < pb->nChainWork) return true;
|
||||||
|
|
||||||
if (pa->GetBlockHash() < pb->GetBlockHash()) return false;
|
if (pa->GetBlockHash() < pb->GetBlockHash()) return false;
|
||||||
if (pa->GetBlockHash() > pb->GetBlockHash()) return true;
|
if (pa->GetBlockHash() > pb->GetBlockHash()) return true;
|
||||||
|
@ -55,6 +55,16 @@ public:
|
|||||||
return ret;
|
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)
|
base_uint& operator=(uint64 b)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user