Skip to content

feat: add unified storage interface (signet-storage)#6

Merged
prestwich merged 11 commits intomainfrom
prestwich/meta-crate
Feb 10, 2026
Merged

feat: add unified storage interface (signet-storage)#6
prestwich merged 11 commits intomainfrom
prestwich/meta-crate

Conversation

@prestwich
Copy link
Copy Markdown
Member

Summary

  • Adds ExecutedBlock and ExecutedBlockBuilder types to signet-storage-types for representing complete block execution output
  • Creates new signet-storage crate with UnifiedStorage struct that wraps both hot and cold storage
  • Implements fire-and-forget semantics for cold storage writes (errors logged but don't block)
  • Adds recovery helpers: cold_lag() to detect gaps, replay_to_cold() for external recovery

Design

The unified interface accepts ExecutedBlock which contains all data needed by both storage systems:

  • Hot storage: header + BundleState (for state/history)
  • Cold storage: header + transactions + receipts + events (for archival)

Write flow:

  1. Hot storage writes synchronously (validates chain, updates state)
  2. Cold storage writes dispatched asynchronously
  3. Hot errors are fatal; cold errors are logged but don't block

Test plan

  • cargo clippy -p signet-storage-types --all-features --all-targets
  • cargo clippy -p signet-storage --all-features --all-targets
  • cargo clippy -p signet-storage-types --no-default-features --all-targets
  • cargo clippy -p signet-storage --no-default-features --all-targets
  • cargo +nightly fmt
  • cargo t -p signet-storage-types
  • cargo t -p signet-storage

🤖 Generated with Claude Code

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 and others added 7 commits February 3, 2026 11:23
- 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 and others added 2 commits February 3, 2026 15:10
- 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>
@prestwich prestwich force-pushed the prestwich/meta-crate branch from 07949e1 to f641151 Compare February 3, 2026 20:57
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@prestwich prestwich merged commit 83bff76 into main Feb 10, 2026
6 checks passed
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.

1 participant