Motivation
TxOrphanage needs to look up orphan announcements in two different orders — by (wtxid, peer) for transaction lookups, and by (peer, reconsider, sequence) for per-peer iteration and eviction.
Currently this is done with boost::multi_index_container, one of the last remaining Boost uses in the codebase. This PR removes it in favor of standard library containers, contributing to the ongoing effort to eliminate the Boost dependency from bitcoind.
Approach
Replace the boost::multi_index_container with a hand-rolled AnnouncementIndex class wrapping two std::map containers cross-linked by iterators:
m_by_wtxidstd::map<(Wtxid, NodeId), Announcement>— owns the datam_by_peerstd::map<(NodeId, bool, Seq), WtxidMap::iterator>— stores cross-references, no data duplication
std::map iterator stability guarantees that cross-references remain valid across insertions and erasures of other elements. All mutations go through AnnouncementIndex member functions (Insert/Erase/SetReconsider) to keep both indices in sync, with Assume() assertions verifying every mutation.
No behavior change.
Operation mapping
| Operation | Before (boost) | After (AnnouncementIndex) |
|---|---|---|
| Insert | m_orphans.get<ByWtxid>().emplace(tx, peer, seq) |
m_orphans.Insert(tx, peer, seq) |
| Erase | m_orphans.get<Tag>().erase(it) |
m_orphans.Erase(it) (overloaded) |
| Modify reconsider | index.modify(it, [](auto& a){ a.m_reconsider = val; }) |
m_orphans.SetReconsider(it, val) |
| Project peer→wtxid | m_orphans.project<ByWtxid>(peer_it) |
m_orphans.ToWtxid(peer_it) |
| Access field | it->m_tx |
Ann(it).m_tx |