mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-01 09:35:52 -05:00
Add FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION in PoW check
To avoid PoW being a blocker for fuzz tests, `FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION` is used in fuzz builds to bypass the actual PoW validation in `CheckProofOfWork`. It's replaced with a check on the last byte of the hash, which allows the fuzzer to quickly generate (in)valid blocks by checking a single bit, rather than performing the full PoW computation. If PoW is the target of a fuzz test, then it should call `CheckProofOfWorkImpl`.
This commit is contained in:
parent
a3f6f5acd8
commit
a0eaa4749f
4 changed files with 14 additions and 2 deletions
11
src/pow.cpp
11
src/pow.cpp
|
@ -134,7 +134,18 @@ bool PermittedDifficultyTransition(const Consensus::Params& params, int64_t heig
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bypasses the actual proof of work check during fuzz testing with a simplified validation checking whether
|
||||||
|
// the most signficant bit of the last byte of the hash is set.
|
||||||
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
|
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
|
||||||
|
{
|
||||||
|
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||||
|
return (hash.data()[31] & 0x80) == 0;
|
||||||
|
#else
|
||||||
|
return CheckProofOfWorkImpl(hash, nBits, params);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CheckProofOfWorkImpl(uint256 hash, unsigned int nBits, const Consensus::Params& params)
|
||||||
{
|
{
|
||||||
bool fNegative;
|
bool fNegative;
|
||||||
bool fOverflow;
|
bool fOverflow;
|
||||||
|
|
|
@ -19,6 +19,7 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF
|
||||||
|
|
||||||
/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
|
/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
|
||||||
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&);
|
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&);
|
||||||
|
bool CheckProofOfWorkImpl(uint256 hash, unsigned int nBits, const Consensus::Params&);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return false if the proof-of-work requirement specified by new_nbits at a
|
* Return false if the proof-of-work requirement specified by new_nbits at a
|
||||||
|
|
|
@ -69,7 +69,7 @@ FUZZ_TARGET(integer, .init = initialize_integer)
|
||||||
const bool b = fuzzed_data_provider.ConsumeBool();
|
const bool b = fuzzed_data_provider.ConsumeBool();
|
||||||
|
|
||||||
const Consensus::Params& consensus_params = Params().GetConsensus();
|
const Consensus::Params& consensus_params = Params().GetConsensus();
|
||||||
(void)CheckProofOfWork(u256, u32, consensus_params);
|
(void)CheckProofOfWorkImpl(u256, u32, consensus_params);
|
||||||
if (u64 <= MAX_MONEY) {
|
if (u64 <= MAX_MONEY) {
|
||||||
const uint64_t compressed_money_amount = CompressAmount(u64);
|
const uint64_t compressed_money_amount = CompressAmount(u64);
|
||||||
assert(u64 == DecompressAmount(compressed_money_amount));
|
assert(u64 == DecompressAmount(compressed_money_amount));
|
||||||
|
|
|
@ -80,7 +80,7 @@ FUZZ_TARGET(pow, .init = initialize_pow)
|
||||||
{
|
{
|
||||||
const std::optional<uint256> hash = ConsumeDeserializable<uint256>(fuzzed_data_provider);
|
const std::optional<uint256> hash = ConsumeDeserializable<uint256>(fuzzed_data_provider);
|
||||||
if (hash) {
|
if (hash) {
|
||||||
(void)CheckProofOfWork(*hash, fuzzed_data_provider.ConsumeIntegral<unsigned int>(), consensus_params);
|
(void)CheckProofOfWorkImpl(*hash, fuzzed_data_provider.ConsumeIntegral<unsigned int>(), consensus_params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue