Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ Success response:
- `examples/app-core/src/`: wallet prototype implementing `Application`
- `tests/benchmarks/`: benchmark harnesses and benchmark spec

Related docs:
- App snapshot format: `docs/app-snapshot-format.md`

## Prototype Limits

- Wallet state is in-memory and not persisted.
Expand Down
69 changes: 69 additions & 0 deletions docs/app-snapshot-format.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# App Snapshot Format (Wallet Toy App)

This document defines the current on-disk snapshot format for the toy wallet app in `examples/app-core`.

Scope note: this only covers the **capability** to serialize/deserialize app state. It does not define when snapshots are triggered or how runtime wiring invokes save/load.

## Encoding

- **Format:** SSZ
- **Current version:** `WalletSnapshotV1` (Rust struct name)
- **Byte order for balances:** big-endian 32-byte integers (`U256`)

## Serialized State

`WalletSnapshotV1` encodes:

- `erc20_portal_address` (`[u8; 20]`)
- `supported_erc20_token` (`[u8; 20]`)
- `sequencer_address` (`[u8; 20]`)
- `balances` (`Vec<SnapshotBalance>`)
- `address` (`[u8; 20]`)
- `balance_be` (`[u8; 32]`)
- `nonces` (`Vec<SnapshotNonce>`)
- `address` (`[u8; 20]`)
- `nonce` (`u32`)
- `executed_input_count` (`u64`)

## Determinism Guarantees

`WalletApp` stores balances/nonces in hash maps, so iteration order is nondeterministic. Before encoding:

- `balances` entries are sorted by `address`
- `nonces` entries are sorted by `address`

This guarantees stable snapshot bytes for equivalent logical state.

## Compatibility Policy

- Restores must decode the exact current snapshot schema.
- Malformed bytes fail restore with a decode error.
- Future breaking changes must introduce a new versioned schema type (for example, `WalletSnapshotV2`) and explicit migration/dispatch logic.
- Do not reorder or reinterpret existing fields in-place without a version bump.

## API Surface

Current wallet snapshot API:

- `snapshot_bytes(&self) -> Vec<u8>`
- `restore_from_snapshot_bytes(&mut self, snapshot: &[u8]) -> Result<(), WalletSnapshotError>`
- `save_snapshot<P: AsRef<Path>>(&self, path: P) -> Result<(), WalletSnapshotError>`
- `load_snapshot<P: AsRef<Path>>(&mut self, path: P) -> Result<(), WalletSnapshotError>`

## Disk Write Semantics

`save_snapshot` uses an atomic replacement pattern:

- write bytes to a temporary file in the same directory as the target
- `sync_all` the temp file
- rename temp file to the final path

This avoids exposing partially written snapshot bytes at the target path.

## Out of Scope

This document intentionally does not define:

- periodic vs explicit snapshot trigger policy
- mount paths and runtime drive conventions
- atomic file replacement protocol for production snapshot lifecycle
1 change: 1 addition & 0 deletions examples/app-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ ssz = { package = "ethereum_ssz", version = "0.10" }
ssz_derive = { package = "ethereum_ssz_derive", version = "0.10" }
tracing = "0.1"
types = { workspace = true }
thiserror = "1"
2 changes: 1 addition & 1 deletion examples/app-core/src/application/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ mod wallet;
pub use anvil_accounts::default_private_keys;
pub use method::{MAX_METHOD_PAYLOAD_BYTES, Method, Transfer, Withdrawal};
pub use notice::{DepositNotice, TransferNotice};
pub use wallet::{WalletApp, WalletConfig};
pub use wallet::{WalletApp, WalletConfig, WalletSnapshotError};
Loading