mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 14:59:39 -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
|
||||
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.
|
||||
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);
|
||||
if (fuzzed_data_provider.ConsumeBool()) time_skip *= -1;
|
||||
time += time_skip;
|
||||
CheckInvariants(txdownload_impl, max_orphan_count);
|
||||
}
|
||||
CheckInvariants(txdownload_impl, max_orphan_count);
|
||||
// Disconnect everybody, check that all data structures are empty.
|
||||
for (NodeId nodeid = 0; nodeid < NUM_PEERS; ++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.
|
||||
if (!ptx_potential_parent || fuzzed_data_provider.ConsumeBool()) {
|
||||
ptx_potential_parent = tx;
|
||||
|
@ -213,4 +214,5 @@ FUZZ_TARGET(txorphan, .init = initialize_orphanage)
|
|||
const bool get_tx_nonnull{orphanage.GetTx(tx->GetWitnessHash()) != nullptr};
|
||||
Assert(have_tx == get_tx_nonnull);
|
||||
}
|
||||
orphanage.SanityCheck();
|
||||
}
|
||||
|
|
|
@ -321,3 +321,43 @@ std::vector<TxOrphanage::OrphanTxBase> TxOrphanage::GetOrphanTransactions() cons
|
|||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/** Check consistency between PeerOrphanInfo and m_orphans. Recalculate counters and ensure they
|
||||
* match what is cached. */
|
||||
void SanityCheck() const;
|
||||
|
||||
protected:
|
||||
struct OrphanTx : public OrphanTxBase {
|
||||
size_t list_pos;
|
||||
|
|
Loading…
Add table
Reference in a new issue