diff options
Diffstat (limited to 'src/test/util/mining.cpp')
-rw-r--r-- | src/test/util/mining.cpp | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/src/test/util/mining.cpp b/src/test/util/mining.cpp index 0df1db84c4..51f4b89512 100644 --- a/src/test/util/mining.cpp +++ b/src/test/util/mining.cpp @@ -6,19 +6,22 @@ #include <chainparams.h> #include <consensus/merkle.h> +#include <consensus/validation.h> #include <key_io.h> #include <node/context.h> #include <pow.h> +#include <primitives/transaction.h> #include <script/standard.h> #include <test/util/script.h> #include <util/check.h> #include <validation.h> +#include <validationinterface.h> #include <versionbits.h> using node::BlockAssembler; using node::NodeContext; -CTxIn generatetoaddress(const NodeContext& node, const std::string& address) +COutPoint generatetoaddress(const NodeContext& node, const std::string& address) { const auto dest = DecodeDestination(address); assert(IsValidDestination(dest)); @@ -58,19 +61,52 @@ std::vector<std::shared_ptr<CBlock>> CreateBlockChain(size_t total_height, const return ret; } -CTxIn MineBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey) +COutPoint MineBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey) { auto block = PrepareBlock(node, coinbase_scriptPubKey); + auto valid = MineBlock(node, block); + assert(!valid.IsNull()); + return valid; +} + +struct BlockValidationStateCatcher : public CValidationInterface { + const uint256 m_hash; + std::optional<BlockValidationState> m_state; + BlockValidationStateCatcher(const uint256& hash) + : m_hash{hash}, + m_state{} {} + +protected: + void BlockChecked(const CBlock& block, const BlockValidationState& state) override + { + if (block.GetHash() != m_hash) return; + m_state = state; + } +}; + +COutPoint MineBlock(const NodeContext& node, std::shared_ptr<CBlock>& block) +{ while (!CheckProofOfWork(block->GetHash(), block->nBits, Params().GetConsensus())) { ++block->nNonce; assert(block->nNonce); } - bool processed{Assert(node.chainman)->ProcessNewBlock(block, true, true, nullptr)}; - assert(processed); - - return CTxIn{block->vtx[0]->GetHash(), 0}; + auto& chainman{*Assert(node.chainman)}; + const auto old_height = WITH_LOCK(chainman.GetMutex(), return chainman.ActiveHeight()); + bool new_block; + BlockValidationStateCatcher bvsc{block->GetHash()}; + RegisterValidationInterface(&bvsc); + const bool processed{chainman.ProcessNewBlock(block, true, true, &new_block)}; + const bool duplicate{!new_block && processed}; + assert(!duplicate); + UnregisterValidationInterface(&bvsc); + SyncWithValidationInterfaceQueue(); + const bool was_valid{bvsc.m_state && bvsc.m_state->IsValid()}; + assert(old_height + was_valid == WITH_LOCK(chainman.GetMutex(), return chainman.ActiveHeight())); + + if (was_valid) return {block->vtx[0]->GetHash(), 0}; + return {}; } std::shared_ptr<CBlock> PrepareBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey, |