mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 14:59:39 -04:00
add check that chainwork doesn't exceed minimum work
This commit is contained in:
parent
9aa5d1c3fc
commit
284bd17309
1 changed files with 24 additions and 8 deletions
|
@ -10,6 +10,7 @@
|
|||
#include <test/util/net.h>
|
||||
#include <test/util/script.h>
|
||||
#include <test/util/setup_common.h>
|
||||
#include <uint256.h>
|
||||
#include <validation.h>
|
||||
|
||||
namespace {
|
||||
|
@ -20,9 +21,7 @@ class HeadersSyncSetup : public TestingSetup
|
|||
std::vector<CNode*> m_connections;
|
||||
|
||||
public:
|
||||
HeadersSyncSetup(const ChainType chain_type = ChainType::MAIN,
|
||||
TestOpts opts = {})
|
||||
: TestingSetup(chain_type, opts)
|
||||
HeadersSyncSetup(const ChainType chain_type, TestOpts opts) : TestingSetup(chain_type, opts)
|
||||
{
|
||||
PeerManager::Options peerman_opts;
|
||||
node::ApplyArgsManOptions(*m_node.args, peerman_opts);
|
||||
|
@ -116,9 +115,9 @@ CBlock ConsumeBlock(FuzzedDataProvider& fuzzed_data_provider, const uint256& pre
|
|||
return block;
|
||||
}
|
||||
|
||||
void FinalizeHeader(CBlockHeader& header)
|
||||
void FinalizeHeader(CBlockHeader& header, const ChainstateManager& chainman)
|
||||
{
|
||||
while (!CheckProofOfWork(header.GetHash(), header.nBits, Params().GetConsensus())) {
|
||||
while (!CheckProofOfWork(header.GetHash(), header.nBits, chainman.GetParams().GetConsensus())) {
|
||||
++(header.nNonce);
|
||||
}
|
||||
}
|
||||
|
@ -144,17 +143,20 @@ FUZZ_TARGET(p2p_headers_presync, .init = initialize)
|
|||
|
||||
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
||||
|
||||
CBlockHeader base{Params().GenesisBlock()};
|
||||
CBlockHeader base{chainman.GetParams().GenesisBlock()};
|
||||
SetMockTime(base.nTime);
|
||||
|
||||
// The chain is just a single block, so this is equal to 1
|
||||
size_t original_index_size{WITH_LOCK(cs_main, return chainman.m_blockman.m_block_index.size())};
|
||||
arith_uint256 total_work{WITH_LOCK(cs_main, return chainman.m_best_header->nChainWork)};
|
||||
|
||||
std::vector<CBlockHeader> all_headers;
|
||||
|
||||
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 100)
|
||||
{
|
||||
auto finalized_block = [&]() {
|
||||
CBlock block = ConsumeBlock(fuzzed_data_provider, base.GetHash(), base.nBits);
|
||||
FinalizeHeader(block);
|
||||
FinalizeHeader(block, chainman);
|
||||
return block;
|
||||
};
|
||||
|
||||
|
@ -167,10 +169,12 @@ FUZZ_TARGET(p2p_headers_presync, .init = initialize)
|
|||
headers.resize(FUZZ_MAX_HEADERS_RESULTS);
|
||||
for (CBlock& header : headers) {
|
||||
header = ConsumeHeader(fuzzed_data_provider, base.GetHash(), base.nBits);
|
||||
FinalizeHeader(header);
|
||||
FinalizeHeader(header, chainman);
|
||||
base = header;
|
||||
}
|
||||
|
||||
all_headers.insert(all_headers.end(), headers.begin(), headers.end());
|
||||
|
||||
auto headers_msg = NetMsg::Make(NetMsgType::HEADERS, TX_WITH_WITNESS(headers));
|
||||
g_testing_setup->SendMessage(fuzzed_data_provider, std::move(headers_msg));
|
||||
},
|
||||
|
@ -179,6 +183,8 @@ FUZZ_TARGET(p2p_headers_presync, .init = initialize)
|
|||
auto block = finalized_block();
|
||||
CBlockHeaderAndShortTxIDs cmpct_block{block, fuzzed_data_provider.ConsumeIntegral<uint64_t>()};
|
||||
|
||||
all_headers.push_back(block);
|
||||
|
||||
auto headers_msg = NetMsg::Make(NetMsgType::CMPCTBLOCK, TX_WITH_WITNESS(cmpct_block));
|
||||
g_testing_setup->SendMessage(fuzzed_data_provider, std::move(headers_msg));
|
||||
},
|
||||
|
@ -186,9 +192,19 @@ FUZZ_TARGET(p2p_headers_presync, .init = initialize)
|
|||
// Send a block
|
||||
auto block = finalized_block();
|
||||
|
||||
all_headers.push_back(block);
|
||||
|
||||
auto headers_msg = NetMsg::Make(NetMsgType::BLOCK, TX_WITH_WITNESS(block));
|
||||
g_testing_setup->SendMessage(fuzzed_data_provider, std::move(headers_msg));
|
||||
});
|
||||
|
||||
// This is a conservative overestimate, as base is only moved forward when sending headers. In theory,
|
||||
// the longest chain generated by this test is 1600 (FUZZ_MAX_HEADERS_RESULTS * 100) headers. In that case,
|
||||
// this variable will accurately reflect the chain's total work.
|
||||
total_work += CalculateClaimedHeadersWork(all_headers);
|
||||
|
||||
// This test should never create a chain with more work than MinimumChainWork.
|
||||
assert(total_work < chainman.MinimumChainWork());
|
||||
}
|
||||
|
||||
// The headers/blocks sent in this test should never be stored, as the chains don't have the work required
|
||||
|
|
Loading…
Add table
Reference in a new issue