Skip to content

Commit 611291c

Browse files
author
Antoine Riard
committed
Introduce CWalletTx::SubmitMemoryPoolAndRelay
Higher wallet-tx method combining RelayWalletTransactions and AcceptToMemoryPool, using new Chain::broadcastTransaction
1 parent 8c8aa19 commit 611291c

File tree

2 files changed

+28
-41
lines changed

2 files changed

+28
-41
lines changed

src/wallet/wallet.cpp

Lines changed: 26 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -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

21812184
std::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-
46774667
void CWallet::LearnRelatedScripts(const CPubKey& key, OutputType type)
46784668
{
46794669
if (key.IsCompressed() && (type == OutputType::P2SH_SEGWIT || type == OutputType::BECH32)) {

src/wallet/wallet.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -579,11 +579,8 @@ class CWalletTx
579579

580580
int64_t GetTxTime() const;
581581

582-
// Pass this transaction to the node to relay to its peers
583-
bool RelayWalletTransaction(interfaces::Chain::Lock& locked_chain);
584-
585-
/** Pass this transaction to the mempool. Fails if absolute fee exceeds absurd fee. */
586-
bool AcceptToMemoryPool(interfaces::Chain::Lock& locked_chain, CValidationState& state);
582+
// Pass this transaction to node for mempool insertion and relay to peers if flag set to true
583+
bool SubmitMemoryPoolAndRelay(std::string& err_string, bool relay, interfaces::Chain::Lock& locked_chain);
587584

588585
// TODO: Remove "NO_THREAD_SAFETY_ANALYSIS" and replace it with the correct
589586
// annotation "EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)". The annotation

0 commit comments

Comments
 (0)