@@ -2134,8 +2134,7 @@ void CWallet::ReacceptWalletTransactions(interfaces::Chain::Lock& locked_chain)
21342134 std::map<int64_t , CWalletTx*> mapSorted;
21352135
21362136 // Sort pending wallet transactions based on their initial wallet insertion order
2137- for (std::pair<const uint256, CWalletTx>& item : mapWallet)
2138- {
2137+ for (std::pair<const uint256, CWalletTx>& item : mapWallet) {
21392138 const uint256& wtxid = item.first ;
21402139 CWalletTx& wtx = item.second ;
21412140 assert (wtx.GetHash () == wtxid);
@@ -2150,12 +2149,12 @@ void CWallet::ReacceptWalletTransactions(interfaces::Chain::Lock& locked_chain)
21502149 // Try to add wallet transactions to memory pool
21512150 for (const std::pair<const int64_t , CWalletTx*>& item : mapSorted) {
21522151 CWalletTx& wtx = *(item.second );
2153- CValidationState state ;
2154- wtx.AcceptToMemoryPool (locked_chain, state );
2152+ std::string unused_err_string ;
2153+ wtx.SubmitMemoryPoolAndRelay (unused_err_string, false , locked_chain );
21552154 }
21562155}
21572156
2158- bool CWalletTx::RelayWalletTransaction ( interfaces::Chain::Lock& locked_chain)
2157+ bool CWalletTx::SubmitMemoryPoolAndRelay (std::string& err_string, bool relay, interfaces::Chain::Lock& locked_chain)
21592158{
21602159 // Can't relay if wallet is not broadcasting
21612160 if (!pwallet->GetBroadcastTransactions ()) return false ;
@@ -2165,17 +2164,21 @@ bool CWalletTx::RelayWalletTransaction(interfaces::Chain::Lock& locked_chain)
21652164 if (isAbandoned ()) return false ;
21662165 // Don't relay conflicted or already confirmed transactions
21672166 if (GetDepthInMainChain (locked_chain) != 0 ) return false ;
2168- // Don't relay transactions that aren't accepted to the mempool
2169- CValidationState unused_state;
2170- if (!InMempool () && !AcceptToMemoryPool (locked_chain, unused_state)) return false ;
2171- // Don't try to relay if the node is not connected to the p2p network
2172- if (!pwallet->chain ().p2pEnabled ()) return false ;
2173-
2174- // Try to relay the transaction
2175- pwallet->WalletLogPrintf (" Relaying wtx %s\n " , GetHash ().ToString ());
2176- pwallet->chain ().relayTransaction (GetHash ());
21772167
2178- return true ;
2168+ // Submit transaction to mempool for relay
2169+ pwallet->WalletLogPrintf (" Submitting wtx %s to mempool for relay\n " , GetHash ().ToString ());
2170+ // We must set fInMempool here - while it will be re-set to true by the
2171+ // entered-mempool callback, if we did not there would be a race where a
2172+ // user could call sendmoney in a loop and hit spurious out of funds errors
2173+ // because we think that this newly generated transaction's change is
2174+ // unavailable as we're not yet aware that it is in the mempool.
2175+ //
2176+ // Irrespective of the failure reason, un-marking fInMempool
2177+ // out-of-order is incorrect - it should be unmarked when
2178+ // TransactionRemovedFromMempool fires.
2179+ bool ret = pwallet->chain ().broadcastTransaction (tx, err_string, pwallet->m_default_max_tx_fee , relay);
2180+ fInMempool |= ret;
2181+ return ret;
21792182}
21802183
21812184std::set<uint256> CWalletTx::GetConflicts () const
@@ -2366,7 +2369,7 @@ void CWallet::ResendWalletTransactions()
23662369 if (m_best_block_time < nLastResend) return ;
23672370 nLastResend = GetTime ();
23682371
2369- int relayed_tx_count = 0 ;
2372+ int submitted_tx_count = 0 ;
23702373
23712374 { // locked_chain and cs_wallet scope
23722375 auto locked_chain = chain ().lock ();
@@ -2378,12 +2381,13 @@ void CWallet::ResendWalletTransactions()
23782381 // only rebroadcast unconfirmed txes older than 5 minutes before the
23792382 // last block was found
23802383 if (wtx.nTimeReceived > m_best_block_time - 5 * 60 ) continue ;
2381- if (wtx.RelayWalletTransaction (*locked_chain)) ++relayed_tx_count;
2384+ std::string unused_err_string;
2385+ if (wtx.SubmitMemoryPoolAndRelay (unused_err_string, true , *locked_chain)) ++submitted_tx_count;
23822386 }
23832387 } // locked_chain and cs_wallet
23842388
2385- if (relayed_tx_count > 0 ) {
2386- WalletLogPrintf (" %s: rebroadcast %u unconfirmed transactions\n " , __func__, relayed_tx_count );
2389+ if (submitted_tx_count > 0 ) {
2390+ WalletLogPrintf (" %s: resubmit %u unconfirmed transactions\n " , __func__, submitted_tx_count );
23872391 }
23882392}
23892393
@@ -3322,12 +3326,10 @@ bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::ve
33223326
33233327 if (fBroadcastTransactions )
33243328 {
3325- // Broadcast
3326- if (!wtx.AcceptToMemoryPool (*locked_chain, state )) {
3327- WalletLogPrintf (" CommitTransaction(): Transaction cannot be broadcast immediately, %s\n " , FormatStateMessage (state) );
3329+ std::string err_string;
3330+ if (!wtx.SubmitMemoryPoolAndRelay (err_string, true , *locked_chain )) {
3331+ WalletLogPrintf (" CommitTransaction(): Transaction cannot be broadcast immediately, %s\n " , err_string );
33283332 // TODO: if we expect the failure to be long term or permanent, instead delete wtx from the wallet and return failure.
3329- } else {
3330- wtx.RelayWalletTransaction (*locked_chain);
33313333 }
33323334 }
33333335 }
@@ -4662,18 +4664,6 @@ bool CWalletTx::IsImmatureCoinBase(interfaces::Chain::Lock& locked_chain) const
46624664 return GetBlocksToMaturity (locked_chain) > 0 ;
46634665}
46644666
4665- bool CWalletTx::AcceptToMemoryPool (interfaces::Chain::Lock& locked_chain, CValidationState& state)
4666- {
4667- // We must set fInMempool here - while it will be re-set to true by the
4668- // entered-mempool callback, if we did not there would be a race where a
4669- // user could call sendmoney in a loop and hit spurious out of funds errors
4670- // because we think that this newly generated transaction's change is
4671- // unavailable as we're not yet aware that it is in the mempool.
4672- bool ret = locked_chain.submitToMemoryPool (tx, pwallet->m_default_max_tx_fee , state);
4673- fInMempool |= ret;
4674- return ret;
4675- }
4676-
46774667void CWallet::LearnRelatedScripts (const CPubKey& key, OutputType type)
46784668{
46794669 if (key.IsCompressed () && (type == OutputType::P2SH_SEGWIT || type == OutputType::BECH32)) {
0 commit comments