#33117 Interfaces: Expose UTXO Snapshot Loading and Add Progress Notifications

ReviewabilityReviewsAgreementSize
#33117 D33r-Gee Interfaces: Expose UTXO Snapshot Loading and Add Progress NotificationsReady0 (+1)Strong126 + 2 tests
  • Allow GUI frontends and multiprocess clients to initiate UTXO snapshot loading
  • Provide user progress feedback while snapshot coins are validated and populated
  • Ready to review
  • Strong support with no remaining objections after rebases and refactoring
  • Verified by testing mainnet snapshot loads with downstream GUI branches (pinheadmz, Sjors)
  • Resolved objection: passing file handles across IPC boundaries complicates separation (ryanofsky)
  • Resolved objection: signaling progress per coin would fire over 100 million times (pinheadmz)
  • 126 lines added or modified outside tests
  • 2 lines added or modified in tests
  • 21 lines removed in total
  • 10 files, 3 commits
IPC / multiprocess#13 of 18
P2 · new feature
  • P2 because it unblocks assumeutxo snapshot loading across process boundaries
  • Directly enables downstream GUI implementations to load snapshots with progress feedback
RPC / REST / ZMQ#41 of 55
P3 · cleanup
  • P3 because the RPC refactor primarily exists to provide test coverage for the new interface
  • Changes failure error codes to internal errors, which could affect external automation
  • Ranking pass: Moved down 8: the RPC-visible part is a refactor plus an error-code change; its payoff is in GUI drafts outside this category.
Reviewability: ReadyStalePaused
Agreement: StrongPositivePositive w/ caveatsNeutralMildDisputedBlockedCrickets
Reviews: current code-review ACKs, then (+stale ACKs) and -NACKs; greener = more ACKs.
Size: lines added or modified outside tests, then in tests; greener = smaller.

Goal

Exposes assumeutxo snapshot loading and metadata access via a new `interfaces::Snapshot` class on `interfaces::Node`, and introduces a progress notification signal during snapshot population. It refactors the `loadtxoutset` RPC to delegate file opening, parsing, and activation through this interface instead of calling internal chainstate methods directly.

Problem: UTXO snapshot loading is tied directly to `ChainstateManager` and internal file helpers inside the `loadtxoutset` RPC handler without an interface abstraction. GUI frontends and multiprocess clients cannot initiate snapshot loading or display progress as coins are validated and populated into the chainstate.

Evidence of importance:

  • PR description: 'This PR implements a complete interface for loading UTXO snapshots through the GUI, including progress notifications to provide user feedback during the loading process.'
  • PR description links to GUI implementations: bitcoin-core/gui#870 and bitcoin-core/gui-qml#488

Scope: Note that error codes returned by `loadtxoutset` for file-opening and metadata-parsing failures change from `RPC_INVALID_PARAMETER` (-8) and `RPC_DESERIALIZATION_ERROR` (-22) to `RPC_INTERNAL_ERROR` (-32603), as reflected in the updated functional test.

Risk of a mistake: medium (validation, rpc_api, gui). A flaw in snapshot activation forwarding or progress signaling could abort UTXO snapshot loading or alter RPC error codes expected by existing automation.

Changed since the previous assessment: Unified error reporting in the `loadtxoutset` RPC handler to consistently return `RPC_INTERNAL_ERROR` for failures during activation, updating `feature_assumeutxo.py` assertions accordingly.

Reviewability

Ready

Nothing known that would invalidate a review now.

Waiting on (from the thread read):

  • reviewer: re-review from reviewers following the refactor and recent rebases 2026-09-24
  • reviewer: review of the refactored snapshot interface and latest rebase 2026-09-24

Agreement

Strong

substantive support, no open objection (pinheadmz, Sjors, pinheadmz)

Thread notes: Added Sjors' suggestion to cover the interface via RPC. All raised objections regarding IPC boundaries, progress notification frequency, and redundant RPC metadata parsing have been addressed and fixed. / Added Sjors' suggestion to cover the interface via loadtxoutset RPC. All objections and suggestions have been addressed and the author completed the requested rebases.

Objections, suggestions, and questions:

ReviewerTypeHarm, request, or questionStatusMust beAuthor repliedQuote
ryanofsky (member)objection, interfacePassing an AutoFile across process boundaries complicates IPC and lacks clean separation between GUI and nodeaccepted · fix pushed · author refactored to pass fs::path, which reviewer approvedansweredyes2025-08-01: 'if the GUI & node are running in separate processes, it could be a awkward for the gui process to create an AutoFile object and pass it to the node like this.'
Status from: 2025-08-04: ryanofsky: 'I think b464f388197c5c31937d309d817d38c4b4849a91 is an improvement over previous de11e3b89f8aba9a90a3419086807e5fee0f941'
Sjors (member)suggestion, approachUse the new snapshot interface in the loadtxoutset RPC to add test coveragefixed · fix pushed · implemented in 30d9bdb and confirmed inlineansweredyes2025-09-08: 'a good way to add test coverage to this new interface would be to use it in the `loadtxoutset` RPC.'
Status from: 2025-09-15: D33r-Gee: 'refactored `loadtxoutset` to utilize the new `snapshot` interface...'
pinheadmz (member)objection, correctnessSignaling progress updates per coin will fire over 100 million times on mainnetfixed · fix pushed · progress updates batched every 100k coinsansweredyes2026-01-20: 'This will fire 100 million times during a mainnet snapshot load. Is that overkill?'
Status from: 2026-02-25: D33r-Gee: 'addressed the snapshot load progress notification to batch progress updates for every 100,000 coins processed'
pinheadmz (member)objection, approachRedundant file open and metadata parse in the RPC handler duplicates activate()fixed · fix pushed · duplication removed in refactor returning util::Result from activate()answeredyes2026-04-17: 'If the file can't be opened for reading, or metadata can't be parsed, won't that come up in `activate()` on line 3433?'
Status from: 2026-06-02: D33r-Gee: 'Yes! That duplication is gone in af0c253. File open, metadata parse, and activation all live in SnapshotImpl::activate()'

Support:

  • pinheadmz (member) (Concept ACK, 2025-08-05) [tested: gui-qml]: tested the mainnet snapshot load with the QML gui branch built on top of this
  • sedited (member) (Approach ACK, 2025-09-08): Approach ACK [not substantive]
  • Sjors (member) (2025-09-08) [both: gui, src/node/interfaces.cpp]: At first glance this looks very reasonable. I also tested it in the (current) GUI with https://github.com/bitcoin-core/gui/pull/870
  • pinheadmz (member) (ACK, 2026-01-20) [read: interfaces, loadtxoutset RPC]: The new interface and signal handlers are fairly straight-forward and follow existing patterns. Consuming the new interface in the `loadtxoutset` RPC ensures it is covered by tests.

Participants:

  • Sjors (member, support, 3 statements 2025-08-01 to 2025-09-08): tested with legacy GUI; suggested covering new interface via loadtxoutset RPC
  • ryanofsky (member, objection, 2 statements 2025-08-01 to 2025-08-04): objected to passing AutoFile across process boundaries; accepted path-based interface refactor
  • pinheadmz (member, support, 10 statements 2025-08-05 to 2026-04-17): Concept ACK and code review ACK; raised progress notification frequency and RPC redundancy which were fixed
  • fanquake (member, neutral, 2 statements 2025-08-06 to 2026-06-01): reported CI build failure and asked for inline replies to review comments
  • sedited (member, support, 2 statements 2025-09-08 to 2026-08-10): Approach ACK and requested a rebase

Dependencies

Files

4 lines under test/bench/ci.

  • src/node/interfaces.cpp +55/-0
  • src/interfaces/snapshot.h +36/-0
  • src/rpc/blockchain.cpp +9/-19
  • src/interfaces/node.h +9/-0
  • src/validation.cpp +6/-0
  • src/node/kernel_notifications.cpp +5/-0
  • test/functional/feature_assumeutxo.py +2/-2
  • src/node/interface_ui.h +3/-0
  • src/node/kernel_notifications.h +2/-0
  • src/kernel/notifications_interface.h +1/-0

Card

The short text the ranking pass compares across PRs.

Adds a Snapshot interface to interfaces::Node and introduces a progress notification signal during UTXO snapshot loading. This enables external clients, such as GUI frontends and IPC wrappers, to initiate assumeutxo snapshot activation and receive real-time progress updates while coins are being loaded. It also refactors the loadtxoutset RPC to use the interface, moving file validation into the snapshot implementation. This change unblocks draft GUI PRs bitcoin-core/gui#870 and bitcoin-core/gui-qml#488.

Data

dossier JSON · extract JSON · model ledger, generated 2026-10-04T01:20, confidence high, input hash ccc52d89dcca9672
thread read through 2026-09-24 (51 statements), head 7181189f59
labels: IPC

Categories

IPC / multiprocess

P2 · new feature

Exposes UTXO snapshot loading and progress notifications on `interfaces::Node`, directly unblocking GUI assumeutxo loading. The change has active downstream consumers waiting on it, specifically bitcoin-core/gui#870 and bitcoin-core/gui-qml#488.

Membership: Labeled IPC; adds `interfaces::Snapshot` in `src/interfaces/snapshot.h`, updates `src/interfaces/node.h`, and implements interface bindings in `src/node/interfaces.cpp`.

Factors: security/stability 0, bug 0, performance 0, user value 2, leverage 2

RPC / REST / ZMQ

P3 · cleanup (ranking pass: Moved down 8: the RPC-visible part is a refactor plus an error-code change; its payoff is in GUI drafts outside this category.)

Refactoring `loadtxoutset` changes failure error codes from `RPC_INVALID_PARAMETER` and `RPC_DESERIALIZATION_ERROR` to `RPC_INTERNAL_ERROR`. This alters compatibility for callers handling snapshot loading errors, though the RPC change itself is primarily a test harness for the interface.

Membership: Changes `src/rpc/blockchain.cpp` to delegate `loadtxoutset` handling to the interface, altering return error codes.

Factors: security/stability 0, bug 0, performance 0, user value 2, leverage 2