feat: add unified storage interface (signet-storage)#6
Merged
Conversation
Add a new signet-storage crate that provides a unified interface for writing execution data to both hot storage (fast state access) and cold storage (historical archival). Key additions: - ExecutedBlock type in signet-storage-types combining all data needed by both storage systems (header, bundle, transactions, receipts, events) - ExecutedBlockBuilder for ergonomic construction - UnifiedStorage struct wrapping HotKv + ColdStorageHandle - Fire-and-forget semantics for cold storage (errors logged, not fatal) - Recovery methods: cold_lag() to detect gaps, replay_to_cold() to recover Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
prestwich
commented
Feb 3, 2026
prestwich
commented
Feb 3, 2026
- Collapse HotTx and Hot variants into single Hot(HistoryError<HotKvError>) - Remove generic E from StorageError, simplifying the API - Add SendFailed variant to ColdStorageError for channel full/closed - Add sync dispatch methods (dispatch_append_blocks, dispatch_truncate_above) using try_send() for non-blocking fire-and-forget writes - Convert append_blocks and unwind_above from async to sync - Remove unused tracing dependency Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add detailed docs to SendFailed explaining backpressure vs task failure - Document dispatch methods with recovery strategies - Add "Backpressure and Failure Recovery" section to UnifiedStorage - Document error semantics for append_blocks and unwind_above Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update alloy from 1.0.9 to 1.6 - Fix broken cross-crate doc links in signet-cold Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Split SendFailed into two distinct error variants: - Backpressure: channel full, task alive but slow (transient) - TaskTerminated: channel closed, task stopped (persistent) This allows callers to handle each case appropriately: - Backpressure: retry, accept gap, or increase capacity - TaskTerminated: restart task, then replay from hot storage Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add ColdStorageReadHandle for read-only access to cold storage - Separate read and write channels in ColdStorageHandle - Process writes sequentially (inline) for ordering guarantees - Process reads concurrently (spawned) for throughput - Remove combined ColdStorageRequest enum - Add cold_reader() method to UnifiedStorage - Document consistency model and recovery procedures - Document streaming writes design (future work) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Document dual channel architecture (read/write separation) - Add ColdStorageReadHandle to core types - Document consistency model and recovery procedures Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove cross-crate link to signet_storage::UnifiedStorage - Replace private constant link with inline value Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
prestwich
commented
Feb 3, 2026
prestwich
commented
Feb 3, 2026
prestwich
commented
Feb 3, 2026
- Add revm_reader() method to UnifiedStorage for revm integration - Re-export RevmRead and RevmWrite from signet-storage - Change append_blocks to take Vec<ExecutedBlock> (owned) - Change replay_to_cold to take Vec<ExecutedBlock> (owned) - Update dispatch_cold to consume blocks via into_iter(), removing clones Hot storage still clones header/bundle for tuple format, but cold storage now consumes owned data without cloning. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Change append_blocks and append_blocks_inconsistent to accept an iterator of references instead of a slice of owned tuples. This eliminates the need to clone SealedHeader and BundleState when writing to hot storage. - append_blocks now accepts impl IntoIterator<Item = (&SealedHeader, &BundleState)> - Validation and writing merged into single pass (zero allocations) - Updated all callers to use iterator pattern - Updated documentation examples Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
07949e1 to
f641151
Compare
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ExecutedBlockandExecutedBlockBuildertypes tosignet-storage-typesfor representing complete block execution outputsignet-storagecrate withUnifiedStoragestruct that wraps both hot and cold storagecold_lag()to detect gaps,replay_to_cold()for external recoveryDesign
The unified interface accepts
ExecutedBlockwhich contains all data needed by both storage systems:Write flow:
Test plan
cargo clippy -p signet-storage-types --all-features --all-targetscargo clippy -p signet-storage --all-features --all-targetscargo clippy -p signet-storage-types --no-default-features --all-targetscargo clippy -p signet-storage --no-default-features --all-targetscargo +nightly fmtcargo t -p signet-storage-typescargo t -p signet-storage🤖 Generated with Claude Code