Skip to content

Conversation

@alexwoods
Copy link
Collaborator

@alexwoods alexwoods commented Dec 12, 2025

Description

This PR implements bootstrapping the UTxO state module from the streaming snapshot.

Related Issue(s)

Implements #386.

How was this tested?

  • configure the utxo state module to listen to the snapshot topic (snapshot-subscribe-topic config setting)
  • check the reported entries in the utxo state store

Checklist

  • My code builds and passes local tests
  • I added/updated tests for my changes, where applicable
  • I updated documentation (if applicable)
  • CI is green for this PR

Impact / Side effects

Replaces the contents of the UtxoEntry struct with our own common types, so anything else relying on them will need updating. I'm not aware of anything that falls into this scope.

Reviewer notes / Areas to focus

I'm not sure if it's normal to have invalid utxos?
acropolis_module_utxo_state::state: slot=134956948 number=10844342 immutable_utxos=11234442 volatile_utxos=243 valid_utxos=11234421

I'm not 100% sure about the address parsing, particularly the "other Shelley" bit where I've assumed that from_bytes_key() is the right thing for everything that isn't a stake address.

The flushing of any final utxo state message batch on completion of the snapshot could do with checking. My understanding from the very helpful comment is that the message sent by on_actions() blocks until all snapshot messages are dealt with, so I have added a call to flush any final batches just before that message is sent.

Sidenote: having a SnapshotComplete message sent on the snapshot channel might provide a cleaner place to hook this into. I think it also provides a simple mechanism for modules to drop their snapshot listeners should we wish to do that.

@lowhung lowhung marked this pull request as ready for review December 15, 2025 18:22
- Extract UTXO-related types (SnapshotUTxO, SnapshotUTxOIdentifier,
  SnapshotAddress, SnapshotValue, SnapshotUTXOValue, UtxoEntry) from
  streaming_snapshot.rs into new utxo.rs module

- Fix utxo_state module not receiving bootstrap UTXOs by adding default
  subscription to "cardano.snapshot" topic (was previously optional with
  no default, so subscription never happened)

- Change publisher's tokio::spawn to blocking calls using block_in_place
  + Handle::current().block_on() to ensure messages are published before
  callbacks return

- Add logging for UTXO batch publishing and receiving to aid debugging
@lowhung lowhung changed the title Ajw/386 bootstrap utxo module feat: bootstrap utxo module Dec 15, 2025
# Conflicts:
#	modules/snapshot_bootstrapper/src/publisher.rs
@lowhung
Copy link
Collaborator

lowhung commented Dec 15, 2025

Confirmation of this working

2025-12-15T20:13:08.184177Z  INFO acropolis_module_utxo_state: UTXO state received Snapshot Startup message
2025-12-15T20:13:08.184239Z  INFO acropolis_module_epochs_state: Received snapshot startup signal, awaiting bootstrap data...
2025-12-15T20:13:09.320795Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Publishing first UTXO batch with 10000 UTXOs to topic 'cardano.snapshot'
2025-12-15T20:13:09.322598Z  INFO acropolis_module_accounts_state: Received snapshot startup signal, awaiting bootstrap data...
2025-12-15T20:13:09.322611Z  INFO acropolis_module_utxo_state: UTXO state received first UTxO batch with 10000 UTxOs
2025-12-15T20:13:09.904343Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Processed 1000000 UTXOs
2025-12-15T20:13:09.904368Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Published 100 UTXO batches (1000000 UTXOs total)
2025-12-15T20:13:09.906298Z  INFO acropolis_common::snapshot::streaming_snapshot: Streamed 1000000 UTXOs, buffer: 16 MB, max entry: 17708 bytes
2025-12-15T20:13:10.106955Z  INFO acropolis_module_utxo_state: UTXO state received 100 batches, 1000000 total UTxOs so far
2025-12-15T20:13:10.999966Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Processed 2000000 UTXOs
2025-12-15T20:13:10.999985Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Published 200 UTXO batches (2000000 UTXOs total)
2025-12-15T20:13:11.011835Z  INFO acropolis_common::snapshot::streaming_snapshot: Streamed 2000000 UTXOs, buffer: 16 MB, max entry: 17708 bytes
2025-12-15T20:13:11.103157Z  INFO acropolis_module_utxo_state: UTXO state received 200 batches, 2000000 total UTxOs so far
2025-12-15T20:13:11.687448Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Processed 3000000 UTXOs
2025-12-15T20:13:11.687467Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Published 300 UTXO batches (3000000 UTXOs total)
2025-12-15T20:13:11.691276Z  INFO acropolis_common::snapshot::streaming_snapshot: Streamed 3000000 UTXOs, buffer: 16 MB, max entry: 21597 bytes
2025-12-15T20:13:11.753360Z  INFO acropolis_module_utxo_state: UTXO state received 300 batches, 3000000 total UTxOs so far
2025-12-15T20:13:13.229750Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Processed 4000000 UTXOs
2025-12-15T20:13:13.229771Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Published 400 UTXO batches (4000000 UTXOs total)
2025-12-15T20:13:13.237095Z  INFO acropolis_common::snapshot::streaming_snapshot: Streamed 4000000 UTXOs, buffer: 16 MB, max entry: 21597 bytes
2025-12-15T20:13:13.329226Z  INFO acropolis_module_utxo_state: UTXO state received 400 batches, 4000000 total UTxOs so far
2025-12-15T20:13:13.974934Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Processed 5000000 UTXOs
2025-12-15T20:13:13.974955Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Published 500 UTXO batches (5000000 UTXOs total)
2025-12-15T20:13:13.984968Z  INFO acropolis_common::snapshot::streaming_snapshot: Streamed 5000000 UTXOs, buffer: 16 MB, max entry: 21597 bytes
2025-12-15T20:13:14.059159Z  INFO acropolis_module_utxo_state: UTXO state received 500 batches, 5000000 total UTxOs so far
2025-12-15T20:13:14.692141Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Processed 6000000 UTXOs
2025-12-15T20:13:14.692164Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Published 600 UTXO batches (6000000 UTXOs total)
2025-12-15T20:13:14.695246Z  INFO acropolis_common::snapshot::streaming_snapshot: Streamed 6000000 UTXOs, buffer: 16 MB, max entry: 21597 bytes
2025-12-15T20:13:14.757047Z  INFO acropolis_module_utxo_state: UTXO state received 600 batches, 6000000 total UTxOs so far
2025-12-15T20:13:15.365971Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Processed 7000000 UTXOs
2025-12-15T20:13:15.365991Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Published 700 UTXO batches (7000000 UTXOs total)
2025-12-15T20:13:15.368646Z  INFO acropolis_common::snapshot::streaming_snapshot: Streamed 7000000 UTXOs, buffer: 16 MB, max entry: 21597 bytes
2025-12-15T20:13:15.432584Z  INFO acropolis_module_utxo_state: UTXO state received 700 batches, 7000000 total UTxOs so far
2025-12-15T20:13:18.301333Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Processed 8000000 UTXOs
2025-12-15T20:13:18.301374Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Published 800 UTXO batches (8000000 UTXOs total)
2025-12-15T20:13:18.312118Z  INFO acropolis_common::snapshot::streaming_snapshot: Streamed 8000000 UTXOs, buffer: 16 MB, max entry: 21597 bytes
2025-12-15T20:13:18.413670Z  INFO acropolis_module_utxo_state: UTXO state received 800 batches, 8000000 total UTxOs so far
2025-12-15T20:13:19.289270Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Processed 9000000 UTXOs
2025-12-15T20:13:19.289300Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Published 900 UTXO batches (9000000 UTXOs total)
2025-12-15T20:13:19.301790Z  INFO acropolis_common::snapshot::streaming_snapshot: Streamed 9000000 UTXOs, buffer: 16 MB, max entry: 21597 bytes
2025-12-15T20:13:19.517841Z  INFO acropolis_module_utxo_state: UTXO state received 900 batches, 9000000 total UTxOs so far
2025-12-15T20:13:20.260348Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Processed 10000000 UTXOs
2025-12-15T20:13:20.260370Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Published 1000 UTXO batches (10000000 UTXOs total)
2025-12-15T20:13:20.265329Z  INFO acropolis_common::snapshot::streaming_snapshot: Streamed 10000000 UTXOs, buffer: 16 MB, max entry: 22641 bytes
2025-12-15T20:13:20.342786Z  INFO acropolis_module_utxo_state: UTXO state received 1000 batches, 10000000 total UTxOs so far
2025-12-15T20:13:20.998105Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Processed 11000000 UTXOs
2025-12-15T20:13:20.998122Z  INFO acropolis_module_snapshot_bootstrapper::publisher: Published 1100 UTXO batches (11000000 UTXOs total)
2025-12-15T20:13:21.002268Z  INFO acropolis_common::snapshot::streaming_snapshot: Streamed 11000000 UTXOs, buffer: 16 MB, max entry: 22641 bytes
2025-12-15T20:13:21.080082Z  INFO acropolis_module_utxo_state: UTXO state received 1100 batches, 11000000 total UTxOs so far
2025-12-15T20:13:21.147314Z  INFO acropolis_common::snapshot::streaming_snapshot: Streaming results:
2025-12-15T20:13:21.147327Z  INFO acropolis_common::snapshot::streaming_snapshot:   UTXOs processed: 11199911


...
2025-12-15T20:14:08.123299Z  INFO acropolis_module_utxo_state::state: slot=134092992 number=10802144 immutable_utxos=11199911 volatile_utxos=444 valid_utxos=11199820

@lowhung lowhung requested a review from golddydev December 15, 2025 20:37
@lowhung lowhung linked an issue Dec 15, 2025 that may be closed by this pull request
4 tasks
Copy link
Collaborator

@buddhisthead buddhisthead left a comment

Choose a reason for hiding this comment

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

Wow, this looks great! So much nice cleanup and nice documentation about the issues.

Note: I initially did have a SnapshotCompleteMessage that marked the end of the boot-from-snapshot process, but found there is already a snapshot complete message. At that time, I didn't realize the order of mithril "snapshot" loading vs our boostrapping. It confused me for a while because there is the Cardano message that means "Mithril snapshot loading complete".

@lowhung lowhung merged commit 9e17bcb into main Dec 16, 2025
2 checks passed
@lowhung lowhung deleted the ajw/386-bootstrap-utxo-module branch December 16, 2025 01:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bootstrap UTXO Module

4 participants