From c68ca1a225fe683e3ed87bb0afc25912fcbe5e73 Mon Sep 17 00:00:00 2001 From: miketout Date: Fri, 28 Sep 2018 14:35:38 -0700 Subject: [PATCH] Leverage nonce for overwhelming chance of single deterministic winner for chain power in POS --- src/komodo_bitcoind.h | 22 ++++++++++------------ src/pow.cpp | 17 +++++++++++------ src/wallet/wallet.cpp | 11 +++++------ 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index 87ea945c3..5e7635b3b 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -1489,10 +1489,10 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height) { bool validHash; bool enablePOSNonce = CPOSNonce::NewPOSActive(height); - bool newPOSActive = enablePOSNonce || (Params().GetConsensus().vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight <= height); + bool newPOSEnforcement = enablePOSNonce && (Params().GetConsensus().vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight <= height); uint256 rawHash; arith_uint256 posHash; - if (newPOSActive) + if (newPOSEnforcement) { validHash = pblock->GetRawVerusPOSHash(rawHash, height); posHash = UintToArith256(rawHash) / value; @@ -1502,12 +1502,12 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height) // printf("Raw POShash: %s\n", posHash.GetHex().c_str()); //} } - if (newPOSActive && !(validHash && posHash <= target)) + if (newPOSEnforcement && !(validHash && posHash <= target)) { printf("ERROR: invalid nonce value for PoS block\nnNonce: %s\nrawHash: %s\nposHash: %s\nvalue: %lu\n", pblock->nNonce.GetHex().c_str(), rawHash.GetHex().c_str(), posHash.GetHex().c_str(), value); } - //else + else { if (slowflag == 0) { @@ -1546,14 +1546,7 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height) //printf("after nNonce: %s, height: %d\n", nonce.GetHex().c_str(), height); //printf("POShash: %s\n\n", hash.GetHex().c_str()); - if (newPOSActive && posHash != hash) - { - printf("blk hash: %s\nnonce: %s\ncorrect: %s\n", pblock->GetHash().GetHex().c_str(), pblock->nNonce.GetHex().c_str(), nonce.GetHex().c_str()); - } - - - //if ((!newPOSActive || posHash == hash) && hash <= target) - if (hash <= target) + if ((!newPOSEnforcement || posHash == hash) && hash <= target) { if ((mapBlockIndex.count(blkHash) == 0) || !(pastBlockIndex = mapBlockIndex[blkHash]) || @@ -1612,6 +1605,11 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height) } } } + else + { + printf("ERROR: malformed nonce value for PoS block\nnNonce: %s\nrawHash: %s\nposHash: %s\nvalue: %lu\n", + pblock->nNonce.GetHex().c_str(), rawHash.GetHex().c_str(), posHash.GetHex().c_str(), value); + } } } } diff --git a/src/pow.cpp b/src/pow.cpp index 2c75fef5f..d3dc2f6aa 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -468,13 +468,18 @@ CChainPower GetBlockProof(const CBlockIndex& block) bnStakeTarget.SetCompact(header.GetVerusPOSTarget(), &fNegative, &fOverflow); if (fNegative || fOverflow || bnWorkTarget == 0) return CChainPower(0); - } + // as the nonce has a fixed definition for a POS block, add the random amount of "work" from the nonce, so there will + // statistically always be a deterministic winner in POS + arith_uint256 aNonce; + aNonce = UintToArith256(block.nNonce); - // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256 - // as it's too large for a 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 / (nTarget+1) + 1. - return CChainPower(0, (~bnStakeTarget / (bnStakeTarget + 1)) + 1, (~bnWorkTarget / (bnWorkTarget + 1)) + 1); + // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256 + // as it's too large for a 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 / (nTarget+1) + 1. + return CChainPower(0, ((~bnStakeTarget / (bnStakeTarget + 1)) + 1) + ((~aNonce / (aNonce + 1)) + 1), + (~bnWorkTarget / (bnWorkTarget + 1)) + 1); + } } int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 8f0c5f044..622fd65c5 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1225,14 +1225,13 @@ bool CWallet::VerusSelectStakeOutput(CBlock *pBlock, arith_uint256 &hashResult, { if (txout.fSpendable && (UintToArith256(txout.tx->GetVerusPOSHash(&(pBlock->nNonce), txout.i, nHeight, pastHash)) <= target) && (txout.nDepth >= VERUS_MIN_STAKEAGE)) { - printf("Found PoS block\nnNonce: %s\n", pBlock->nNonce.GetHex().c_str()); - pBlock->nNonce.SetPOSEntropy(pastHash, txout.tx->GetHash(), txout.i); - printf("new nonce: %s\n", pBlock->nNonce.GetHex().c_str()); - // get the smallest winner - if (Solver(txout.tx->vout[txout.i].scriptPubKey, whichType, vSolutions) && (whichType == TX_PUBKEY || whichType == TX_PUBKEYHASH) && - (!pwinner || pwinner->tx->vout[pwinner->i].nValue > txout.tx->vout[txout.i].nValue)) + if ((!pwinner || UintToArith256(curNonce) > UintToArith256(pBlock->nNonce)) && + (Solver(txout.tx->vout[txout.i].scriptPubKey, whichType, vSolutions) && (whichType == TX_PUBKEY || whichType == TX_PUBKEYHASH))) + { + printf("Found PoS block\nnNonce: %s\n", pBlock->nNonce.GetHex().c_str()); pwinner = &txout; curNonce = pBlock->nNonce; + } } } if (pwinner)