diff options
author | glozow <gloriajzhao@gmail.com> | 2025-01-30 00:46:01 -0500 |
---|---|---|
committer | glozow <gloriajzhao@gmail.com> | 2025-02-07 13:55:57 -0500 |
commit | e107bf78f9d722fcdeb5c1fba5a784dd7747e12f (patch) | |
tree | 2e053c7aac88d71df33f900f41f5d0ae1791f29c | |
parent | 22dccea553253a83c50b2509b881d1c3ae925bdc (diff) |
[fuzz] TxOrphanage::SanityCheck accounting
-rw-r--r-- | src/test/fuzz/txdownloadman.cpp | 3 | ||||
-rw-r--r-- | src/test/fuzz/txorphan.cpp | 2 | ||||
-rw-r--r-- | src/txorphanage.cpp | 40 | ||||
-rw-r--r-- | src/txorphanage.h | 4 |
4 files changed, 48 insertions, 1 deletions
diff --git a/src/test/fuzz/txdownloadman.cpp b/src/test/fuzz/txdownloadman.cpp index a786068256..06385e7bdd 100644 --- a/src/test/fuzz/txdownloadman.cpp +++ b/src/test/fuzz/txdownloadman.cpp @@ -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); diff --git a/src/test/fuzz/txorphan.cpp b/src/test/fuzz/txorphan.cpp index 53f57f5539..9133323449 100644 --- a/src/test/fuzz/txorphan.cpp +++ b/src/test/fuzz/txorphan.cpp @@ -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(); } diff --git a/src/txorphanage.cpp b/src/txorphanage.cpp index 1f7a198594..5de894e32b 100644 --- a/src/txorphanage.cpp +++ b/src/txorphanage.cpp @@ -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); + } + } +} diff --git a/src/txorphanage.h b/src/txorphanage.h index 386408e7ea..50b8d732b2 100644 --- a/src/txorphanage.h +++ b/src/txorphanage.h @@ -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; |