Problem
When BroadcastTransaction is invoked with TxBroadcast::MEMPOOL_AND_BROADCAST_TO_ALL (via send, sendtoaddress, or sendrawtransaction) for a transaction that is already admitted to the mempool (for example, loaded from mempool.dat on node startup/restart, or resubmitted by wallet/RPC), it previously skipped tracking the transaction in m_unbroadcast_txids.
If initial P2P broadcast attempts failed because outbound peers had not yet established connections during node restart, the transaction was never retried via ReattemptInitialBroadcast(), leaving locally submitted wallet/RPC transactions in an unbroadcast state indefinitely even while appearing as InMempool.
Solution
In src/node/transaction.cpp:
- When
mempool->get(txid)succeeds duringBroadcastTransaction, ifbroadcast_method == TxBroadcast::MEMPOOL_AND_BROADCAST_TO_ALL, callnode.mempool->AddUnbroadcastTx(txid).
Testing
- Added deterministic functional test
test/functional/wallet_restart_mempool_unbroadcast.pyreproducing the exact startup race with persisted mempool and verifying transaction delivery upon subsequent peer connection. - Updated
test/functional/mempool_unbroadcast.pyto assert that rebroadcasting an existing transaction tracks it in the unbroadcast set until delivered to peers. - Ran all 819 unit test cases (
test_bitcoin) and relevant functional tests (mempool_unbroadcast.py,wallet_restart_mempool_unbroadcast.py,mempool_persist.py,wallet_resendwallettransactions.py,mempool_packages.py,mempool_accept_wtxid.py).
Fixes #35589.