Skip to content

wallet: call SyncWithValidationInterfaceQueue after disconnecting chain notifications#34642

Merged
sedited merged 2 commits intobitcoin:masterfrom
achow101:failed-load-blockconnected-race
Mar 2, 2026
Merged

wallet: call SyncWithValidationInterfaceQueue after disconnecting chain notifications#34642
sedited merged 2 commits intobitcoin:masterfrom
achow101:failed-load-blockconnected-race

Conversation

@achow101
Copy link
Member

@achow101 achow101 commented Feb 20, 2026

When the wallet disconnects chain notifications, it is expecting no further notifications to execute, but this is not the case. This results in test failures such as in #34354. Instead of disconnecting the notifications and continuing shutdown, we should wait for the validation interface queue to be drained before the rest of wallet shutdown. This is achieved by adding an interfaces::Chain::waitForNotifications() function which calls SyncWithValidationInterfaceQueue().

Fixes #34354

@DrahtBot
Copy link
Contributor

DrahtBot commented Feb 20, 2026

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK furszy, stickies-v, rkrux, sedited

If your review is incorrectly listed, please copy-paste <!--meta-tag:bot-skip--> into the comment that the bot should ignore.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #33034 (wallet: Store transactions in a separate sqlite table by achow101)
  • #32895 (wallet: Prepare for future upgrades by recording versions of last client to open and decrypt by achow101)
  • #32489 (wallet: Add exportwatchonlywallet RPC to export a watchonly version of a wallet by achow101)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

Copy link
Contributor

@stickies-v stickies-v left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK

@achow101 achow101 force-pushed the failed-load-blockconnected-race branch from 563ec53 to c010fe8 Compare February 26, 2026 21:14
Copy link
Member

@furszy furszy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current approach has a downside during IBD, any wallet unload during IBD could stall for hours because notification will keep coming. This wouldn't be much a deal for an RPC thread but for the GUI, this would totally freeze the app.

What we can do instead, is to unregister the wallet from the validation interface and submit a blocking task to the interface, so that we only wait up until the pending notifications gets cleared, and nothing else. Then we continue shutdown etc.

I implemented it here furszy@bf1abcd. All yours (haven't tested it).

If we want more concurrency in the future, instead of waiting for the queue to drain, we can submit the remaining unload steps into the validation interface so they are executed only after the pending tasks get processed. I didn't do it because it would require further changes that don't think they are acceptable for the release freeze period.

@achow101
Copy link
Member Author

submit a blocking task to the interface, so that we only wait up until the pending notifications gets cleared, and nothing else. Then we continue shutdown etc.

Isn't that what SyncWithValidationInterfaceQueue does? It also calls CallFunctionInValidationInterfaceQueue, but with std::promise, and then it wait()s on that future.

@furszy
Copy link
Member

furszy commented Feb 26, 2026

Isn't that what SyncWithValidationInterfaceQueue does? It also calls CallFunctionInValidationInterfaceQueue, but with std::promise, and then it wait()s on that future.

ha yeah.. nvm. Bad brain, dunno why I was completely convinced it was waiting until the queue was empty instead 🤷🏼‍♂️.

Copy link
Member

@furszy furszy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK c010fe8

@DrahtBot DrahtBot requested a review from stickies-v February 26, 2026 23:19
Copy link
Contributor

@stickies-v stickies-v left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

crACK c010fe8

PR description needs to be updated after the changed approach.

Waiting for the chain notifications to be processed makes the wallet shutdown more correct, but also slower. In most cases this seems harmless, but I did not test if there are edge cases (e.g. IBD, multiple wallets, a somehow clogged up/slow validation queue) where this can be problematic.

achow101 and others added 2 commits February 27, 2026 12:16
…rfaceQueue()

Co-Authored-By: stickies-v <stickies-v@protonmail.com>
When unloading a wallet, there may be unexecuted callbacks in the
validation interface queue that can still execute after we have
completed all of the other wallet shutdown tasks. Instead of letting
these run in the background, once the notifications are disconnected,
wait for the queue to drain before continuing with wallet shutdown.
@achow101 achow101 force-pushed the failed-load-blockconnected-race branch from c010fe8 to 98e8af4 Compare February 27, 2026 20:16
Copy link
Member

@furszy furszy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 98e8af4

@DrahtBot DrahtBot requested a review from stickies-v February 28, 2026 00:12
@stickies-v
Copy link
Contributor

utACK 98e8af4

Copy link
Contributor

@rkrux rkrux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

crACK 98e8af4

This makes the wallet unloading / shutdown operation more robust albeit slower (specially in case of multiple wallets loaded), which I don't mind. I'd prefer consistent & slow(er) operations over brittle & fast(er) ones.

I too feel that the waiting portion can be encapsulated within the disconnect function, but can be addressed later.

Copy link
Contributor

@sedited sedited left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 98e8af4

@sedited sedited merged commit 2702711 into bitcoin:master Mar 2, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test wallet_assumeutxo.py / wallet_backup.py is failing intermittently: wallet.cpp:543 RestoreWallet Assertion `fs::is_empty(wallet_path)' failed.

6 participants