Skip to content

Commit 410ebd6

Browse files
committed
[fuzz] break out parent functions and add GetChildrenFrom* coverage
It's very hard to randomly construct a transaction that would be the parent of an existing orphanage tx. For functions like AddChildrenToWorkSet and GetChildren that take orphan parents, use a tx that was previously constructed.
1 parent d095316 commit 410ebd6

File tree

1 file changed

+29
-3
lines changed

1 file changed

+29
-3
lines changed

src/test/fuzz/txorphan.cpp

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ FUZZ_TARGET(txorphan, .init = initialize_orphanage)
4545
// if true, allow duplicate input when constructing tx
4646
const bool duplicate_input = fuzzed_data_provider.ConsumeBool();
4747

48+
CTransactionRef ptx_potential_parent = nullptr;
49+
4850
LIMITED_WHILE(outpoints.size() < 200'000 && fuzzed_data_provider.ConsumeBool(), 10 * DEFAULT_MAX_ORPHAN_TRANSACTIONS)
4951
{
5052
// construct transaction
@@ -78,16 +80,34 @@ FUZZ_TARGET(txorphan, .init = initialize_orphanage)
7880
return new_tx;
7981
}();
8082

83+
// Trigger orphanage functions that are called using parents. ptx_potential_parent is a tx we constructed in a
84+
// previous loop and potentially the parent of this tx.
85+
if (ptx_potential_parent) {
86+
// Set up future GetTxToReconsider call.
87+
orphanage.AddChildrenToWorkSet(*ptx_potential_parent);
88+
89+
// Check that all txns returned from GetChildrenFrom* are indeed a direct child of this tx.
90+
NodeId peer_id = fuzzed_data_provider.ConsumeIntegral<NodeId>();
91+
for (const auto& child : orphanage.GetChildrenFromSamePeer(ptx_potential_parent, peer_id)) {
92+
assert(std::any_of(child->vin.cbegin(), child->vin.cend(), [&](const auto& input) {
93+
return input.prevout.hash == ptx_potential_parent->GetHash();
94+
}));
95+
}
96+
for (const auto& [child, peer] : orphanage.GetChildrenFromDifferentPeer(ptx_potential_parent, peer_id)) {
97+
assert(std::any_of(child->vin.cbegin(), child->vin.cend(), [&](const auto& input) {
98+
return input.prevout.hash == ptx_potential_parent->GetHash();
99+
}));
100+
assert(peer != peer_id);
101+
}
102+
}
103+
81104
// trigger orphanage functions
82105
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10 * DEFAULT_MAX_ORPHAN_TRANSACTIONS)
83106
{
84107
NodeId peer_id = fuzzed_data_provider.ConsumeIntegral<NodeId>();
85108

86109
CallOneOf(
87110
fuzzed_data_provider,
88-
[&] {
89-
orphanage.AddChildrenToWorkSet(*tx);
90-
},
91111
[&] {
92112
{
93113
CTransactionRef ref = orphanage.GetTxToReconsider(peer_id);
@@ -136,6 +156,12 @@ FUZZ_TARGET(txorphan, .init = initialize_orphanage)
136156
orphanage.LimitOrphans(limit, limit_orphans_rng);
137157
Assert(orphanage.Size() <= limit);
138158
});
159+
160+
}
161+
// Set tx as potential parent to be used for future GetChildren() calls.
162+
if (!ptx_potential_parent || fuzzed_data_provider.ConsumeBool()) {
163+
ptx_potential_parent = tx;
139164
}
165+
140166
}
141167
}

0 commit comments

Comments
 (0)