@@ -2134,8 +2134,7 @@ void CWallet::ReacceptWalletTransactions(interfaces::Chain::Lock& locked_chain)
2134
2134
std::map<int64_t , CWalletTx*> mapSorted;
2135
2135
2136
2136
// 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) {
2139
2138
const uint256& wtxid = item.first ;
2140
2139
CWalletTx& wtx = item.second ;
2141
2140
assert (wtx.GetHash () == wtxid);
@@ -2150,12 +2149,12 @@ void CWallet::ReacceptWalletTransactions(interfaces::Chain::Lock& locked_chain)
2150
2149
// Try to add wallet transactions to memory pool
2151
2150
for (const std::pair<const int64_t , CWalletTx*>& item : mapSorted) {
2152
2151
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 );
2155
2154
}
2156
2155
}
2157
2156
2158
- bool CWalletTx::RelayWalletTransaction ( interfaces::Chain::Lock& locked_chain)
2157
+ bool CWalletTx::SubmitMemoryPoolAndRelay (std::string& err_string, bool relay, interfaces::Chain::Lock& locked_chain)
2159
2158
{
2160
2159
// Can't relay if wallet is not broadcasting
2161
2160
if (!pwallet->GetBroadcastTransactions ()) return false ;
@@ -2165,17 +2164,21 @@ bool CWalletTx::RelayWalletTransaction(interfaces::Chain::Lock& locked_chain)
2165
2164
if (isAbandoned ()) return false ;
2166
2165
// Don't relay conflicted or already confirmed transactions
2167
2166
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 ());
2177
2167
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;
2179
2182
}
2180
2183
2181
2184
std::set<uint256> CWalletTx::GetConflicts () const
@@ -2366,7 +2369,7 @@ void CWallet::ResendWalletTransactions()
2366
2369
if (m_best_block_time < nLastResend) return ;
2367
2370
nLastResend = GetTime ();
2368
2371
2369
- int relayed_tx_count = 0 ;
2372
+ int submitted_tx_count = 0 ;
2370
2373
2371
2374
{ // locked_chain and cs_wallet scope
2372
2375
auto locked_chain = chain ().lock ();
@@ -2378,12 +2381,13 @@ void CWallet::ResendWalletTransactions()
2378
2381
// only rebroadcast unconfirmed txes older than 5 minutes before the
2379
2382
// last block was found
2380
2383
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;
2382
2386
}
2383
2387
} // locked_chain and cs_wallet
2384
2388
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 );
2387
2391
}
2388
2392
}
2389
2393
@@ -3322,12 +3326,10 @@ bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::ve
3322
3326
3323
3327
if (fBroadcastTransactions )
3324
3328
{
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 );
3328
3332
// 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);
3331
3333
}
3332
3334
}
3333
3335
}
@@ -4662,18 +4664,6 @@ bool CWalletTx::IsImmatureCoinBase(interfaces::Chain::Lock& locked_chain) const
4662
4664
return GetBlocksToMaturity (locked_chain) > 0 ;
4663
4665
}
4664
4666
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
-
4677
4667
void CWallet::LearnRelatedScripts (const CPubKey& key, OutputType type)
4678
4668
{
4679
4669
if (key.IsCompressed () && (type == OutputType::P2SH_SEGWIT || type == OutputType::BECH32)) {
0 commit comments