88#include < chainparams.h>
99#include < validation.h>
1010
11+ // Include whatever header actually declares LogPrintf in your codebase.
12+ // In DigiByte, it might be "logging.h" or "util/system.h". Adjust as needed:
13+ #include < logging.h> // or #include <util/system.h> or #include "util.h"
14+
15+ /* *
16+ * CBlockIndex default constructor
17+ */
18+ CBlockIndex::CBlockIndex ()
19+ {
20+ for (unsigned i = 0 ; i < NUM_ALGOS_IMPL; i++) {
21+ lastAlgoBlocks[i] = nullptr ;
22+ }
23+ }
24+
1125/* *
12- * CChain implementation
26+ * CBlockIndex constructor that copies from a block header.
27+ * We can safely call LogPrintf here because we are in a .cpp file that includes logging.
1328 */
29+ CBlockIndex::CBlockIndex (const CBlockHeader& block)
30+ : nVersion(block.nVersion),
31+ hashMerkleRoot(block.hashMerkleRoot),
32+ nTime(block.nTime),
33+ nBits(block.nBits),
34+ nNonce(block.nNonce)
35+ {
36+ // Initialize lastAlgoBlocks to null.
37+ for (unsigned i = 0 ; i < NUM_ALGOS_IMPL; i++) {
38+ lastAlgoBlocks[i] = nullptr ;
39+ }
40+
41+ // Determine raw algo index from version bits:
42+ int rawAlgo = block.GetAlgo (); // This returns ALGO_UNKNOWN if it doesn't match recognized bits
43+ if (rawAlgo >= 0 && rawAlgo < NUM_ALGOS_IMPL) {
44+ lastAlgoBlocks[rawAlgo] = this ;
45+ } else {
46+ // We can log this occurrence:
47+ LogPrintf (" CBlockIndex ctor: ALGO_UNKNOWN in block version=0x%08x\n " , block.nVersion );
48+ }
49+ }
50+
1451void CChain::SetTip (CBlockIndex *pindex) {
1552 if (pindex == nullptr ) {
1653 vChain.clear ();
@@ -65,23 +102,55 @@ const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const {
65102CBlockIndex* CChain::FindEarliestAtLeast (int64_t nTime, int height) const
66103{
67104 std::pair<int64_t , int > blockparams = std::make_pair (nTime, height);
68- std::vector<CBlockIndex*>::const_iterator lower = std::lower_bound (vChain.begin (), vChain.end (), blockparams,
69- [](CBlockIndex* pBlock, const std::pair<int64_t , int >& blockparams) -> bool { return pBlock->GetBlockTimeMax () < blockparams.first || pBlock->nHeight < blockparams.second ; });
105+ auto lower = std::lower_bound (
106+ vChain.begin (), vChain.end (), blockparams,
107+ [](CBlockIndex* pBlock, const std::pair<int64_t , int >& bp) {
108+ return pBlock->GetBlockTimeMax () < bp.first || pBlock->nHeight < bp.second ;
109+ }
110+ );
70111 return (lower == vChain.end () ? nullptr : *lower);
71112}
72113
73- /* * Turn the lowest '1' bit in the binary representation of a number into a '0'. */
114+ /* *
115+ * Return recognized mining algo for this block, forcibly mapping blocks
116+ * below height 145,000 to ALGO_SCRYPT. If none recognized, logs a warning.
117+ */
118+ int CBlockIndex::GetAlgo () const
119+ {
120+ // If we’re on mainnet, for historical reasons we force blocks below 145k to scrypt:
121+ if (!Params ().NetworkIDString ().compare (" main" )) {
122+ if (nHeight < 145000 ) {
123+ return ALGO_SCRYPT;
124+ }
125+ }
126+
127+ // Otherwise, parse from version bits (same as before):
128+ switch (nVersion & BLOCK_VERSION_ALGO) {
129+ case BLOCK_VERSION_SCRYPT: return ALGO_SCRYPT;
130+ case BLOCK_VERSION_SHA256D: return ALGO_SHA256D;
131+ case BLOCK_VERSION_GROESTL: return ALGO_GROESTL;
132+ case BLOCK_VERSION_SKEIN: return ALGO_SKEIN;
133+ case BLOCK_VERSION_QUBIT: return ALGO_QUBIT;
134+ case BLOCK_VERSION_ODO: return ALGO_ODO;
135+ }
136+
137+ // If still not recognized:
138+ LogPrintf (" Warning: block at height=%d has unrecognized nVersion=0x%08x\n " , nHeight, nVersion);
139+ return ALGO_UNKNOWN;
140+ }
141+
142+
143+ /* * Turn the lowest '1' bit in the binary representation of a number into '0'. */
74144int static inline InvertLowestOne (int n) { return n & (n - 1 ); }
75145
76146/* * Compute what height to jump back to with the CBlockIndex::pskip pointer. */
77147int static inline GetSkipHeight (int height) {
78148 if (height < 2 )
79149 return 0 ;
80150
81- // Determine which height to jump back to. Any number strictly lower than height is acceptable,
82- // but the following expression seems to perform well in simulations (max 110 steps to go back
83- // up to 2**18 blocks).
84- return (height & 1 ) ? InvertLowestOne (InvertLowestOne (height - 1 )) + 1 : InvertLowestOne (height);
151+ return (height & 1 )
152+ ? InvertLowestOne (InvertLowestOne (height - 1 )) + 1
153+ : InvertLowestOne (height);
85154}
86155
87156const CBlockIndex* CBlockIndex::GetAncestor (int height) const
@@ -124,18 +193,16 @@ void CBlockIndex::BuildSkip()
124193
125194int GetAlgoWorkFactor (int nHeight, int algo)
126195{
127- if (nHeight < Params ().GetConsensus ().multiAlgoDiffChangeTarget )
128- {
196+ if (nHeight < Params ().GetConsensus ().multiAlgoDiffChangeTarget ) {
129197 return 1 ;
130198 }
131199
132200 switch (algo)
133201 {
134202 case ALGO_SHA256D:
135- return 1 ;
136- // work factor = absolute work ratio * optimisation factor
203+ return 1 ;
137204 case ALGO_SCRYPT:
138- return 1024 * 4 ;
205+ return 1024 * 4 ; // etc...
139206 case ALGO_GROESTL:
140207 return 64 * 8 ;
141208 case ALGO_SKEIN:
@@ -155,33 +222,26 @@ arith_uint256 GetBlockProofBase(const CBlockIndex& block)
155222 bnTarget.SetCompact (block.nBits , &fNegative , &fOverflow );
156223 if (fNegative || fOverflow || bnTarget == 0 )
157224 return 0 ;
158- // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
159- // as it's too large for a arith_uint256. However, as 2**256 is at least as large
160- // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
161- // or ~bnTarget / (nTarget+1) + 1.
225+
226+ // 2**256 / (bnTarget+1)
162227 return (~bnTarget / (bnTarget + 1 )) + 1 ;
163228}
164229
165- // DGB 6.14.1 GetBlock Proof
166230arith_uint256 GetBlockProof (const CBlockIndex& block)
167231{
168232 CBlockHeader header = block.GetBlockHeader ();
169233 int nHeight = block.nHeight ;
170234 const Consensus::Params& params = Params ().GetConsensus ();
171235
172- if (nHeight < params.workComputationChangeTarget )
173- {
236+ if (nHeight < params.workComputationChangeTarget ) {
174237 arith_uint256 bnBlockWork = GetBlockProofBase (block);
175238 uint32_t nAlgoWork = GetAlgoWorkFactor (nHeight, header.GetAlgo ());
176239 return bnBlockWork * nAlgoWork;
177- }
178- else
179- {
180- // Compute the geometric mean of the block targets for each individual algorithm.
240+ } else {
241+ // Compute the geometric mean across all active algos
181242 arith_uint256 bnAvgTarget (1 );
182243
183- for (int i = 0 ; i < NUM_ALGOS_IMPL; i++)
184- {
244+ for (int i = 0 ; i < NUM_ALGOS_IMPL; i++) {
185245 if (!IsAlgoActive (block.pprev , params, i))
186246 continue ;
187247 unsigned int nBits = GetNextWorkRequired (block.pprev , &header, params, i);
@@ -196,11 +256,9 @@ arith_uint256 GetBlockProof(const CBlockIndex& block)
196256 // that all intermediate values fit in 256-bit integers.
197257 bnAvgTarget *= bnTarget.ApproxNthRoot (NUM_ALGOS);
198258 }
199- // see comment in GetProofBase
200259 arith_uint256 bnRes = (~bnAvgTarget / (bnAvgTarget + 1 )) + 1 ;
201- // Scale to roughly match the old work calculation
260+ // scale
202261 bnRes <<= 7 ;
203-
204262 return bnRes;
205263 }
206264}
@@ -211,14 +269,11 @@ arith_uint256 GetBlockProof(const CBlockIndex& block, int algo)
211269 int nHeight = block.nHeight ;
212270 const Consensus::Params& params = Params ().GetConsensus ();
213271
214- if (nHeight < params.workComputationChangeTarget )
215- {
272+ if (nHeight < params.workComputationChangeTarget ) {
216273 arith_uint256 bnBlockWork = GetBlockProofBase (block);
217274 uint32_t nAlgoWork = GetAlgoWorkFactor (nHeight, header.GetAlgo ());
218275 return bnBlockWork * nAlgoWork;
219- }
220- else
221- {
276+ } else {
222277 if (!IsAlgoActive (block.pprev , params, algo))
223278 return 0 ;
224279 unsigned int nBits = GetNextWorkRequired (block.pprev , &header, params, algo);
@@ -228,12 +283,12 @@ arith_uint256 GetBlockProof(const CBlockIndex& block, int algo)
228283 bnTarget.SetCompact (nBits, &fNegative , &fOverflow );
229284 if (fNegative || fOverflow || bnTarget == 0 )
230285 return 0 ;
231-
232286 return (~bnTarget / (bnTarget + 1 )) + 1 ;
233287 }
234288}
235289
236- int64_t GetBlockProofEquivalentTime (const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params)
290+ int64_t GetBlockProofEquivalentTime (const CBlockIndex& to, const CBlockIndex& from,
291+ const CBlockIndex& tip, const Consensus::Params& params)
237292{
238293 arith_uint256 r;
239294 int sign = 1 ;
@@ -250,9 +305,8 @@ int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& fr
250305 return sign * r.GetLow64 ();
251306}
252307
253- /* * Find the last common ancestor two blocks have.
254- * Both pa and pb must be non-nullptr. */
255- const CBlockIndex* LastCommonAncestor (const CBlockIndex* pa, const CBlockIndex* pb) {
308+ const CBlockIndex* LastCommonAncestor (const CBlockIndex* pa, const CBlockIndex* pb)
309+ {
256310 if (pa->nHeight > pb->nHeight ) {
257311 pa = pa->GetAncestor (pb->nHeight );
258312 } else if (pb->nHeight > pa->nHeight ) {
0 commit comments