arith_uint256 GetGeometricMeanPrevWork(const CBlockIndex& block) { //arith_uint256 bnRes; arith_uint256 nBlockWork = GetBlockProofBase(block); CBigNum bnBlockWork = CBigNum(ArithToUint256(nBlockWork)); int nAlgo = block.GetAlgo(); for (int algo = 0; algo < NUM_ALGOS; algo++) { if (algo != nAlgo) { arith_uint256 nBlockWorkAlt = GetPrevWorkForAlgoWithDecayV3(block, algo); CBigNum bnBlockWorkAlt = CBigNum(ArithToUint256(nBlockWorkAlt)); if (bnBlockWorkAlt != 0) bnBlockWork *= bnBlockWorkAlt; } } // Compute the geometric mean CBigNum bnRes = bnBlockWork.nthRoot(NUM_ALGOS); // Scale to roughly match the old work calculation bnRes <<= 8; //return bnRes; return UintToArith256(bnRes.getuint256()); }
arith_uint256 GetBlockProof(const CBlockIndex& block) { Consensus::Params params = Params().GetConsensus(); arith_uint256 bnTarget; int nHeight = block.nHeight; int nAlgo = block.GetAlgo(); if (nHeight > params.nGeometricAverageWork_Start) { bnTarget = GetGeometricMeanPrevWork(block); } else { arith_uint256 nBlockWork = GetBlockProofBase(block); for (int algo = 0; algo < NUM_ALGOS; algo++) { if (algo != nAlgo) { if(nHeight >= params.nBlockAlgoNormalisedWorkDecayV2Start) { nBlockWork += GetPrevWorkForAlgoWithDecayV2(block, algo); } else { nBlockWork += GetPrevWorkForAlgoWithDecayV1(block, algo); } } } bnTarget = nBlockWork / NUM_ALGOS; } return bnTarget; }
arith_uint256 GetBlockProof(const CBlockIndex& block) { arith_uint256 bnTarget; bool fNegative; bool fOverflow; bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow); if (fNegative || fOverflow || bnTarget == 0) return 0; // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256 // as it's too large for an arith_uint256. However, as 2**256 is at least as large // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1, // or ~bnTarget / (bnTarget+1) + 1. // Use weighting system for equivelant algo chainwork return (~bnTarget / (bnTarget + 1)) * GetAlgoWeight(block.GetAlgo()) + 1; }