-
Notifications
You must be signed in to change notification settings - Fork 0
Logbook January 2026
paolino edited this page Jan 30, 2026
·
19 revisions
- Bump csmt dependecy to have access to transaction composition.
- merged Bump csmt dependency #3
- Implement 'Update' object for rocksdb backend
- Opened issue Implement rocksdb persistence #4
- Drafted PR Switch chainsync application to rocksdb backend #6
- Was able to define the forward apply as the primitives from the csmt library are sufficient.
- Still need to implement the rollback apply as the rocksdb transaction backend hash no cursor support.
- Refined the 'Update' abstraction that represents the database changes FSM
- Work on Switch chainsync application to rocksdb backend #6
- update type change
- chainsync change
- This required to add a Reset command to the ChainSync protocol as Rewind is taking
[Point]while we actually need to reset toOrigin - Now the state of the database is a tagged
Updateobject where we specify if- we can proceed forward of backward or
- we have to find an intersection among a set of valid points before rolling back to one of them
- we have to reset to origin
- Only rollback can really send the state to the reset state and intersection. This is not encoded in the types yet.
- Work on Switch chainsync application to rocksdb backend #6
- Work on PR: Switch chainsync application to rocksdb backend #6
- Implemented the rollForwardFinality for rocks-db backend
- Required a fix in csmt library to allow seeking column-type encoded keys
- Introduced the Point type to containe hash and slot
- Point type is the rocksdb
slot. Maybe we should rename slot as point in the Update / State type ?- In memory is unsafe on that side and could rollback to points on a different fork. OTOH running in memory implies trust on the node and running once on one node.
- Introduced an armageddon concept. This is breaking atomicity of the Update application. OTOH it should never happen in practice. It happens only if the node rolls back more than our inverse operation queue, which is dimensioned at 2160 blocks, covering the instability window.
- Armageddon is when we have to reset to origin because we cannot find a common intersection point. It deletes all the database content, but is done in batches to avoid unbound memory usage to build the complete deletion in one transaction.
- Because it happens only as a reaction to when the node request to rollback to Origin (and not straight at the time when it proposes an impossible rollback), it's also happening when we start with an empty inverse operation queue, which is fine.
- Funny time with fibonacci when sampling the possible rollback points.
- Implemented the rollForwardFinality for rocks-db backend
- Work on PR: Switch chainsync application to rocksdb backend #6
- Generalized implementation to be independent from rocksdb backend
- actually was already independent, just lower the capital letter in the types did it
- cleanup the implementation by using a deeper monad stack
- Added the implementation runner for the rocksdb backend, both update and query, based on the transactional interface.
- Copy over the properties from the InMemorySpec to the RocksDBSpec
- It's not needed for the specs themselves so I will make a common spec later
- Prepare the spec runner for the rocksdb backend
- Got some success but found out already a bad assumption that makes the specs unusable:
- I assumed it was ok to use the inverse operation queue to identify both the tip and the finality point, but in reality I am not storing the finality when it is at origin (i.e. when the queue is empty), and because it's always computed as the last point in the queue, it results moved from Origin to the first slot after the first forward, which is wrong (it should move only when required). I will need to store the finality point separately or encode the elements in the queue differently, with origin as a special value. The second solution is more complex but cleaner. The empty database will then have a queue with one element, the Origin, representing both tip and finality at origin.
- Generalized implementation to be independent from rocksdb backend
- Work on PR: Switch chainsync application to rocksdb backend #6
- Fixed the finality point tracking by storing finality and tip as Origin at bootstrap
- Implemented an Application module that took the logic from the in memory application module
- Using it for the in-memory application would require some work to unlift the StateT ... to IO. The in-memory application can die as soon as the rocksdb is working ..
- Implemented the rocksdb run module that provides prisms nad context to run the application module
- It runs! But it fails to restart from the tip. Plus there is no interface to query proofs and stuff yet.
- Work on PR: Switch chainsync application to rocksdb backend #6
- Removed the in-memory implementation as rocksdb is now working
- Fixed the restarting issue that was always triggering the armageddon. The kv interface is not perfect: we cannot set the cursor over the last key, so iterating with prev-key is not able to pick up the last entry. The solution for now is picking up the last entry and then going into scanning.
- Added logging support, to file or to stdout
- Investigated the space leak more, not fixed yet.
- Simplified the block-fetch module by removing the IORef around the points and breaking up the big functions.
- Merged PR Switch chainsync application to rocksdb backend #6
- bumped haskell-csmt dependency
- hunted space-leak, tested with header queue of 1 , not solved yet.
- Opened Issue Add basic proofs HTTP API #8
- Opened Issue Store current merkle tree roots #9
- Opened Issue Implement the merkle-tree roots endpoint #10
- Opened Issue Implement the current proof of tx-in existence end-point #11
- Merged PR Store and trace merkle roots #12
- adding the merkle-trie roots to the rollback points in the db and
- traced the current merkle root in the metrics
- merged
- Closed Issue Store current merkle tree roots #9
- Merged PR Add HTTP service with merkle-roots endpoint #13
- implemented the HTTP server with servant
- added the merkle-roots endpoint
- added the swagger UI on a separate port
- added the swagger UI to the documentation and CI swagger UI
- tried both copilot agent with github PRs, interesting but not very interactive
- I decided to evaluate Claude Code pro for 1 year, the pro plan seems not enough for me, but let's see how it goes
- today's PR was written with Claude assistance, I must say it was quite helpful in writing the servant boilerplate and the swagger integration. Seeing the mistake it made I have hard time trusting it to write any businnes logic, but for boilerplate it's quite good.
- Merged PR feat: add inclusion proof endpoint #17
- Added new
/proof/{txId}/{txIx}endpoint that retrieves inclusion proofs for a given transaction input - Return the proof bytes, tx output, and current merkle root in base16 encoding
- Factored out base16 encoding/decoding utilities into a dedicated
Base16module - Added a test suite to roughly check the API is responding
- Closed Issue Implement the current proof of
tx-inexistence end-point #11
- Added new
- Opened Issue Record and report base checkpoint #16
- Record the CLI argument
-fcontent in the DB as the base checkpoint for the UTXO set - Make sure that armageddon restarts from that base checkpoint when reconstructing the UTXO set
- Report the base checkpoint in the metrics
- Record the CLI argument
- Opened Issue Demo the HTTP API #19
- Need to record a new screencast that performs operations via CURL since we now have an HTTP interface
- Opened PR feat: Record and report base checkpoint #20
- Merged PR feat: Record and report base checkpoint #20
- Added ConfigCol column family to store configuration data
- Implemented base checkpoint persistence and retrieval
- Extended metrics with baseCheckpoint field exposed via HTTP API
- Refactored application function signature for clarity
- Closed Issue Record and report base checkpoint #16
- Merged PR chore: bump haskell-csmt and add rocksdb-kv-transactions dependency #21
- Updated haskell-csmt to latest commit with improved documentation
- Added rocksdb-kv-transactions as separate source-repository-package
- Fixed API change:
mkCols→fromList
- Merged PR chore: improve code quality and documentation #22
- Added module-level Haddock documentation to 10 key modules
- Expanded mkdocs with getting-started and architecture pages
- Improved README with overview, features, quick start
- Fixed justfile to use
findfor consistent.hsfile scanning
- Opened Issue Use Mithril for fast UTxO database bootstrapping #23
- Plan to use Mithril certified snapshots to reduce bootstrap time from days to hours
- Defined three phases: Infrastructure, UTxO Extraction, Integration
- Merged PR feat: add Mithril integration for fast bootstrapping #24 (Phase 1)
- Added Mithril.Client module for aggregator API interaction
- Added Mithril.Options module for CLI parsing with OptEnvConf
- Added Mithril.Import module for import orchestration
- E2E tests verifying connection to preview, preprod, and mainnet aggregators
- Merged PR feat: add Mithril UTxO extraction infrastructure #25 (Phase 2)
- Extract UTxOs from ledger state
tvarfile (InMemory backing store format) - Convert MemPack encoding to CBOR for chain sync compatibility
- Added
--mithril-bootstrap-onlyflag to exit after import - HTTP-based snapshot download (no mithril-client CLI required)
- Extract UTxOs from ledger state
- Merged PR feat: Mithril UTxO extraction and bootstrap-only mode #27
- Verify TxIn/TxOut MemPack decoding in E2E tests
- Updated documentation with working extraction status
- Merged PR feat: add extract-utxos utility and golden file import tests #28
- Add
extract-utxosexecutable for extracting UTxOs from Mithril snapshots to golden files - Add ImportSpec tests with 1000 UTxOs golden file from preview network
- Add
- Merged PR feat: add Marp presentation slides for light clients #29
- Merged PR feat: Mithril integration improvements and CLI simplification #30
- Opened Issue Mithril bootstrap: scan headers to find block hash for checkpoint #32
- Done Issue Stream UTxOs from HTTP to disk during Mithril extraction #33
- Done Issue --mithril-bootstrap-only should imply --mithril-bootstrap #35
- Merged PR feat: stream HTTP snapshot download to disk #36
- Replaced
httpLbswith streamingwithResponse+brRead - Memory stays constant (~141MB) during download instead of proportional to file size
- Tested with preview (405MB) and mainnet (2.8GB) - memory stayed flat
- Replaced
- Merged PR feat: skip block fetch until Mithril slot during bootstrap #37
- Skip fetching blocks until reaching the Mithril snapshot slot during bootstrap
- Avoids unnecessary block processing when starting from Mithril snapshot
- Merged PR fix: --mithril-bootstrap-only implies --mithril-bootstrap #38
-
--mithril-bootstrap-onlynow automatically enables Mithril bootstrap - No need to specify both flags anymore
-
- Started preview chainsync test with Mithril bootstrap
- Importing UTxOs at ~850/sec from Mithril snapshot
- Merged PR feat: add progress logging during chain sync #40
- Log block processing every 1000 slots during chain synchronization
- Provides visibility after Mithril bootstrap completes
- Moved progress throttling from BlockFetch to tracer layer
- Merged PR feat: gate API with 503 until synced, add /ready endpoint #43
- Gate
/merkle-rootsand/proof/{txId}/{txIx}endpoints with HTTP 503 until node is synced - Add
/readyendpoint for orchestration to check sync status - Add
--sync-thresholdCLI option (default: 100 slots) - Closed Issue API should return 503 until node is synced #31
- Gate
- Merged PR feat: stream UTxOs from disk using incremental CBOR parsing #47
- Refactor Mithril extraction to use true streaming with
deserialiseIncremental - Memory usage now O(chunk_size) instead of O(file_size)
- Preprod test: 3.8M UTxOs processed with only 5.9 MB max residency at 1.36M UTxOs/sec
- Closed Issue Stream UTxOs from disk to database during import #34
- Refactor Mithril extraction to use true streaming with
- Closed Issue Mithril bootstrap: scan headers to find block hash for checkpoint #32
- Closed Issue Add basic proofs HTTP API #8
- Opened Issue Validate node connection before Mithril bootstrap #41
- Opened Issue Implement Mithril STM validation in Haskell #42 (experiment)
- Opened Issue FFI bindings to mithril-client Rust library #45 (experiment)
- Opened Issue Expose Mithril import progress via HTTP API #46
- Opened Issue Use Mithril CLI to verify state snapshot #48
- Opened Issue feat: add docker-compose setup for cardano-utxo-csmt #49
- Opened Issue Expose extraction and header sync progress via HTTP metrics #51
- Merged PR feat: implement Ed25519 verification for ancillary downloads #53
- Ed25519 signature verification for Mithril ancillary files without full mithril-client
- Avoids downloading 14GB immutable history, only needs ancillary (ledger state)
- Closed Issue Implement Ed25519 verification for ancillary-only downloads #52
- Opened Issue Add unit tests for Mithril CLI options parser #54
- Opened Issue Rename executable and remove cardano-cli dump restore #55
- Merged PR docs: fix confusing navigation structure #56
- Home now points to index.md instead of slides
- Presentation moved to end of navigation
- Opened Issue Improve demo recording: full sync to tip, compressed to 30s #57
- Opened Issue feat: implement non-mithril UTxO sync with era projection and change reduction #58
- Opened Issue fix: docker image packages wrong executable #59
- Opened Issue Simplify inclusion proof format (haskell-csmt dependency) #60 (experiment)
- Merged PR Update generateInclusionProof API #62
- Bumped haskell-csmt to
308d2232d9db8064698460e0aebc101dadbd6fe4 - Fixed breaking API change:
generateInclusionProofnow returnsMaybe (v, ByteString)instead ofMaybe ByteString - Added extra
Selector d k vargument for KV column lookup - Fixed
downloadSnapshotHttpsignature change (new tracer argument) - Closed Issue Update generateInclusionProof API #61
- Closed Issue Simplify inclusion proof format (haskell-csmt dependency) #60
- Bumped haskell-csmt to
- Merged PR chore: rename executable and remove cardano-cli dump restore #63
- Renamed
cardano-utxo-chainsync→cardano-utxo - Renamed
cardano-utxo-csmt-swagger→cardano-utxo-swagger - Removed
cardano-utxo-csmtexecutable (obsolete cardano-cli dump restore) - Fixed docker image entrypoint to use correct executable
- Fixed CI artifacts to target
.#cardano-utxo - Removed orphaned tarball artifact upload step from CI
- Added
-O0to all cabal commands in justfile for consistent cache - Closed Issue Rename executable and remove cardano-cli dump restore #55
- Closed Issue fix: docker image packages wrong executable #59
- Renamed
- Merged PR test: add unit tests for CLI options parser #65
- Added Hspec tests for Mithril CLI options parsing
- Closed Issue Add unit tests for Mithril CLI options parser #54
- Opened PR feat: expose bootstrap progress metrics via HTTP API #66
- Adds bootstrap phase tracking: Downloading, Counting, Extracting, SyncingHeaders, Synced
- Adds extraction progress with current count, total, percentage, and rate
- Adds header sync progress with current/target slots
- Metrics available via existing
/metricsendpoint - Work in progress: metricsTracer fold not accumulating events correctly
- Opened Issue Rename repository and cabal package to cardano-utxo #64
- Opened Issue Mithril bootstrap should fail on extraction errors #67
- Disk full during extraction silently corrupts state instead of failing
- Merged PR feat: expose bootstrap progress metrics via HTTP API #66
- Bootstrap phase tracking: Downloading, Counting, Extracting, SyncingHeaders, Synced
- Extraction progress with current count, total, percentage, and rate
- Counting phase progress tracking
- Header sync progress with current/target slots
- ETA display for extraction progress in H:M:S format
- Refactored Metrics module into
Metrics.TypesandControl.Foldl.Extra - Unified run script with network parameter (
./run/cardano-utxo.sh <network>) - Fixed stdout buffering for immediate metrics output
- Spun off generic tracer utilities to contra-tracer-contrib
- Closed Issue Expose extraction and header sync progress via HTTP metrics #51
- Opened Issue Suppress stdout logs when metrics console is active #68
- Opened Issue Track Mithril bootstrap completion state #69
- Handle interrupted bootstrap on restart
- Merged PR feat: add YAML config file support #71
- Add
--config-fileoption for YAML configuration - All CLI options can now be specified in config file
- Closed Issue refactor: remove hardcoded Mithril URLs, add config file support #70
- Add
- Merged PR refactor: remove PartialHistory type and always use complete behavior #75
- Removed
PartialHistorytype, always useCompletebehavior - Simplified
newState,forwardTip,mkUpdatesignatures - Removed dead
Limittype from Options.hs - Closed Issue Remove Partial option and ensure run scripts reach network tip #72
- Removed
- Merged PR feat: validate node connection before Mithril bootstrap #77
- Validate node connection before starting Mithril download
- Fail fast if node is unreachable
- Closed Issue Validate node connection before Mithril bootstrap #41
- Merged PR fix: track incomplete Mithril bootstrap for cleanup on restart #78
- Track incomplete Mithril bootstrap state in database
- Clean up partial state on restart before re-bootstrapping
- Added docs: document interrupted bootstrap recovery behavior
- Closed Issue Track Mithril bootstrap completion state #69
- Merged PR docs: add bootstrap time estimates for all networks #80
- Add bootstrap time estimates for preview, preprod, mainnet
- Based on actual measurements: extraction ~1h for 2.9M UTxOs, header sync ~1.5h
- Added detailed bootstrap design documentation to architecture.md
- Merged PR docs: remove time estimates for non-mithril sync #81
- Remove "Comparison with Full Sync" section
- Document planned direct chain sync alternative (issue #58)
- Added architecture.md: Bootstrapping section with double-buffer design
- Added mithril-bootstrap.md: Alternative Direct Chain Sync section
- Merged PR fix: prevent Word64 underflow in slotsBehind calculation #84
-
/readywas returningfalseeven when fully synced -
slotsBehindshowed huge underflowed values due to Word64 underflow - Debug tracing revealed ChainSync protocol behavior:
tiplagsheaderby one block - Hypothesis:
tiprepresents candidate chain's known tip at message creation - Fix: safe subtraction returns 0 when
processed >= tip - Closed Issue chainTipSlot not updating correctly in metrics #83
-
- Opened Issue ChainSync: MsgRollForward tip slot can be behind header slot on ouroboros-network
- Asking about observed protocol behavior where
tip.slot < header.slotin MsgRollForward
- Asking about observed protocol behavior where
- Opened Issue refactor: remove hardcoded Mithril URLs, add config file support #70 (closed)
- Opened Issue Remove Partial option and ensure run scripts reach network tip #72 (closed)
- Opened Issue Emit non-ready status during rollback operations #73
- Opened Issue Expose metrics in Prometheus format #74
- Opened Issue Persist Mithril slot for skip mode on restart #76
- Opened Issue Add ETA and rate to header sync progress #79
- Opened Issue Remove progress data for completed phases from metrics #82
- Opened Issue chainTipSlot not updating correctly in metrics #83 (closed)