Skip to content

Commit 9ef429b

Browse files
committed
wallet: fix crash on double block disconnection
The wallet crashes if it processes the same block disconnection event twice in a row due to an incompatible coinbase transaction state. This happens because 'disconnectBlock' provides 'TxStateInactive' without the "abandoned" flag for coinbase transactions to 'SyncTransaction', while 'AddToWallet()' internally modifies it to retain the abandoned state. The flow is as follows: 1) On the first disconnection, the transaction state transitions from "confirmed" to "inactive," bypassing the state equality check since the provided state differs. Then, 'AddToWallet' internally updates the state to "inactive + abandoned" 2) On the second disconnection, as we provide only the "inactive" state to 'SyncTransaction()', the state equality assertion fails and crashes the wallet.
1 parent 785649f commit 9ef429b

File tree

1 file changed

+5
-2
lines changed

1 file changed

+5
-2
lines changed

src/wallet/wallet.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,8 +1548,11 @@ void CWallet::blockDisconnected(const interfaces::BlockInfo& block)
15481548

15491549
int disconnect_height = block.height;
15501550

1551-
for (const CTransactionRef& ptx : Assert(block.data)->vtx) {
1552-
SyncTransaction(ptx, TxStateInactive{});
1551+
for (size_t index = 0; index < block.data->vtx.size(); index++) {
1552+
const CTransactionRef& ptx = Assert(block.data)->vtx[index];
1553+
// Coinbase transactions are not only inactive but also abandoned,
1554+
// meaning they should never be relayed standalone via the p2p protocol.
1555+
SyncTransaction(ptx, TxStateInactive{/*abandoned=*/index == 0});
15531556

15541557
for (const CTxIn& tx_in : ptx->vin) {
15551558
// No other wallet transactions conflicted with this transaction

0 commit comments

Comments
 (0)