diff --git a/src/chain.h b/src/chain.h index 66ae025b7599e..732fe6826a2a5 100644 --- a/src/chain.h +++ b/src/chain.h @@ -275,7 +275,7 @@ class CBlockIndex SetNull(); } - CBlockIndex(const CBlock& block) + explicit CBlockIndex(const CBlock& block) { SetNull(); diff --git a/src/kernel.cpp b/src/kernel.cpp index 9106860994faf..1e2ee4d5e8545 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -288,10 +288,6 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned bnTargetPerCoinDay.SetCompact(nBits); CAmount nValueIn = txPrev->vout[prevout.n].nValue; - // discard stakes generated from inputs of less than 10000 PAC - if (nValueIn < Params().GetConsensus().nMinimumStakeValue) - return error("CheckStakeKernelHash() : min amount violation"); - // v0.3 protocol kernel hash weight starts from 0 at the 30-day min age // this change increases active coins participating the hash and helps // to secure the network when proof-of-stake difficulty is low @@ -366,11 +362,6 @@ bool CheckProofOfStake(const CBlock &block, uint256& hashProofOfStake) CTxOut prevTxOut = txPrev->vout[txin.prevout.n]; - // Enforce minimum amount for stake input - if (prevTxOut.nValue < Params().GetConsensus().nMinimumStakeValue) - return error("CheckProofOfStake() : INFO: stakeinput value less than minimum required (%llu < %llu), blockhash %s\n", - prevTxOut.nValue, Params().GetConsensus().nMinimumStakeValue, hashBlock.ToString().c_str()); - CBlockIndex* pindex = NULL; BlockMap::iterator it = mapBlockIndex.find(hashBlock); if (it != mapBlockIndex.end()) @@ -386,9 +377,8 @@ bool CheckProofOfStake(const CBlock &block, uint256& hashProofOfStake) if(!CheckKernelScript(prevTxOut.scriptPubKey, tx->vout[1].scriptPubKey)) return error("CheckProofOfStake() : INFO: check kernel script failed on coinstake %s, hashProof=%s \n", tx->GetHash().ToString().c_str(), hashProofOfStake.ToString().c_str()); - unsigned int nTime = block.nTime; - if (!CheckStakeKernelHash(block.nBits, blockprev, sizeof(CBlock), txPrev, txin.prevout, nTime, hashProofOfStake, false, true)) - return error("CheckProofOfStake() : INFO: check kernel failed on coinstake %s, hashProof=%s \n", tx->GetHash().ToString().c_str(), hashProofOfStake.ToString().c_str()); // may occur during initial download or if behind on block chain sync + if (!CheckStakeKernelHash(block.nBits, blockprev, sizeof(CBlock), txPrev, txin.prevout, block.nTime, hashProofOfStake, false, true)) + return error("CheckProofOfStake() : INFO: check kernel failed on coinstake %s, hashProof=%s \n", tx->GetHash().ToString().c_str(), hashProofOfStake.ToString().c_str()); return true; } diff --git a/src/validation.cpp b/src/validation.cpp index 3dab739cb590b..e809c71ee565e 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -107,7 +107,6 @@ std::atomic fDIP0001ActiveAtTip{false}; std::atomic fDIP0003ActiveAtTip{false}; uint256 hashAssumeValid; -std::map mapStakeSpent; CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE; @@ -1095,8 +1094,12 @@ bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHea return true; } -bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams) -{ +#if __APPLE__ +bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams) { +#else +bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams, const char* str) { + LogPrintf("ReadBlockFromDisk(CDiskBlockPos)::called by %s\n", str); +#endif LOCK(cs_main); block.SetNull(); @@ -1120,8 +1123,12 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus: return true; } -bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams) -{ +#if __APPLE__ +bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams) { +#else +bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams, const char* str) { + LogPrintf("ReadBlockFromDisk(CBlockIndex)::called by %s\n", str); +#endif CDiskBlockPos blockPos; { LOCK(cs_main); @@ -1744,9 +1751,6 @@ static DisconnectResult DisconnectBlock(const CBlock& block, CValidationState& s if (res == DISCONNECT_FAILED) return DISCONNECT_FAILED; fClean = fClean && res != DISCONNECT_UNCLEAN; - // erase the spent input - mapStakeSpent.erase(out); - const CTxIn input = tx.vin[j]; if (fSpentIndex) { @@ -2370,30 +2374,6 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd if (!pblocktree->WriteTxIndex(vPos)) return AbortNode(state, "Failed to write transaction index"); - if (pindex->nHeight > Params().GetConsensus().nLastPoWBlock) - { - // add new entries - for (const CTransactionRef ptx: block.vtx) { - const CTransaction& tx = *ptx; - if (tx.IsCoinBase()) - continue; - for (const CTxIn in: tx.vin) { - LogPrintf("mapStakeSpent: Insert %s | %u\n", in.prevout.ToString(), pindex->nHeight); - mapStakeSpent.insert(std::make_pair(in.prevout, pindex->nHeight)); - } - } - - // delete old entries - for (auto it = mapStakeSpent.begin(); it != mapStakeSpent.end();) { - if (it->second < pindex->nHeight - Params().MaxReorganizationDepth()) { - LogPrintf("mapStakeSpent: Erase %s | %u\n", it->first.ToString(), it->second); - it = mapStakeSpent.erase(it); - }else { - it++; - } - } - } - if (fAddressIndex) { if (!pblocktree->WriteAddressIndex(addressIndex)) { return AbortNode(state, "Failed to write address index"); @@ -3681,6 +3661,7 @@ static bool AcceptBlock(const std::shared_ptr& pblock, CValidation CBlockIndex *pindexDummy = NULL; CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy; + if (!AcceptBlockHeader(block, state, chainparams, &pindex)) return false; @@ -3725,68 +3706,12 @@ static bool AcceptBlock(const std::shared_ptr& pblock, CValidation if (!IsInitialBlockDownload() && chainActive.Tip() == pindex->pprev) GetMainSignals().NewPoWValidBlock(pindex, pblock); - int nHeight = pindex->nHeight; - - if (block.IsProofOfStake()) { - LOCK(cs_main); - - CCoinsViewCache coins(pcoinsTip); - - const CTransaction& tx = *block.vtx[1]; - if (!coins.HaveInputs(tx)) { - // the inputs are spent at the chain tip so we should look at the recently spent outputs - - for (CTxIn in : tx.vin) { - auto it = mapStakeSpent.find(in.prevout); - if (it == mapStakeSpent.end()) { - return false; - } - if (it->second < pindex->pprev->nHeight) { - return false; - } - } - } - - // if this is on fork - if (!chainActive.Contains(pindex->pprev) && pindex->pprev != nullptr) { - // start at the block we're adding on to - CBlockIndex *last = pindex->pprev; - - // while that block is not on the main chain - while (!chainActive.Contains(last) && last != NULL) { - CBlock bl; - ReadBlockFromDisk(bl, last, Params().GetConsensus()); - // loop through every spent input from said block - - for (CTransactionRef tRef : bl.vtx) { - const CTransaction& t = *tRef; - for (CTxIn in : t.vin) { - // loop through every spent input in the staking transaction of the new block - - const CTransaction& tx = *block.vtx[1]; - for (CTxIn stakeIn : tx.vin) { - - // if they spent the same input - if (stakeIn.prevout == in.prevout) { - // reject the block - return false; - } - } - } - } - - // go to the parent block - last = last->pprev; - } - } - } - - // test if hashproofofstake matches + //// hashproof test uint256 hashProofOfStake = uint256(); if (block.IsProofOfStake()) { - if(block.GetHash() == hashProofOfStake) - return state.DoS(100, error("CheckBlock(): invalid proof of stake block\n")); + if(block.GetHash() == hashProofOfStake) + return state.DoS(100, error("CheckBlock(): invalid proof of stake block\n")); if(!CheckProofOfStake(block, hashProofOfStake)) return state.DoS(100, error("CheckBlock(): check proof-of-stake failed for block %s\n", hashProofOfStake.ToString().c_str())); @@ -3805,7 +3730,7 @@ static bool AcceptBlock(const std::shared_ptr& pblock, CValidation CDiskBlockPos blockPos; if (dbp != NULL) blockPos = *dbp; - if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL)) + if (!FindBlockPos(state, blockPos, nBlockSize+8, pindex->nHeight, block.GetBlockTime(), dbp != NULL)) return error("AcceptBlock(): FindBlockPos failed"); if (dbp == NULL) if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart())) diff --git a/src/validation.h b/src/validation.h index 86b0e03ab0224..a26f2ee59db08 100644 --- a/src/validation.h +++ b/src/validation.h @@ -486,8 +486,15 @@ bool GetAddressUnspent(uint160 addressHash, int type, /** Functions for disk access for blocks */ bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart); + +// note - clang doesnt like __builtin_FUNCTION() +#if __APPLE__ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams); bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams); +#else +bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams, const char* str = __builtin_FUNCTION()); +bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams, const char* str = __builtin_FUNCTION()); +#endif /** Functions for validating blocks and updating the block tree */