mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-03 09:56:38 -05:00
Merge bitcoin/bitcoin#28825: fuzz: Minor improvements to tx_package_eval target
6a917918b7
fuzz: allow fake and duplicate inputs in tx_package_eval target (Greg Sanders)a0626ccdad
fuzz: allow reaching MempoolAcceptResult::ResultType::DIFFERENT_WITNESS in tx_package_eval target (Greg Sanders) Pull request description: Exercises `DIFFERENT_WITNESS` by using "blank" WSH() and allowing witness to determine wtxid, and attempts to make invalid/duplicate inputs. ACKs for top commit: dergoegge: Coverage looks good to me ACK6a917918b7
Tree-SHA512: db894f5f5b81c6b454874baf11f296462832285f41ccb09f23c0db92b9abc98f8ecacd72fc8f60dc92cb7947f543a2e55bed2fd210b0e8ca7c7d5389d90b14af
This commit is contained in:
commit
6b7bf907f5
2 changed files with 30 additions and 4 deletions
|
@ -40,7 +40,7 @@ void initialize_tx_pool()
|
||||||
g_setup = testing_setup.get();
|
g_setup = testing_setup.get();
|
||||||
|
|
||||||
for (int i = 0; i < 2 * COINBASE_MATURITY; ++i) {
|
for (int i = 0; i < 2 * COINBASE_MATURITY; ++i) {
|
||||||
COutPoint prevout{MineBlock(g_setup->m_node, P2WSH_OP_TRUE)};
|
COutPoint prevout{MineBlock(g_setup->m_node, P2WSH_EMPTY)};
|
||||||
if (i < COINBASE_MATURITY) {
|
if (i < COINBASE_MATURITY) {
|
||||||
// Remember the txids to avoid expensive disk access later on
|
// Remember the txids to avoid expensive disk access later on
|
||||||
g_outpoints_coinbase_init_mature.push_back(prevout);
|
g_outpoints_coinbase_init_mature.push_back(prevout);
|
||||||
|
@ -195,7 +195,8 @@ FUZZ_TARGET(tx_package_eval, .init = initialize_tx_pool)
|
||||||
// Create input
|
// Create input
|
||||||
const auto sequence = ConsumeSequence(fuzzed_data_provider);
|
const auto sequence = ConsumeSequence(fuzzed_data_provider);
|
||||||
const auto script_sig = CScript{};
|
const auto script_sig = CScript{};
|
||||||
const auto script_wit_stack = std::vector<std::vector<uint8_t>>{WITNESS_STACK_ELEM_OP_TRUE};
|
const auto script_wit_stack = fuzzed_data_provider.ConsumeBool() ? P2WSH_EMPTY_TRUE_STACK : P2WSH_EMPTY_TWO_STACK;
|
||||||
|
|
||||||
CTxIn in;
|
CTxIn in;
|
||||||
in.prevout = outpoint;
|
in.prevout = outpoint;
|
||||||
in.nSequence = sequence;
|
in.nSequence = sequence;
|
||||||
|
@ -204,17 +205,30 @@ FUZZ_TARGET(tx_package_eval, .init = initialize_tx_pool)
|
||||||
|
|
||||||
tx_mut.vin.push_back(in);
|
tx_mut.vin.push_back(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Duplicate an input
|
||||||
|
bool dup_input = fuzzed_data_provider.ConsumeBool();
|
||||||
|
if (dup_input) {
|
||||||
|
tx_mut.vin.push_back(tx_mut.vin.back());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refer to a non-existant input
|
||||||
|
if (fuzzed_data_provider.ConsumeBool()) {
|
||||||
|
tx_mut.vin.emplace_back();
|
||||||
|
}
|
||||||
|
|
||||||
const auto amount_fee = fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(0, amount_in);
|
const auto amount_fee = fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(0, amount_in);
|
||||||
const auto amount_out = (amount_in - amount_fee) / num_out;
|
const auto amount_out = (amount_in - amount_fee) / num_out;
|
||||||
for (int i = 0; i < num_out; ++i) {
|
for (int i = 0; i < num_out; ++i) {
|
||||||
tx_mut.vout.emplace_back(amount_out, P2WSH_OP_TRUE);
|
tx_mut.vout.emplace_back(amount_out, P2WSH_EMPTY);
|
||||||
}
|
}
|
||||||
// TODO vary transaction sizes to catch size-related issues
|
// TODO vary transaction sizes to catch size-related issues
|
||||||
auto tx = MakeTransactionRef(tx_mut);
|
auto tx = MakeTransactionRef(tx_mut);
|
||||||
// Restore previously removed outpoints, except in-package outpoints
|
// Restore previously removed outpoints, except in-package outpoints
|
||||||
if (!last_tx) {
|
if (!last_tx) {
|
||||||
for (const auto& in : tx->vin) {
|
for (const auto& in : tx->vin) {
|
||||||
Assert(outpoints.insert(in.prevout).second);
|
// It's a fake input, or a new input, or a duplicate
|
||||||
|
Assert(in == CTxIn() || outpoints.insert(in.prevout).second || dup_input);
|
||||||
}
|
}
|
||||||
// Cache the in-package outpoints being made
|
// Cache the in-package outpoints being made
|
||||||
for (size_t i = 0; i < tx->vout.size(); ++i) {
|
for (size_t i = 0; i < tx->vout.size(); ++i) {
|
||||||
|
|
|
@ -18,6 +18,18 @@ static const CScript P2WSH_OP_TRUE{
|
||||||
return hash;
|
return hash;
|
||||||
}())};
|
}())};
|
||||||
|
|
||||||
|
static const std::vector<uint8_t> EMPTY{};
|
||||||
|
static const CScript P2WSH_EMPTY{
|
||||||
|
CScript{}
|
||||||
|
<< OP_0
|
||||||
|
<< ToByteVector([] {
|
||||||
|
uint256 hash;
|
||||||
|
CSHA256().Write(EMPTY.data(), EMPTY.size()).Finalize(hash.begin());
|
||||||
|
return hash;
|
||||||
|
}())};
|
||||||
|
static const std::vector<std::vector<uint8_t>> P2WSH_EMPTY_TRUE_STACK{{static_cast<uint8_t>(OP_TRUE)}, {}};
|
||||||
|
static const std::vector<std::vector<uint8_t>> P2WSH_EMPTY_TWO_STACK{{static_cast<uint8_t>(OP_2)}, {}};
|
||||||
|
|
||||||
/** Flags that are not forbidden by an assert in script validation */
|
/** Flags that are not forbidden by an assert in script validation */
|
||||||
bool IsValidFlagCombination(unsigned flags);
|
bool IsValidFlagCombination(unsigned flags);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue