@@ -1857,34 +1857,6 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
18571857 return result;
18581858}
18591859
1860- void CWallet::ReacceptWalletTransactions ()
1861- {
1862- // If transactions aren't being broadcasted, don't let them into local mempool either
1863- if (!fBroadcastTransactions )
1864- return ;
1865- std::map<int64_t , CWalletTx*> mapSorted;
1866-
1867- // Sort pending wallet transactions based on their initial wallet insertion order
1868- for (std::pair<const uint256, CWalletTx>& item : mapWallet) {
1869- const uint256& wtxid = item.first ;
1870- CWalletTx& wtx = item.second ;
1871- assert (wtx.GetHash () == wtxid);
1872-
1873- int nDepth = GetTxDepthInMainChain (wtx);
1874-
1875- if (!wtx.IsCoinBase () && (nDepth == 0 && !wtx.isAbandoned ())) {
1876- mapSorted.insert (std::make_pair (wtx.nOrderPos , &wtx));
1877- }
1878- }
1879-
1880- // Try to add wallet transactions to memory pool
1881- for (const std::pair<const int64_t , CWalletTx*>& item : mapSorted) {
1882- CWalletTx& wtx = *(item.second );
1883- std::string unused_err_string;
1884- SubmitTxMemoryPoolAndRelay (wtx, unused_err_string, false );
1885- }
1886- }
1887-
18881860bool CWallet::SubmitTxMemoryPoolAndRelay (CWalletTx& wtx, std::string& err_string, bool relay) const
18891861{
18901862 AssertLockHeld (cs_wallet);
@@ -1925,43 +1897,69 @@ std::set<uint256> CWallet::GetTxConflicts(const CWalletTx& wtx) const
19251897 return result;
19261898}
19271899
1928- // Rebroadcast transactions from the wallet. We do this on a random timer
1929- // to slightly obfuscate which transactions come from our wallet.
1900+ // Resubmit transactions from the wallet to the mempool, optionally asking the
1901+ // mempool to relay them. On startup, we will do this for all unconfirmed
1902+ // transactions but will not ask the mempool to relay them. We do this on startup
1903+ // to ensure that our own mempool is aware of our transactions, and to also
1904+ // initialize nNextResend so that the actual rebroadcast is scheduled. There
1905+ // is a privacy side effect here as not broadcasting on startup also means that we won't
1906+ // inform the world of our wallet's state, particularly if the wallet (or node) is not
1907+ // yet synced.
1908+ //
1909+ // Otherwise this function is called periodically in order to relay our unconfirmed txs.
1910+ // We do this on a random timer to slightly obfuscate which transactions
1911+ // come from our wallet.
19301912//
1931- // Ideally, we'd only resend transactions that we think should have been
1913+ // TODO: Ideally, we'd only resend transactions that we think should have been
19321914// mined in the most recent block. Any transaction that wasn't in the top
19331915// blockweight of transactions in the mempool shouldn't have been mined,
19341916// and so is probably just sitting in the mempool waiting to be confirmed.
19351917// Rebroadcasting does nothing to speed up confirmation and only damages
19361918// privacy.
1937- void CWallet::ResendWalletTransactions ()
1919+ //
1920+ // The `force` option results in all unconfirmed transactions being submitted to
1921+ // the mempool. This does not necessarily result in those transactions being relayed,
1922+ // that depends on the `relay` option. Periodic rebroadcast uses the pattern
1923+ // relay=true force=false (also the default values), while loading into the mempool
1924+ // (on start, or after import) uses relay=false force=true.
1925+ void CWallet::ResubmitWalletTransactions (bool relay, bool force)
19381926{
1927+ // Don't attempt to resubmit if the wallet is configured to not broadcast,
1928+ // even if forcing.
1929+ if (!fBroadcastTransactions ) return ;
1930+
19391931 // During reindex, importing and IBD, old wallet transactions become
19401932 // unconfirmed. Don't resend them as that would spam other nodes.
1941- if (!chain ().isReadyToBroadcast ()) return ;
1933+ // We only allow forcing mempool submission when not relaying to avoid this spam.
1934+ if (!force && relay && !chain ().isReadyToBroadcast ()) return ;
19421935
19431936 // Do this infrequently and randomly to avoid giving away
19441937 // that these are our transactions.
1945- if (GetTime () < nNextResend || !fBroadcastTransactions ) return ;
1946- bool fFirst = (nNextResend == 0 );
1938+ if (!force && GetTime () < nNextResend) return ;
19471939 // resend 12-36 hours from now, ~1 day on average.
19481940 nNextResend = GetTime () + (12 * 60 * 60 ) + GetRand (24 * 60 * 60 );
1949- if (fFirst ) return ;
19501941
19511942 int submitted_tx_count = 0 ;
19521943
19531944 { // cs_wallet scope
19541945 LOCK (cs_wallet);
19551946
1956- // Relay transactions
1957- for (std::pair<const uint256, CWalletTx>& item : mapWallet) {
1958- CWalletTx& wtx = item.second ;
1959- // Attempt to rebroadcast all txes more than 5 minutes older than
1960- // the last block. SubmitTxMemoryPoolAndRelay() will not rebroadcast
1961- // any confirmed or conflicting txs.
1962- if (wtx.nTimeReceived > m_best_block_time - 5 * 60 ) continue ;
1947+ // First filter for the transactions we want to rebroadcast.
1948+ // We use a set with WalletTxOrderComparator so that rebroadcasting occurs in insertion order
1949+ std::set<CWalletTx*, WalletTxOrderComparator> to_submit;
1950+ for (auto & [txid, wtx] : mapWallet) {
1951+ // Only rebroadcast unconfirmed txs
1952+ if (!wtx.isUnconfirmed ()) continue ;
1953+
1954+ // attempt to rebroadcast all txes more than 5 minutes older than
1955+ // the last block, or all txs if forcing.
1956+ if (!force && wtx.nTimeReceived > m_best_block_time - 5 * 60 ) continue ;
1957+ to_submit.insert (&wtx);
1958+ }
1959+ // Now try submitting the transactions to the memory pool and (optionally) relay them.
1960+ for (auto wtx : to_submit) {
19631961 std::string unused_err_string;
1964- if (SubmitTxMemoryPoolAndRelay (wtx, unused_err_string, true )) ++submitted_tx_count;
1962+ if (SubmitTxMemoryPoolAndRelay (* wtx, unused_err_string, relay )) ++submitted_tx_count;
19651963 }
19661964 } // cs_wallet
19671965
@@ -1975,7 +1973,7 @@ void CWallet::ResendWalletTransactions()
19751973void MaybeResendWalletTxs (WalletContext& context)
19761974{
19771975 for (const std::shared_ptr<CWallet>& pwallet : GetWallets (context)) {
1978- pwallet->ResendWalletTransactions ( );
1976+ pwallet->ResubmitWalletTransactions ( /* relay= */ true , /* force= */ false );
19791977 }
19801978}
19811979
@@ -3191,7 +3189,7 @@ void CWallet::postInitProcess()
31913189
31923190 // Add wallet transactions that aren't already in a block to mempool
31933191 // Do this here as mempool requires genesis block to be loaded
3194- ReacceptWalletTransactions ( );
3192+ ResubmitWalletTransactions ( /* relay= */ false , /* force= */ true );
31953193
31963194 // Update wallet transactions with current mempool transactions.
31973195 chain ().requestMempoolTransactions (*this );
0 commit comments