net: introduce TxSendStatus internal state container
What changed, and why it matters
This commit is a small internal code cleanup in Bitcoin Core's private transaction-broadcast feature. It wraps an existing list of per-peer send records inside a new 'TxSendStatus' container and adds a timestamp for when each transaction was first added. There is no change to network behavior, no bug fix, and no security-relevant change visible in the diff.
No security action required. Treat as ordinary refactoring/development commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch refactors PrivateBroadcast’s m_transactions map value type from std::vector
Changed components
src/private_broadcast.cppsrc/private_broadcast.hInspect captured patch +16 / −13
diff --git a/src/private_broadcast.cpp b/src/private_broadcast.cpp
index 3900f10a..ce42dfd8 100644
--- a/src/private_broadcast.cpp
+++ b/src/private_broadcast.cpp
@@ -25,7 +25,7 @@ std::optional<size_t> PrivateBroadcast::Remove(const CTransactionRef& tx)
LOCK(m_mutex);
const auto handle{m_transactions.extract(tx)};
if (handle) {
- const auto p{DerivePriority(handle.mapped())};
+ const auto p{DerivePriority(handle.mapped().send_statuses)};
return p.num_confirmed;
}
return std::nullopt;
@@ -39,11 +39,11 @@ std::optional<CTransactionRef> PrivateBroadcast::PickTxForSend(const NodeId& wil
const auto it{std::ranges::max_element(
m_transactions,
[](const auto& a, const auto& b) { return a < b; },
- [](const auto& el) { return DerivePriority(el.second); })};
+ [](const auto& el) { return DerivePriority(el.second.send_statuses); })};
if (it != m_transactions.end()) {
- auto& [tx, sent_to]{*it};
- sent_to.emplace_back(will_send_to_nodeid, will_send_to_address, NodeClock::now());
+ auto& [tx, state]{*it};
+ state.send_statuses.emplace_back(will_send_to_nodeid, will_send_to_address, NodeClock::now());
return tx;
}
@@ -95,8 +95,8 @@ std::vector<CTransactionRef> PrivateBroadcast::GetStale() const
LOCK(m_mutex);
const auto stale_time{NodeClock::now() - STALE_DURATION};
std::vector<CTransactionRef> stale;
- for (const auto& [tx, send_status] : m_transactions) {
- const Priority p{DerivePriority(send_status)};
+ for (const auto& [tx, state] : m_transactions) {
+ const Priority p{DerivePriority(state.send_statuses)};
if (p.last_confirmed < stale_time) {
stale.push_back(tx);
}
@@ -111,10 +111,10 @@ std::vector<PrivateBroadcast::TxBroadcastInfo> PrivateBroadcast::GetBroadcastInf
std::vector<TxBroadcastInfo> entries;
entries.reserve(m_transactions.size());
- for (const auto& [tx, sent_to] : m_transactions) {
+ for (const auto& [tx, state] : m_transactions) {
std::vector<PeerSendInfo> peers;
- peers.reserve(sent_to.size());
- for (const auto& status : sent_to) {
+ peers.reserve(state.send_statuses.size());
+ for (const auto& status : state.send_statuses) {
peers.emplace_back(PeerSendInfo{.address = status.address, .sent = status.picked, .received = status.confirmed});
}
entries.emplace_back(TxBroadcastInfo{.tx = tx, .peers = std::move(peers)});
@@ -141,8 +141,8 @@ std::optional<PrivateBroadcast::TxAndSendStatusForNode> PrivateBroadcast::GetSen
EXCLUSIVE_LOCKS_REQUIRED(m_mutex)
{
AssertLockHeld(m_mutex);
- for (auto& [tx, sent_to] : m_transactions) {
- for (auto& send_status : sent_to) {
+ for (auto& [tx, state] : m_transactions) {
+ for (auto& send_status : state.send_statuses) {
if (send_status.nodeid == nodeid) {
return TxAndSendStatusForNode{.tx = tx, .send_status = send_status};
}
diff --git a/src/private_broadcast.h b/src/private_broadcast.h
index 28634424..27f42166 100644
--- a/src/private_broadcast.h
+++ b/src/private_broadcast.h
@@ -177,9 +177,12 @@ private:
*/
std::optional<TxAndSendStatusForNode> GetSendStatusByNode(const NodeId& nodeid)
EXCLUSIVE_LOCKS_REQUIRED(m_mutex);
-
+ struct TxSendStatus {
+ const NodeClock::time_point time_added{NodeClock::now()};
+ std::vector<SendStatus> send_statuses;
+ };
mutable Mutex m_mutex;
- std::unordered_map<CTransactionRef, std::vector<SendStatus>, CTransactionRefHash, CTransactionRefComp>
+ std::unordered_map<CTransactionRef, TxSendStatus, CTransactionRefHash, CTransactionRefComp>
m_transactions GUARDED_BY(m_mutex);
};
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.