Skip to content

Commit 79cabe3

Browse files
committed
Merge bitcoin/bitcoin#25239: wallet: 'CommitTransaction', remove extra wtx lookup and add exception for db write error
57fb37c wallet: CommitTransaction, remove extra wtx lookup and add exception for a possible db write error. (furszy) Pull request description: Two points for `CWallet::CommitTransaction`: 1) The extra wtx lookup: As we are calling to `AddToWallet` first, which returns the recently added/updated wtx pointer, there is no need to look up the wtx again few lines later. We can just use it. 2) The db write error: `AddToWallet` can only return a nullptr if the db write fails, which inside `CommitTransaction` translates to an exception throw cause. We expect everywhere that `CommitTransaction` always succeed. ------------------------------------------------ Extra note: This finding generated another working path for me :) It starts with the following question: why are we returning a nullptr from `AddToWallet` if the db write failed without removing the recently added transaction from the wallet's map?.. Can led to a wallet invalid state where the inputs of this new transaction are not marked dirty, while the transaction that spends them still exist on the in-memory wallet tx map. -- I'm writing it here to gather some feedback first and not forget it, will create a follow-up PR in the coming days 🚜 -- ACKs for top commit: achow101: ACK 57fb37c jonatack: ACK 57fb37c ryanofsky: Code review ACK 57fb37c. Seems like a clear improvement. Better to fail earlier with a better error message if the failure is going to happen anyway Tree-SHA512: 80e59c01852cfbbc70a5de1a1c2c59b5e572f9eaa08c2175112cb515256e63fa04c7942f92a513b620d6b06e66392029ebe8902287c456efdbee58a7a5ae42da
2 parents e282764 + 57fb37c commit 79cabe3

File tree

1 file changed

+7
-6
lines changed

1 file changed

+7
-6
lines changed

src/wallet/wallet.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2106,7 +2106,7 @@ void CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::ve
21062106

21072107
// Add tx to wallet, because if it has change it's also ours,
21082108
// otherwise just for transaction history.
2109-
AddToWallet(tx, TxStateInactive{}, [&](CWalletTx& wtx, bool new_tx) {
2109+
CWalletTx* wtx = AddToWallet(tx, TxStateInactive{}, [&](CWalletTx& wtx, bool new_tx) {
21102110
CHECK_NONFATAL(wtx.mapValue.empty());
21112111
CHECK_NONFATAL(wtx.vOrderForm.empty());
21122112
wtx.mapValue = std::move(mapValue);
@@ -2116,24 +2116,25 @@ void CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::ve
21162116
return true;
21172117
});
21182118

2119+
// wtx can only be null if the db write failed.
2120+
if (!wtx) {
2121+
throw std::runtime_error(std::string(__func__) + ": Wallet db error, transaction commit failed");
2122+
}
2123+
21192124
// Notify that old coins are spent
21202125
for (const CTxIn& txin : tx->vin) {
21212126
CWalletTx &coin = mapWallet.at(txin.prevout.hash);
21222127
coin.MarkDirty();
21232128
NotifyTransactionChanged(coin.GetHash(), CT_UPDATED);
21242129
}
21252130

2126-
// Get the inserted-CWalletTx from mapWallet so that the
2127-
// wtx cached mempool state is updated correctly
2128-
CWalletTx& wtx = mapWallet.at(tx->GetHash());
2129-
21302131
if (!fBroadcastTransactions) {
21312132
// Don't submit tx to the mempool
21322133
return;
21332134
}
21342135

21352136
std::string err_string;
2136-
if (!SubmitTxMemoryPoolAndRelay(wtx, err_string, true)) {
2137+
if (!SubmitTxMemoryPoolAndRelay(*wtx, err_string, true)) {
21372138
WalletLogPrintf("CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", err_string);
21382139
// TODO: if we expect the failure to be long term or permanent, instead delete wtx from the wallet and return failure.
21392140
}

0 commit comments

Comments
 (0)