Skip to content

Commit e43aee5

Browse files
committed
refactor: update guest program workspace and add public values
1 parent 9be73bb commit e43aee5

5 files changed

Lines changed: 72 additions & 119 deletions

File tree

Cargo.lock

Lines changed: 6 additions & 96 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,18 @@ members = [
99
"crates/common/crypto",
1010
"crates/common/metrics",
1111
"crates/common/test-fixtures",
12-
"crates/common/types", "crates/guest-program/sp1",
12+
"crates/common/types",
1313
"crates/net/api",
1414
"crates/net/p2p",
1515
"crates/net/rpc",
1616
"crates/storage",
1717
]
1818

19+
# NOTE: zkVM guest programs are their own workspaces: they build for the respective
20+
# target ISA via their respective build commands, not for the host, so `cargo {clippy,test}
21+
# --workspace` must not try to compile them.
22+
exclude = ["crates/guest-program/sp1"]
23+
1924
[workspace.package]
2025
authors = ["LambdaClass"]
2126
edition = "2024"

crates/common/types/src/stf.rs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,37 @@
11
use libssz::{SszDecode, SszEncode};
22
use serde::{Deserialize, Serialize};
33

4-
use crate::{block::Block, state::State};
4+
use crate::{block::Block, primitives::H256, state::State};
55

6-
// we will pass as bytes, as we want this to be definitely serializable and both implement Sszencode and decode
6+
7+
/// Input type for the zkVM's
8+
///
9+
/// The inputs to the zkVM need to derive serde Serialize/deserialize
10+
/// which is not derived for state (libssz traits)
11+
/// wrapping pre-serialized SSZ bytes sidesteps that part.
712
#[derive(Debug, Clone, Serialize, Deserialize)]
813
pub struct StfInput {
914
state: Vec<u8>,
1015
block: Vec<u8>,
1116
}
1217

18+
/// Public values committed by the STF guest program.
19+
///
20+
/// These bind a proof to one concrete transition: applying the block with
21+
/// `block_root` to the state with `pre_state_root` yields the state with
22+
/// `post_state_root`. A verifier reads these back from the proof without ever
23+
/// seeing the full pre-state or block, and can chain proofs by matching one
24+
/// transition's `post_state_root` to the next's `pre_state_root`.
25+
#[derive(Debug, Clone, Serialize, Deserialize)]
26+
pub struct StfPublicValues {
27+
/// `hash_tree_root` of the pre-state.
28+
pub pre_state_root: H256,
29+
/// `hash_tree_root` of the block being applied.
30+
pub block_root: H256,
31+
/// `hash_tree_root` of the post-state (equals `block.state_root`).
32+
pub post_state_root: H256,
33+
}
34+
1335
impl StfInput {
1436
pub fn new(state: State, block: Block) -> Self {
1537
StfInput {
@@ -18,11 +40,11 @@ impl StfInput {
1840
}
1941
}
2042

21-
pub fn return_state(input: Self) -> State {
22-
State::from_ssz_bytes(&input.state).expect("error decoding State")
43+
pub fn state(&self) -> State {
44+
State::from_ssz_bytes(&self.state).expect("error decoding State")
2345
}
2446

25-
pub fn return_block(input: Self) -> Block {
26-
Block::from_ssz_bytes(&input.block).expect("error decoding block")
47+
pub fn block(&self) -> Block {
48+
Block::from_ssz_bytes(&self.block).expect("error decoding block")
2749
}
2850
}
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1+
# Standalone workspace: this guest builds for a RISC-V zkVM target via
2+
# `cargo prove build`, so it is excluded from the root workspace and cannot
3+
# inherit its `[workspace.package]` / `[workspace.dependencies]` values.
4+
[workspace]
5+
16
[package]
27
name = "zkvm_guest_sp1"
3-
authors.workspace = true
4-
edition.workspace = true
5-
keywords.workspace = true
6-
license.workspace = true
7-
readme.workspace = true
8-
repository.workspace = true
9-
rust-version.workspace = true
10-
version.workspace = true
8+
version = "0.1.0"
9+
edition = "2024"
10+
publish = false
1111

1212
[dependencies]
1313
sp1-zkvm = "6.1.0"
14-
ethlambda-types.workspace = true
15-
ethlambda-state-transition.workspace = true
14+
ethlambda-types = { path = "../../common/types" }
15+
ethlambda-state-transition = { path = "../../blockchain/state_transition" }

crates/guest-program/sp1/src/main.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,28 @@
22
sp1_zkvm::entrypoint!(main);
33

44
use ethlambda_state_transition::state_transition;
5-
use ethlambda_types::{primitives::HashTreeRoot, stf::StfInput};
5+
use ethlambda_types::{
6+
primitives::HashTreeRoot,
7+
stf::{StfInput, StfPublicValues},
8+
};
69

710
fn main() {
8-
let input: StfInput = sp1_zkvm::io::read();
9-
let mut state = StfInput::return_state(input.clone());
10-
let block = &StfInput::return_block(input.clone());
11-
let _ = state_transition(&mut state, block);
12-
sp1_zkvm::io::commit(&state.hash_tree_root());
11+
let input: StfInput = sp1_zkvm::io::read();
12+
let mut state = input.state();
13+
let block = input.block();
14+
15+
// Capture the pre-state and block roots before mutating the state, so the
16+
// committed public values bind the proof to this specific transition.
17+
let pre_state_root = state.hash_tree_root();
18+
let block_root = block.hash_tree_root();
19+
20+
state_transition(&mut state, &block).expect("state transition failed");
21+
22+
let public_values = StfPublicValues {
23+
pre_state_root,
24+
block_root,
25+
// state_transition already asserts this equals block.state_root.
26+
post_state_root: state.hash_tree_root(),
27+
};
28+
sp1_zkvm::io::commit(&public_values);
1329
}

0 commit comments

Comments
 (0)