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()); }
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params, std::string sGRCAddress, const CBlockIndex* pindexPrev) { bool fNegative; bool fOverflow; arith_uint256 bnTarget; bnTarget.SetCompact(nBits, &fNegative, &fOverflow); // Check range if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit)) return error("CheckProofOfWork(): nBits below minimum work"); // Check that proof of age exceeds the bar if (UintToArith256(hash) > bnTarget) { uint256 uTarget = ArithToUint256(bnTarget); uint256 uNewTarget = ArithToUint256(bnTarget); return error("CheckProofOfWork(): High Hash - BlockIndex %s, Original Hash %s, Adjusted Hash %s, Hash %s", pindexPrev->GetBlockHash().GetHex().c_str(), uTarget.GetHex().c_str(), uNewTarget.GetHex().c_str(), hash.GetHex().c_str()); } return true; }
/** * Tamper with a uint256 (modify it). * @param num The number to modify. */ static void tamperWith (uint256& num) { arith_uint256 modifiable = UintToArith256 (num); modifiable += 1; num = ArithToUint256 (modifiable); }
// // Deterministically calculate a given "score" for a Masternode depending on how close it's hash is to // the proof of work for that block. The further away they are the better, the furthest will win the election // and get paid this block // arith_uint256 CMasternode::CalculateScore(const uint256& blockHash) { uint256 aux = ArithToUint256(UintToArith256(vin.prevout.hash) + vin.prevout.n); CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); ss << blockHash; arith_uint256 hash2 = UintToArith256(ss.GetHash()); CHashWriter ss2(SER_GETHASH, PROTOCOL_VERSION); ss2 << blockHash; ss2 << aux; arith_uint256 hash3 = UintToArith256(ss2.GetHash()); return (hash3 > hash2 ? hash3 - hash2 : hash2 - hash3); }
valtype CAuxpowBuilder::buildAuxpowChain (const uint256& hashAux, unsigned h, int index) { auxpowChainIndex = index; /* Just use "something" for the branch. Doesn't really matter. */ auxpowChainMerkleBranch.clear (); for (unsigned i = 0; i < h; ++i) auxpowChainMerkleBranch.push_back (ArithToUint256 (arith_uint256 (i))); const uint256 hash = CBlock::CheckMerkleBranch (hashAux, auxpowChainMerkleBranch, index); valtype res = ToByteVector (hash); std::reverse (res.begin (), res.end ()); return res; }
uint256 GetAdjustHash(const uint256 TargetHash, const uint64_t nPos, const int nCurHeight) { uint64_t posacc = nPos/COIN; posacc /= SysCfg().GetIntervalPos(); posacc = max(posacc, (uint64_t) 1); arith_uint256 adjusthash = UintToArith256(TargetHash); //adjust nbits arith_uint256 minhash = SysCfg().ProofOfWorkLimit(); while (posacc) { adjusthash = adjusthash << 1; posacc = posacc >> 1; if (adjusthash > minhash) { adjusthash = minhash; break; } } return std::move(ArithToUint256(adjusthash)); }
// Check kernel hash target and coinstake signature bool CheckProofOfStake(const CBlock& block, const CBlockIndex* prevBlock, const COutPoint& outpointStakePointer, uint256& hashProofOfStake) { const CTransaction tx = block.vtx[1]; if (!tx.IsCoinStake()) return error("CheckProofOfStake() : called on non-coinstake %s", tx.GetHash().ToString().c_str()); // Get the stake modifier auto pindexModifier = prevBlock->GetAncestor(prevBlock->nHeight - Params().KernelModifierOffset()); if (!pindexModifier) return error("CheckProofOfStake() : could not find modifier index for stake"); uint256 nStakeModifier = pindexModifier->GetBlockHash(); // Get the correct amount for the collateral CAmount nAmountCollateral = 0; if (outpointStakePointer.n == 1) nAmountCollateral = MASTERNODE_COLLATERAL; else if (outpointStakePointer.n == 2) nAmountCollateral = SYSTEMNODE_COLLATERAL; else return error("%s: Stake pointer is neither pos 1 or 2", __func__); // Reconstruct the kernel that created the stake auto pairOut = std::make_pair(outpointStakePointer.hash, outpointStakePointer.n); Kernel kernel(pairOut, nAmountCollateral, nStakeModifier, prevBlock->GetBlockTime(), block.nTime); bool fNegative; bool fOverflow; arith_uint256 bnTarget; bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow); // Check range if (fNegative || bnTarget == 0 || fOverflow) return error("CheckProofOfStake() : nBits below minimum stake"); LogPrintf("%s : %s\n", __func__, kernel.ToString()); hashProofOfStake = kernel.GetStakeHash(); return kernel.IsValidProof(ArithToUint256(bnTarget)); }
unsigned int GetNextWorkRequiredV1(const CBlockIndex* pindexLast, const Consensus::Params& params, int algo) { int nHeight = pindexLast->nHeight + 1; bool fNewDifficultyProtocol = (nHeight >= params.nDiffChangeTarget); int blockstogoback = 0; //set default to pre-v2.0 values int64_t retargetTimespan = params.nTargetTimespan; //int64_t retargetSpacing = nTargetSpacing; int64_t retargetInterval = params.nInterval; //if v2.0 changes are in effect for block num, alter retarget values if(fNewDifficultyProtocol && !params.fPowAllowMinDifficultyBlocks) { LogPrintf("GetNextWorkRequired nActualTimespan Limiting\n"); retargetTimespan = params.nTargetTimespanRe; //retargetSpacing = nTargetSpacingRe; retargetInterval = params.nIntervalRe; } // Only change once per interval if ((pindexLast->nHeight+1) % retargetInterval != 0) { return pindexLast->nBits; } // DigiByte: This fixes an issue where a 51% attack can change difficulty at will. // Go back the full period unless it's the first retarget after genesis. Code courtesy of Art Forz blockstogoback = retargetInterval-1; if ((pindexLast->nHeight+1) != retargetInterval) blockstogoback = retargetInterval; // Go back by what we want to be 14 days worth of blocks const CBlockIndex* pindexFirst = pindexLast; for (int i = 0; pindexFirst && i < blockstogoback; i++) pindexFirst = pindexFirst->pprev; assert(pindexFirst); // Limit adjustment step int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime(); // thanks to RealSolid & WDC for this code if(fNewDifficultyProtocol && !params.fPowAllowMinDifficultyBlocks) { if (nActualTimespan < (retargetTimespan - (retargetTimespan/4)) ) nActualTimespan = (retargetTimespan - (retargetTimespan/4)); if (nActualTimespan > (retargetTimespan + (retargetTimespan/2)) ) nActualTimespan = (retargetTimespan + (retargetTimespan/2)); } else { if (nActualTimespan < retargetTimespan/4) nActualTimespan = retargetTimespan/4; if (nActualTimespan > retargetTimespan*4) nActualTimespan = retargetTimespan*4; } arith_uint256 bnNew; arith_uint256 bnBefore; bnNew.SetCompact(pindexLast->nBits); bnBefore=bnNew; bnNew *= nActualTimespan; bnNew /= retargetTimespan; if (bnNew > UintToArith256(params.powLimit)) bnNew = UintToArith256(params.powLimit); // debug print LogPrintf("nTargetTimespan = %d nActualTimespan = %d\n", retargetTimespan, nActualTimespan); LogPrintf("Before: %08x %s\n", pindexLast->nBits, ArithToUint256(bnBefore).ToString()); LogPrintf("After: %08x %s\n", bnNew.GetCompact(), ArithToUint256(bnNew).ToString()); return bnNew.GetCompact(); }