txpool: fix time_in_pool age calculation
What changed, and why it matters
This commit fixes a simple arithmetic bug in how long a transaction has been waiting in the memory pool ("time in pool") was calculated. The old code subtracted the current time from the receive time in the wrong order, which could produce a very large, nonsensical age value instead of a small positive number. The fix ensures the age is always the current time minus the receive time, or zero if the clock somehow runs backward. This is a correctness fix for statistics/ranking of pending transactions, not a direct funds-theft or code-execution vulnerability.
Merge the patch; it is a low-risk correctness fix. Review any downstream logic that uses the returned age (e.g., fee estimation, relay decisions) to confirm it was not relying on the bogus underflowed value. No emergency response is warranted.
Security signals we found
Integer underflow in age field due to reversed subtraction order
Incorrect metadata reported for mempool transactions
Potential skew of transaction backlog statistics / prioritization heuristics
Evidence from the diff
In tx_pool.cpp, get_transaction_backlog() builds a vector of pending tx metadata including weight, fee, and age. The original expression meta.receive_time - now reverses the operands, yielding a negative value represented as a large unsigned 64-bit integer (underflow). The patch computes now >= meta.receive_time ? now - meta.receive_time : 0, producing a sane unsigned age. This affects only the age field reported to callers such as RPC/CLI statistics and possibly fee/relay prioritization heuristics that rely on time-in-pool.
Changed components
src/cryptonote_core/tx_pool.cppget_transaction_backlog()txpool_tx_meta_t receive_time handlingInspect captured patch +2 / −1
diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp
index 4bc723a..1ad9230 100644
--- a/src/cryptonote_core/tx_pool.cpp
+++ b/src/cryptonote_core/tx_pool.cpp
@@ -1071,7 +1071,8 @@ namespace cryptonote
const relay_category category = include_sensitive ? relay_category::all : relay_category::broadcasted;
backlog.reserve(m_blockchain.get_txpool_tx_count(include_sensitive));
m_blockchain.for_all_txpool_txes([&backlog, now](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref *bd){
- backlog.push_back({meta.weight, meta.fee, meta.receive_time - now});
+ const uint64_t age = now >= meta.receive_time ? now - meta.receive_time : 0;
+ backlog.push_back({meta.weight, meta.fee, age});
return true;
}, false, category);
}
Why this scored 19/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.