From c852cb0db9dfe594bdf3e0fede2db15e60a8e4ea Mon Sep 17 00:00:00 2001 From: j-berman Date: Mon, 29 Jun 2026 17:50:18 -0700 Subject: [PATCH] txpool: re-relay txs that haven't been relayed and need to be Fixes the following circumstance: 1. Wallet submits tx to node. 2. Node adds tx to pool and queues for relay. 3. Node shuts off before the relay executes in the strand. 4. Node restarts. 5. Now, the fix ensures the node will re-relay the tx in the get_relayable_transactions loop. Also makes sure that stem txs don't have last_relayed_time set to max, which would prevent them from ever being re-relayed on a restart as well. Context: https://github.com/seraphis-migration/monero/issues/365#issuecomment-4811722029 (cherry picked from commit aa13c6340f0d855d42aed1d9a8bebe76245e0e7c) --- src/cryptonote_core/tx_pool.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index 0b6c9c973..c70bde93a 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -300,9 +300,10 @@ namespace cryptonote { using clock = std::chrono::system_clock; auto last_relayed_time = std::numeric_limits::max(); - if (tx_relay == relay_method::forward) + if (tx_relay == relay_method::forward || tx_relay == relay_method::stem) { - last_relayed_time = clock::to_time_t(clock::now() + crypto::random_poisson_seconds{forward_delay_average}()); + const auto delay = tx_relay == relay_method::forward ? forward_delay_average : dandelionpp_embargo_average; + last_relayed_time = clock::to_time_t(clock::now() + crypto::random_poisson_seconds{delay}()); set_if_less(m_next_check, time_t(last_relayed_time)); } // else the `set_relayed` function will adjust the time accordingly later @@ -815,6 +816,8 @@ namespace cryptonote case relay_method::local: case relay_method::fluff: case relay_method::block: + if (!meta.relayed) + break; // if it hasn't been relayed yet, relay it if (now - meta.last_relayed_time <= get_relay_delay(meta.last_relayed_time, meta.receive_time)) return true; // continue to next tx break;