Skip to content

Commit 7fd7e99

Browse files
committed
wallet: fix crash on double block disconnection
The wallet crashes if it processes the same block disconnection event twice due to an incompatible coinbase transaction state. This happens because 'disconnectBlock' provides 'TxStateInactive' without the "abandoned" flag for coinbase transactions, 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 0a931a9 commit 7fd7e99

File tree

1 file changed

+5
-2
lines changed

1 file changed

+5
-2
lines changed

src/wallet/wallet.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -1545,8 +1545,11 @@ void CWallet::blockDisconnected(const interfaces::BlockInfo& block)
15451545

15461546
int disconnect_height = block.height;
15471547

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

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

0 commit comments

Comments
 (0)