@@ -1857,34 +1857,6 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
1857
1857
return result;
1858
1858
}
1859
1859
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
-
1888
1860
bool CWallet::SubmitTxMemoryPoolAndRelay (CWalletTx& wtx, std::string& err_string, bool relay) const
1889
1861
{
1890
1862
AssertLockHeld (cs_wallet);
@@ -1925,43 +1897,69 @@ std::set<uint256> CWallet::GetTxConflicts(const CWalletTx& wtx) const
1925
1897
return result;
1926
1898
}
1927
1899
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.
1930
1912
//
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
1932
1914
// mined in the most recent block. Any transaction that wasn't in the top
1933
1915
// blockweight of transactions in the mempool shouldn't have been mined,
1934
1916
// and so is probably just sitting in the mempool waiting to be confirmed.
1935
1917
// Rebroadcasting does nothing to speed up confirmation and only damages
1936
1918
// 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)
1938
1926
{
1927
+ // Don't attempt to resubmit if the wallet is configured to not broadcast,
1928
+ // even if forcing.
1929
+ if (!fBroadcastTransactions ) return ;
1930
+
1939
1931
// During reindex, importing and IBD, old wallet transactions become
1940
1932
// 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 ;
1942
1935
1943
1936
// Do this infrequently and randomly to avoid giving away
1944
1937
// that these are our transactions.
1945
- if (GetTime () < nNextResend || !fBroadcastTransactions ) return ;
1946
- bool fFirst = (nNextResend == 0 );
1938
+ if (!force && GetTime () < nNextResend) return ;
1947
1939
// resend 12-36 hours from now, ~1 day on average.
1948
1940
nNextResend = GetTime () + (12 * 60 * 60 ) + GetRand (24 * 60 * 60 );
1949
- if (fFirst ) return ;
1950
1941
1951
1942
int submitted_tx_count = 0 ;
1952
1943
1953
1944
{ // cs_wallet scope
1954
1945
LOCK (cs_wallet);
1955
1946
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) {
1963
1961
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;
1965
1963
}
1966
1964
} // cs_wallet
1967
1965
@@ -1975,7 +1973,7 @@ void CWallet::ResendWalletTransactions()
1975
1973
void MaybeResendWalletTxs (WalletContext& context)
1976
1974
{
1977
1975
for (const std::shared_ptr<CWallet>& pwallet : GetWallets (context)) {
1978
- pwallet->ResendWalletTransactions ( );
1976
+ pwallet->ResubmitWalletTransactions ( /* relay= */ true , /* force= */ false );
1979
1977
}
1980
1978
}
1981
1979
@@ -3191,7 +3189,7 @@ void CWallet::postInitProcess()
3191
3189
3192
3190
// Add wallet transactions that aren't already in a block to mempool
3193
3191
// Do this here as mempool requires genesis block to be loaded
3194
- ReacceptWalletTransactions ( );
3192
+ ResubmitWalletTransactions ( /* relay= */ false , /* force= */ true );
3195
3193
3196
3194
// Update wallet transactions with current mempool transactions.
3197
3195
chain ().requestMempoolTransactions (*this );
0 commit comments