aboutsummaryrefslogtreecommitdiff
path: root/src/test/util/mining.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/util/mining.cpp')
-rw-r--r--src/test/util/mining.cpp48
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,