diff --git a/src/main.cpp b/src/main.cpp index 134268f7..c2afda88 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -79,7 +79,38 @@ int miningAlgo = ALGO_SHA256D; namespace { struct CBlockIndexWorkComparator { - bool operator()(CBlockIndex *pa, CBlockIndex *pb) { + bool operator()(CBlockIndex *pa, CBlockIndex *pb) + { + if ( (pa->nHeight >= nBlockAlgoNormalisedWorkStart2) || + (pb->nHeight >= nBlockAlgoNormalisedWorkStart2) ) + { + // First sort by most work per algo, ... + int aWins = 0, bWins = 0; + for (int i = 0; i < NUM_ALGOS; i++) + { + if (pa->nAlgoWork[i] > pb->nAlgoWork[i]) aWins++; + if (pa->nAlgoWork[i] < pb->nAlgoWork[i]) bWins++; + } + if (aWins > bWins) return false; + if (aWins < bWins) return true; + + // ... then by number of blocks ... + if (pa->nHeight > pb->nHeight) return false; + if (pa->nHeight < pb->nHeight) return true; + + // ... then by earliest time received, ... + if (pa->nSequenceId < pb->nSequenceId) return false; + if (pa->nSequenceId > pb->nSequenceId) return true; + + // Use pointer address as tie breaker (should only happen with blocks + // loaded from disk, as those all have id 0). + if (pa < pb) return false; + if (pa > pb) return true; + + // Identical blocks. + return false; + } + // First sort by most total work, ... if (pa->nChainWork > pb->nChainWork) return false; if (pa->nChainWork < pb->nChainWork) return true; @@ -2322,6 +2353,11 @@ bool AddToBlockIndex(CBlock& block, CValidationState& state, const CDiskBlockPos } pindexNew->nTx = block.vtx.size(); pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + pindexNew->GetBlockWorkAdjusted().getuint256(); + for (int i = 0; i < NUM_ALGOS; i++) + { + pindexNew->nAlgoWork[i] = (pindexNew->pprev ? pindexNew->pprev->nAlgoWork[i] : 0) + + (i == pindexNew->GetAlgo() ? pindexNew->GetBlockWork().getuint256() : 0); + } pindexNew->nChainTx = (pindexNew->pprev ? pindexNew->pprev->nChainTx : 0) + pindexNew->nTx; pindexNew->nFile = pos.nFile; pindexNew->nDataPos = pos.nPos; diff --git a/src/main.h b/src/main.h index 524bfb17..57b91c81 100644 --- a/src/main.h +++ b/src/main.h @@ -727,6 +727,8 @@ public: // (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block uint256 nChainWork; + uint256 nAlgoWork[NUM_ALGOS]; + // Number of transactions in this block. // Note: in a potential headers-first mode, this number cannot be relied upon unsigned int nTx; @@ -756,6 +758,8 @@ public: nDataPos = 0; nUndoPos = 0; nChainWork = 0; + for (int i = 0; i < NUM_ALGOS; i++) + nAlgoWork[i] = 0; nTx = 0; nChainTx = 0; nStatus = 0; @@ -777,6 +781,8 @@ public: nDataPos = 0; nUndoPos = 0; nChainWork = 0; + for (int i = 0; i < NUM_ALGOS; i++) + nAlgoWork[i] = 0; nTx = 0; nChainTx = 0; nStatus = 0; @@ -849,7 +855,6 @@ public: CBigNum GetPrevWorkForAlgoWithDecay(int algo) const { int nDistance = 0; - CBigNum nWork; CBlockIndex* pindex = this->pprev; while (pindex) { @@ -860,8 +865,10 @@ public: if (pindex->GetAlgo() == algo) { CBigNum nWork = pindex->GetBlockWork(); - nWork = nWork * (32 - nDistance); - nWork = nWork / 32; + nWork *= (32 - nDistance); + nWork /= 32; + if (nWork < Params().ProofOfWorkLimit(algo)) + nWork = Params().ProofOfWorkLimit(algo); return nWork; } pindex = pindex->pprev;