diff --git a/src/gridcoin/staking/kernel.cpp b/src/gridcoin/staking/kernel.cpp index 1eb8e195ab..47e436643b 100644 --- a/src/gridcoin/staking/kernel.cpp +++ b/src/gridcoin/staking/kernel.cpp @@ -12,6 +12,8 @@ #include "streams.h" #include "util.h" +#include + using namespace std; using namespace GRC; @@ -385,12 +387,28 @@ bool GRC::ReadStakedInput( CTxDB& txdb, const uint256 prevout_hash, CBlockHeader& out_header, - CTransaction& out_txprev) + CTransaction& out_txprev, + CBlockIndex* pindexPrev) { CTxIndex tx_index; // Get transaction index for the previous transaction if (!txdb.ReadTxIndex(prevout_hash, tx_index)) { + if (pindexPrev != nullptr) { + for (CBlockIndex* pindex = pindexPrev; pindex->pprev != nullptr; pindex = pindex->pprev) { + CBlock block; + ReadBlockFromDisk(block, pindex, Params().GetConsensus()); + + for (const auto& tx : block.vtx) { + if (tx.GetHash() == prevout_hash) { + error("Found tx %s in block %s", tx.GetHash().ToString(), pindex->GetBlockHash().ToString()); + out_txprev = tx; + out_header = pindex->GetBlockHeader(); + return true; + } + } + } + } // Previous transaction not in main chain, may occur during initial download return error("%s: tx index not found for input tx %s", __func__, prevout_hash.GetHex()); } @@ -429,7 +447,7 @@ bool GRC::CalculateLegacyV3HashProof( CTransaction input_tx; CBlockHeader input_block; - if (!ReadStakedInput(txdb, prevout.hash, input_block, input_tx)) { + if (!ReadStakedInput(txdb, prevout.hash, input_block, input_tx, nullptr)) { return coinstake.DoS(1, error("Read staked input failed.")); } @@ -584,7 +602,7 @@ bool GRC::CheckProofOfStakeV8( CBlockHeader header; CTransaction txPrev; - if (!ReadStakedInput(txdb, prevout.hash, header, txPrev)) + if (!ReadStakedInput(txdb, prevout.hash, header, txPrev, pindexPrev)) return tx.DoS(1, error("%s: read staked input failed", __func__)); if (!VerifySignature(txPrev, tx, 0, 0)) diff --git a/src/gridcoin/staking/kernel.h b/src/gridcoin/staking/kernel.h index 237ea7b4b7..380355daad 100644 --- a/src/gridcoin/staking/kernel.h +++ b/src/gridcoin/staking/kernel.h @@ -57,7 +57,8 @@ bool ReadStakedInput( CTxDB& txdb, const uint256 prevout_hash, CBlockHeader& out_header, - CTransaction& out_txprev); + CTransaction& out_txprev, + CBlockIndex* pindexPrev = nullptr); //! //! \brief Calculate the provided block's proof hash with the version 3 staking diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp index f491b723a8..502686fa9f 100644 --- a/src/node/blockstorage.cpp +++ b/src/node/blockstorage.cpp @@ -15,7 +15,10 @@ bool WriteBlockToDisk(const CBlock& block, unsigned int& nFileRet, unsigned int& nBlockPosRet, const CMessageHeader::MessageStartChars& messageStart) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { + AssertLockHeld(cs_main); + // Open history file to append CAutoFile fileout(AppendBlockFile(nFileRet), SER_DISK, CLIENT_VERSION); if (fileout.IsNull()) diff --git a/src/validation.cpp b/src/validation.cpp index 775dc60181..ee78d93bf5 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1752,7 +1752,10 @@ bool AddToBlockIndex(CBlock& block, unsigned int nFile, unsigned int nBlockPos, } bool CheckBlock(const CBlock& block, int height1, bool fCheckPOW, bool fCheckMerkleRoot, bool fCheckSig, bool fLoadingIndex) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { + AssertLockHeld(cs_main); + // Allow the genesis block to pass. if(block.hashPrevBlock.IsNull() && block.GetHash(true) == (fTestNet ? hashGenesisBlockTestNet : hashGenesisBlock))