mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-20 10:38:42 +01:00
test: Add util to mine invalid blocks
With the current utils it is only possible to mine valid blocks. This commit adds new util methods to mine invalid blocks.
This commit is contained in:
parent
7b45d171f5
commit
fa846ee074
@ -27,7 +27,7 @@ static void AssembleBlock(benchmark::Bench& bench)
|
||||
std::array<CTransactionRef, NUM_BLOCKS - COINBASE_MATURITY + 1> txs;
|
||||
for (size_t b{0}; b < NUM_BLOCKS; ++b) {
|
||||
CMutableTransaction tx;
|
||||
tx.vin.push_back(MineBlock(test_setup->m_node, P2WSH_OP_TRUE));
|
||||
tx.vin.push_back(CTxIn{MineBlock(test_setup->m_node, P2WSH_OP_TRUE)});
|
||||
tx.vin.back().scriptWitness = witness;
|
||||
tx.vout.emplace_back(1337, P2WSH_OP_TRUE);
|
||||
if (NUM_BLOCKS - b >= COINBASE_MATURITY)
|
||||
|
@ -42,12 +42,12 @@ void initialize_tx_pool()
|
||||
g_setup = testing_setup.get();
|
||||
|
||||
for (int i = 0; i < 2 * COINBASE_MATURITY; ++i) {
|
||||
CTxIn in = MineBlock(g_setup->m_node, P2WSH_OP_TRUE);
|
||||
COutPoint prevout{MineBlock(g_setup->m_node, P2WSH_OP_TRUE)};
|
||||
// Remember the txids to avoid expensive disk access later on
|
||||
auto& outpoints = i < COINBASE_MATURITY ?
|
||||
g_outpoints_coinbase_init_mature :
|
||||
g_outpoints_coinbase_init_immature;
|
||||
outpoints.push_back(in.prevout);
|
||||
outpoints.push_back(prevout);
|
||||
}
|
||||
SyncWithValidationInterfaceQueue();
|
||||
}
|
||||
|
@ -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);
|
||||
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()));
|
||||
|
||||
return CTxIn{block->vtx[0]->GetHash(), 0};
|
||||
if (was_valid) return {block->vtx[0]->GetHash(), 0};
|
||||
return {};
|
||||
}
|
||||
|
||||
std::shared_ptr<CBlock> PrepareBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey,
|
||||
|
@ -13,8 +13,8 @@
|
||||
|
||||
class CBlock;
|
||||
class CChainParams;
|
||||
class COutPoint;
|
||||
class CScript;
|
||||
class CTxIn;
|
||||
namespace node {
|
||||
struct NodeContext;
|
||||
} // namespace node
|
||||
@ -23,7 +23,13 @@ struct NodeContext;
|
||||
std::vector<std::shared_ptr<CBlock>> CreateBlockChain(size_t total_height, const CChainParams& params);
|
||||
|
||||
/** Returns the generated coin */
|
||||
CTxIn MineBlock(const node::NodeContext&, const CScript& coinbase_scriptPubKey);
|
||||
COutPoint MineBlock(const node::NodeContext&, const CScript& coinbase_scriptPubKey);
|
||||
|
||||
/**
|
||||
* Returns the generated coin (or Null if the block was invalid).
|
||||
* It is recommended to call RegenerateCommitments before mining the block to avoid merkle tree mismatches.
|
||||
**/
|
||||
COutPoint MineBlock(const node::NodeContext&, std::shared_ptr<CBlock>& block);
|
||||
|
||||
/** Prepare a block to be mined */
|
||||
std::shared_ptr<CBlock> PrepareBlock(const node::NodeContext&, const CScript& coinbase_scriptPubKey);
|
||||
@ -31,6 +37,6 @@ std::shared_ptr<CBlock> PrepareBlock(const node::NodeContext& node, const CScrip
|
||||
const node::BlockAssembler::Options& assembler_options);
|
||||
|
||||
/** RPC-like helper function, returns the generated coin */
|
||||
CTxIn generatetoaddress(const node::NodeContext&, const std::string& address);
|
||||
COutPoint generatetoaddress(const node::NodeContext&, const std::string& address);
|
||||
|
||||
#endif // BITCOIN_TEST_UTIL_MINING_H
|
||||
|
Loading…
Reference in New Issue
Block a user