Follow-up to #35923.
getmempoolinfo currently calls GetUnbroadcastTxs().size() to report unbroadcastcount. The getter returns the set by value, so every call copies its entries under the mempool lock and immediately discards the copy after reading its size.
Fix: Add GetUnbroadcastTxCount() and use it in the RPC to read the size under the same lock without allocating a temporary set. This is a separate accessor because broadcast retry and persistence still need the transaction IDs returned by the existing GetUnbroadcastTxs().
I also searched for similar cases nearby: the ancestor/descendant count helpers and the cluster-count path build vectors just to read their sizes, while the mining RPC uses GetDust(...).empty() to check whether any dust outputs exist. These could potentially use count-only or boolean helpers, but would require separate changes to the graph and policy code, so I left them out of this PR.
Added a temporary bench_bitcoin benchmark on my branch, comparing both getters.
Results below are medians from five runs on an Apple M5, using Apple clang 17/libc++ with -O2:
| Unbroadcast IDs | GetUnbroadcastTxs().size() (ns/query) |
GetUnbroadcastTxCount()(ns/query) |
|---|---|---|
| 0 | 25.22 | 22.60 |
| 1 | 58.99 | 22.52 |
| 10 | 420.82 | 22.79 |
| 100 | 4,788.22 | 22.45 |
| 1,000 | 57,904.17 | 22.60 |
| 10,000 | 908,399.04 | 22.62 |
The copy cost grew with the set size, while the count accessor stayed approximately constant.