mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 23:09:44 -04:00
[fuzz] TxOrphanage::SanityCheck accounting
This commit is contained in:
parent
22dccea553
commit
e107bf78f9
4 changed files with 48 additions and 1 deletions
|
@ -285,6 +285,7 @@ static void CheckInvariants(const node::TxDownloadManagerImpl& txdownload_impl,
|
||||||
|
|
||||||
// Orphanage usage should never exceed what is allowed
|
// Orphanage usage should never exceed what is allowed
|
||||||
Assert(orphanage.Size() <= max_orphan_count);
|
Assert(orphanage.Size() <= max_orphan_count);
|
||||||
|
txdownload_impl.m_orphanage.SanityCheck();
|
||||||
|
|
||||||
// We should never have more than the maximum in-flight requests out for a peer.
|
// We should never have more than the maximum in-flight requests out for a peer.
|
||||||
for (NodeId peer = 0; peer < NUM_PEERS; ++peer) {
|
for (NodeId peer = 0; peer < NUM_PEERS; ++peer) {
|
||||||
|
@ -437,8 +438,8 @@ FUZZ_TARGET(txdownloadman_impl, .init = initialize)
|
||||||
auto time_skip = fuzzed_data_provider.PickValueInArray(TIME_SKIPS);
|
auto time_skip = fuzzed_data_provider.PickValueInArray(TIME_SKIPS);
|
||||||
if (fuzzed_data_provider.ConsumeBool()) time_skip *= -1;
|
if (fuzzed_data_provider.ConsumeBool()) time_skip *= -1;
|
||||||
time += time_skip;
|
time += time_skip;
|
||||||
CheckInvariants(txdownload_impl, max_orphan_count);
|
|
||||||
}
|
}
|
||||||
|
CheckInvariants(txdownload_impl, max_orphan_count);
|
||||||
// Disconnect everybody, check that all data structures are empty.
|
// Disconnect everybody, check that all data structures are empty.
|
||||||
for (NodeId nodeid = 0; nodeid < NUM_PEERS; ++nodeid) {
|
for (NodeId nodeid = 0; nodeid < NUM_PEERS; ++nodeid) {
|
||||||
txdownload_impl.DisconnectedPeer(nodeid);
|
txdownload_impl.DisconnectedPeer(nodeid);
|
||||||
|
|
|
@ -204,6 +204,7 @@ FUZZ_TARGET(txorphan, .init = initialize_orphanage)
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set tx as potential parent to be used for future GetChildren() calls.
|
// Set tx as potential parent to be used for future GetChildren() calls.
|
||||||
if (!ptx_potential_parent || fuzzed_data_provider.ConsumeBool()) {
|
if (!ptx_potential_parent || fuzzed_data_provider.ConsumeBool()) {
|
||||||
ptx_potential_parent = tx;
|
ptx_potential_parent = tx;
|
||||||
|
@ -213,4 +214,5 @@ FUZZ_TARGET(txorphan, .init = initialize_orphanage)
|
||||||
const bool get_tx_nonnull{orphanage.GetTx(tx->GetWitnessHash()) != nullptr};
|
const bool get_tx_nonnull{orphanage.GetTx(tx->GetWitnessHash()) != nullptr};
|
||||||
Assert(have_tx == get_tx_nonnull);
|
Assert(have_tx == get_tx_nonnull);
|
||||||
}
|
}
|
||||||
|
orphanage.SanityCheck();
|
||||||
}
|
}
|
||||||
|
|
|
@ -321,3 +321,43 @@ std::vector<TxOrphanage::OrphanTxBase> TxOrphanage::GetOrphanTransactions() cons
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TxOrphanage::SanityCheck() const
|
||||||
|
{
|
||||||
|
// Check that cached m_total_announcements is correct
|
||||||
|
unsigned int counted_total_announcements{0};
|
||||||
|
// Check that m_total_orphan_usage is correct
|
||||||
|
unsigned int counted_total_usage{0};
|
||||||
|
|
||||||
|
// Check that cached PeerOrphanInfo::m_total_size is correct
|
||||||
|
std::map<NodeId, unsigned int> counted_size_per_peer;
|
||||||
|
|
||||||
|
for (const auto& [wtxid, orphan] : m_orphans) {
|
||||||
|
counted_total_announcements += orphan.announcers.size();
|
||||||
|
counted_total_usage += orphan.GetUsage();
|
||||||
|
|
||||||
|
Assume(!orphan.announcers.empty());
|
||||||
|
for (const auto& peer : orphan.announcers) {
|
||||||
|
auto& count_peer_entry = counted_size_per_peer.try_emplace(peer).first->second;
|
||||||
|
count_peer_entry += orphan.GetUsage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Assume(m_total_announcements >= m_orphans.size());
|
||||||
|
Assume(counted_total_announcements == m_total_announcements);
|
||||||
|
Assume(counted_total_usage == m_total_orphan_usage);
|
||||||
|
|
||||||
|
// There must be an entry in m_peer_orphanage_info for each peer
|
||||||
|
// However, there may be m_peer_orphanage_info entries corresponding to peers for whom we
|
||||||
|
// previously had orphans but no longer do.
|
||||||
|
Assume(counted_size_per_peer.size() <= m_peer_orphanage_info.size());
|
||||||
|
|
||||||
|
for (const auto& [peerid, info] : m_peer_orphanage_info) {
|
||||||
|
auto it_counted = counted_size_per_peer.find(peerid);
|
||||||
|
if (it_counted == counted_size_per_peer.end()) {
|
||||||
|
Assume(info.m_total_usage == 0);
|
||||||
|
} else {
|
||||||
|
Assume(it_counted->second == info.m_total_usage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -105,6 +105,10 @@ public:
|
||||||
return peer_it == m_peer_orphanage_info.end() ? 0 : peer_it->second.m_total_usage;
|
return peer_it == m_peer_orphanage_info.end() ? 0 : peer_it->second.m_total_usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Check consistency between PeerOrphanInfo and m_orphans. Recalculate counters and ensure they
|
||||||
|
* match what is cached. */
|
||||||
|
void SanityCheck() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct OrphanTx : public OrphanTxBase {
|
struct OrphanTx : public OrphanTxBase {
|
||||||
size_t list_pos;
|
size_t list_pos;
|
||||||
|
|
Loading…
Add table
Reference in a new issue