From 495b954f207f42750f25a1d08924ddba346486e9 Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Wed, 6 Sep 2023 16:02:54 -0500 Subject: [PATCH 01/21] Switch ordering of witness --- examples/demo-prover/host/src/main.rs | 8 ++++--- .../methods/guest/src/bin/rollup.rs | 23 +++++++++---------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/examples/demo-prover/host/src/main.rs b/examples/demo-prover/host/src/main.rs index 3ccbfb775..85b66089c 100644 --- a/examples/demo-prover/host/src/main.rs +++ b/examples/demo-prover/host/src/main.rs @@ -117,13 +117,15 @@ async fn main() -> Result<(), anyhow::Error> { // The above proofs of correctness and completeness need to passed to the prover host.write_to_guest(&inclusion_proof); host.write_to_guest(&completeness_proof); - // The extracted blobs need to be passed to the prover - host.write_to_guest(&blobs); - + let result = app .stf .apply_slot(Default::default(), &filtered_block, &mut blobs); + // The extracted blobs need to be passed to the prover after execution. + // (Without executing, the host couldn't prune any data that turned out to be irrelevant to the guest) + host.write_to_guest(&blobs); + // Witness contains the merkle paths to the state root so that the code inside the VM // can access state values (Witness can also contain other hints and proofs) host.write_to_guest(&result.witness); diff --git a/examples/demo-prover/methods/guest/src/bin/rollup.rs b/examples/demo-prover/methods/guest/src/bin/rollup.rs index 0f1fe8278..df7d60694 100644 --- a/examples/demo-prover/methods/guest/src/bin/rollup.rs +++ b/examples/demo-prover/methods/guest/src/bin/rollup.rs @@ -11,7 +11,6 @@ use celestia::{BlobWithSender, CelestiaHeader}; use const_rollup_config::{ROLLUP_NAMESPACE_RAW, SEQUENCER_DA_ADDRESS}; use demo_stf::app::create_zk_app_template; use demo_stf::ArrayWitness; - use risc0_adapter::guest::Risc0Guest; use risc0_zkvm::guest::env; use sov_rollup_interface::crypto::NoOpHasher; @@ -50,7 +49,17 @@ pub fn main() { let mut blobs: Vec = guest.read_from_host(); env::write(&"blobs have been read\n"); - // Step 2: Apply blobs + // Step 2: Verify tx list + let verifier = CelestiaVerifier::new(celestia::verifier::RollupParams { + namespace: ROLLUP_NAMESPACE, + }); + + let validity_condition = verifier + .verify_relevant_tx_list::(&header, &blobs, inclusion_proof, completeness_proof) + .expect("Transaction list must be correct"); + env::write(&"Relevant txs verified\n"); + + // Step 3: Apply blobs let mut app = create_zk_app_template::(prev_state_root_hash); let witness: ArrayWitness = guest.read_from_host(); @@ -61,16 +70,6 @@ pub fn main() { env::write(&"Slot has been applied\n"); - // Step 3: Verify tx list - let verifier = CelestiaVerifier::new(celestia::verifier::RollupParams { - namespace: ROLLUP_NAMESPACE, - }); - - let validity_condition = verifier - .verify_relevant_tx_list::(&header, &blobs, inclusion_proof, completeness_proof) - .expect("Transaction list must be correct"); - env::write(&"Relevant txs verified\n"); - // TODO: https://github.com/Sovereign-Labs/sovereign-sdk/issues/647 let rewarded_address = CelestiaAddress::from_str(SEQUENCER_DA_ADDRESS).unwrap(); let output = StateTransition { From 08f4065828eb1360a4ad65541ac71dda97ff497f Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Thu, 7 Sep 2023 16:14:37 -0500 Subject: [PATCH 02/21] Feature gate native in stf runner --- full-node/sov-stf-runner/Cargo.toml | 27 ++-- full-node/sov-stf-runner/src/ledger_rpc.rs | 1 - full-node/sov-stf-runner/src/lib.rs | 164 ++------------------- full-node/sov-stf-runner/src/runner.rs | 156 ++++++++++++++++++++ 4 files changed, 181 insertions(+), 167 deletions(-) create mode 100644 full-node/sov-stf-runner/src/runner.rs diff --git a/full-node/sov-stf-runner/Cargo.toml b/full-node/sov-stf-runner/Cargo.toml index 446b9f775..fb0fc6c92 100644 --- a/full-node/sov-stf-runner/Cargo.toml +++ b/full-node/sov-stf-runner/Cargo.toml @@ -23,11 +23,11 @@ tracing = { workspace = true } futures = "0.3" tracing-subscriber = "0.3.17" -sov-db = { path = "../db/sov-db" } +sov-db = { path = "../db/sov-db", optional = true } sov-rollup-interface = { path = "../../rollup-interface", version = "0.1" } -sov-state = { path = "../../module-system/sov-state", version = "0.1", features = ["native"] } -sov-modules-api = { path = "../../module-system/sov-modules-api", version = "0.1", features = ["native"] } -celestia = { path = "../../adapters/celestia", features = ["native"] } +sov-state = { path = "../../module-system/sov-state", version = "0.1" } +sov-modules-api = { path = "../../module-system/sov-modules-api", version = "0.1" } +celestia = { path = "../../adapters/celestia" } [dev-dependencies] tempfile = { workspace = true } @@ -39,12 +39,13 @@ sov-modules-stf-template = { path = "../../module-system/sov-modules-stf-templat sov-value-setter = { path = "../../module-system/module-implementations/examples/sov-value-setter", features = ["native"] } sov-accounts = { path = "../../module-system/module-implementations/sov-accounts", features = ["native"] } -#[features] -#default = [] -#native = [ -# "sov-sequencer-registry/native", -# "sov-bank/native", -# "sov-value-setter/native", -# "sov-accounts/native", -# "jupiter/native", -#] +[features] +default = [] +native = [ + "sov-db", + "celestia/native", + "sov-sequencer-registry/native", + "sov-bank/native", + "sov-state/native", + "sov-modules-api/native", +] diff --git a/full-node/sov-stf-runner/src/ledger_rpc.rs b/full-node/sov-stf-runner/src/ledger_rpc.rs index 4b0be4d73..062858ad1 100644 --- a/full-node/sov-stf-runner/src/ledger_rpc.rs +++ b/full-node/sov-stf-runner/src/ledger_rpc.rs @@ -7,7 +7,6 @@ use sov_modules_api::utils::to_jsonrpsee_error_object; use sov_rollup_interface::rpc::{ BatchIdentifier, EventIdentifier, LedgerRpcProvider, SlotIdentifier, TxIdentifier, }; - const LEDGER_RPC_ERROR: &str = "LEDGER_RPC_ERROR"; use self::query_args::{extract_query_args, QueryArgs}; diff --git a/full-node/sov-stf-runner/src/lib.rs b/full-node/sov-stf-runner/src/lib.rs index 7ae3e4307..2db8ae86d 100644 --- a/full-node/sov-stf-runner/src/lib.rs +++ b/full-node/sov-stf-runner/src/lib.rs @@ -1,164 +1,22 @@ #![deny(missing_docs)] #![doc = include_str!("../README.md")] +#[cfg(feature = "native")] mod batch_builder; +#[cfg(feature = "native")] mod config; -use std::net::SocketAddr; +#[cfg(feature = "native")] pub use config::RpcConfig; +#[cfg(feature = "native")] mod ledger_rpc; +#[cfg(feature = "native")] +mod runner; +#[cfg(feature = "native")] pub use batch_builder::FiFoStrictBatchBuilder; +#[cfg(feature = "native")] pub use config::{from_toml_path, RollupConfig, RunnerConfig, StorageConfig}; -use jsonrpsee::RpcModule; +#[cfg(feature = "native")] pub use ledger_rpc::get_ledger_rpc; -use sov_db::ledger_db::{LedgerDB, SlotCommit}; -use sov_rollup_interface::da::{BlobReaderTrait, DaSpec}; -use sov_rollup_interface::services::da::DaService; -use sov_rollup_interface::stf::StateTransitionFunction; -use sov_rollup_interface::zk::Zkvm; -use tokio::sync::oneshot; -use tracing::{debug, info}; - -type StateRoot = ::Spec as DaSpec>::BlobTransaction, ->>::StateRoot; - -type InitialState = ::Spec as DaSpec>::BlobTransaction, ->>::InitialState; - -/// Combines `DaService` with `StateTransitionFunction` and "runs" the rollup. -pub struct StateTransitionRunner -where - Da: DaService, - Vm: Zkvm, - ST: StateTransitionFunction< - Vm, - <::Spec as DaSpec>::BlobTransaction, - Condition = ::ValidityCondition, - >, -{ - start_height: u64, - da_service: Da, - app: ST, - ledger_db: LedgerDB, - state_root: StateRoot, - listen_address: SocketAddr, -} - -impl StateTransitionRunner -where - Da: DaService + Clone + Send + Sync + 'static, - Vm: Zkvm, - ST: StateTransitionFunction< - Vm, - <::Spec as DaSpec>::BlobTransaction, - Condition = ::ValidityCondition, - >, -{ - /// Creates a new `StateTransitionRunner` runner. - pub fn new( - runner_config: RunnerConfig, - da_service: Da, - ledger_db: LedgerDB, - mut app: ST, - should_init_chain: bool, - genesis_config: InitialState, - ) -> Result { - let rpc_config = runner_config.rpc_config; - - let prev_state_root = { - // Check if the rollup has previously been initialized - if should_init_chain { - info!("No history detected. Initializing chain..."); - let ret_hash = app.init_chain(genesis_config); - info!("Chain initialization is done."); - ret_hash - } else { - debug!("Chain is already initialized. Skipping initialization."); - app.get_current_state_root()? - } - }; - - let listen_address = SocketAddr::new(rpc_config.bind_host.parse()?, rpc_config.bind_port); - - // Start the main rollup loop - let item_numbers = ledger_db.get_next_items_numbers(); - let last_slot_processed_before_shutdown = item_numbers.slot_number - 1; - let start_height = runner_config.start_height + last_slot_processed_before_shutdown; - - Ok(Self { - start_height, - da_service, - app, - ledger_db, - state_root: prev_state_root, - listen_address, - }) - } - - /// Starts a RPC server with provided rpc methods. - pub async fn start_rpc_server( - &self, - methods: RpcModule<()>, - channel: Option>, - ) { - let listen_address = self.listen_address; - let _handle = tokio::spawn(async move { - let server = jsonrpsee::server::ServerBuilder::default() - .build([listen_address].as_ref()) - .await - .unwrap(); - - let bound_address = server.local_addr().unwrap(); - if let Some(channel) = channel { - channel.send(bound_address).unwrap(); - } - info!("Starting RPC server at {} ", &bound_address); - - let _server_handle = server.start(methods).unwrap(); - futures::future::pending::<()>().await; - }); - } - - /// Runs the rollup. - pub async fn run(&mut self) -> Result<(), anyhow::Error> { - for height in self.start_height.. { - debug!("Requesting data for height {}", height,); - - let filtered_block = self.da_service.get_finalized_at(height).await?; - let mut blobs = self.da_service.extract_relevant_txs(&filtered_block); - - info!( - "Extracted {} relevant blobs at height {}: {:?}", - blobs.len(), - height, - blobs - .iter() - .map(|b| format!( - "sequencer={} blob_hash=0x{}", - b.sender(), - hex::encode(b.hash()) - )) - .collect::>() - ); - - let mut data_to_commit = SlotCommit::new(filtered_block.clone()); - - let slot_result = self - .app - .apply_slot(Default::default(), &filtered_block, &mut blobs); - for receipt in slot_result.batch_receipts { - data_to_commit.add_batch(receipt); - } - let next_state_root = slot_result.state_root; - - self.ledger_db.commit_slot(data_to_commit)?; - self.state_root = next_state_root; - } - - Ok(()) - } -} +#[cfg(feature = "native")] +pub use runner::*; diff --git a/full-node/sov-stf-runner/src/runner.rs b/full-node/sov-stf-runner/src/runner.rs new file mode 100644 index 000000000..065c8fc04 --- /dev/null +++ b/full-node/sov-stf-runner/src/runner.rs @@ -0,0 +1,156 @@ +use std::net::SocketAddr; + +use jsonrpsee::RpcModule; +use sov_db::ledger_db::{LedgerDB, SlotCommit}; +use sov_rollup_interface::da::{BlobReaderTrait, DaSpec}; +use sov_rollup_interface::services::da::DaService; +use sov_rollup_interface::stf::StateTransitionFunction; +use sov_rollup_interface::zk::Zkvm; +use tokio::sync::oneshot; +use tracing::{debug, info}; + +use crate::RunnerConfig; + +type StateRoot = ::Spec as DaSpec>::BlobTransaction, +>>::StateRoot; + +type InitialState = ::Spec as DaSpec>::BlobTransaction, +>>::InitialState; + +/// Combines `DaService` with `StateTransitionFunction` and "runs" the rollup. +pub struct StateTransitionRunner +where + Da: DaService, + Vm: Zkvm, + ST: StateTransitionFunction< + Vm, + <::Spec as DaSpec>::BlobTransaction, + Condition = ::ValidityCondition, + >, +{ + start_height: u64, + da_service: Da, + app: ST, + ledger_db: LedgerDB, + state_root: StateRoot, + listen_address: SocketAddr, +} + +impl StateTransitionRunner +where + Da: DaService + Clone + Send + Sync + 'static, + Vm: Zkvm, + ST: StateTransitionFunction< + Vm, + <::Spec as DaSpec>::BlobTransaction, + Condition = ::ValidityCondition, + >, +{ + /// Creates a new `StateTransitionRunner` runner. + pub fn new( + runner_config: RunnerConfig, + da_service: Da, + ledger_db: LedgerDB, + mut app: ST, + should_init_chain: bool, + genesis_config: InitialState, + ) -> Result { + let rpc_config = runner_config.rpc_config; + + let prev_state_root = { + // Check if the rollup has previously been initialized + if should_init_chain { + info!("No history detected. Initializing chain..."); + let ret_hash = app.init_chain(genesis_config); + info!("Chain initialization is done."); + ret_hash + } else { + debug!("Chain is already initialized. Skipping initialization."); + app.get_current_state_root()? + } + }; + + let listen_address = SocketAddr::new(rpc_config.bind_host.parse()?, rpc_config.bind_port); + + // Start the main rollup loop + let item_numbers = ledger_db.get_next_items_numbers(); + let last_slot_processed_before_shutdown = item_numbers.slot_number - 1; + let start_height = runner_config.start_height + last_slot_processed_before_shutdown; + + Ok(Self { + start_height, + da_service, + app, + ledger_db, + state_root: prev_state_root, + listen_address, + }) + } + + /// Starts a RPC server with provided rpc methods. + pub async fn start_rpc_server( + &self, + methods: RpcModule<()>, + channel: Option>, + ) { + let listen_address = self.listen_address; + let _handle = tokio::spawn(async move { + let server = jsonrpsee::server::ServerBuilder::default() + .build([listen_address].as_ref()) + .await + .unwrap(); + + let bound_address = server.local_addr().unwrap(); + if let Some(channel) = channel { + channel.send(bound_address).unwrap(); + } + info!("Starting RPC server at {} ", &bound_address); + + let _server_handle = server.start(methods).unwrap(); + futures::future::pending::<()>().await; + }); + } + + /// Runs the rollup. + pub async fn run(&mut self) -> Result<(), anyhow::Error> { + for height in self.start_height.. { + debug!("Requesting data for height {}", height,); + + let filtered_block = self.da_service.get_finalized_at(height).await?; + let mut blobs = self.da_service.extract_relevant_txs(&filtered_block); + + info!( + "Extracted {} relevant blobs at height {}: {:?}", + blobs.len(), + height, + blobs + .iter() + .map(|b| format!( + "sequencer={} blob_hash=0x{}", + b.sender(), + hex::encode(b.hash()) + )) + .collect::>() + ); + + let mut data_to_commit = SlotCommit::new(filtered_block.clone()); + + let slot_result = self + .app + .apply_slot(Default::default(), &filtered_block, &mut blobs); + for receipt in slot_result.batch_receipts { + data_to_commit.add_batch(receipt); + } + let next_state_root = slot_result.state_root; + + self.ledger_db.commit_slot(data_to_commit)?; + self.state_root = next_state_root; + } + + Ok(()) + } +} From 90183efd04aa3cd3662534873ecf71390a64a33d Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Fri, 8 Sep 2023 12:00:03 -0500 Subject: [PATCH 03/21] WIP: Fix chain-state signature. Done except for borsh --- adapters/celestia/src/verifier/mod.rs | 2 +- examples/demo-rollup/benches/rollup_bench.rs | 3 +- .../benches/rollup_coarse_measure.rs | 3 +- examples/demo-simple-stf/README.md | 6 +- examples/demo-simple-stf/src/lib.rs | 13 ++-- examples/demo-simple-stf/tests/stf_test.rs | 11 ++-- examples/demo-stf/Cargo.toml | 2 +- full-node/sov-stf-runner/src/runner.rs | 36 ++++------ .../src/chain_state/helpers.rs | 26 ++++++-- .../src/chain_state/tests.rs | 26 +++++--- .../sov-attester-incentives/src/call.rs | 29 ++++---- .../sov-attester-incentives/src/genesis.rs | 2 + .../sov-attester-incentives/src/lib.rs | 4 +- .../src/tests/attestation_proccessing.rs | 12 ++-- .../src/tests/challenger.rs | 20 +++--- .../src/tests/helpers.rs | 8 ++- .../src/tests/invariant.rs | 10 +-- .../src/tests/unbonding.rs | 2 +- .../sov-blob-storage/src/capabilities.rs | 7 +- .../sov-blob-storage/src/lib.rs | 7 +- .../tests/capability_tests.rs | 66 +++++++++++++++---- .../sov-chain-state/Cargo.toml | 1 + .../sov-chain-state/src/call.rs | 5 +- .../sov-chain-state/src/hooks.rs | 20 ++++-- .../sov-chain-state/src/lib.rs | 55 ++++++++-------- .../sov-chain-state/src/query.rs | 7 +- .../sov-chain-state/tests/all_tests.rs | 29 +++++--- module-system/sov-modules-api/src/hooks.rs | 4 +- .../sov-modules-stf-template/src/lib.rs | 20 +++--- rollup-interface/src/state_machine/da.rs | 7 +- .../src/state_machine/mocks/da.rs | 29 +++++++- .../state_machine/mocks/validity_condition.rs | 11 +++- .../src/state_machine/optimistic.rs | 9 +-- rollup-interface/src/state_machine/stf.rs | 13 ++-- rollup-interface/src/state_machine/zk/mod.rs | 16 +++-- 35 files changed, 337 insertions(+), 184 deletions(-) diff --git a/adapters/celestia/src/verifier/mod.rs b/adapters/celestia/src/verifier/mod.rs index 7e2856e6e..0f447fb95 100644 --- a/adapters/celestia/src/verifier/mod.rs +++ b/adapters/celestia/src/verifier/mod.rs @@ -89,7 +89,7 @@ impl AsRef for tendermint::Hash { impl BlockHash for TmHash {} -#[derive(serde::Serialize, serde::Deserialize)] +#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)] pub struct CelestiaSpec; impl DaSpec for CelestiaSpec { diff --git a/examples/demo-rollup/benches/rollup_bench.rs b/examples/demo-rollup/benches/rollup_bench.rs index 502d43c5f..5bc52fe3a 100644 --- a/examples/demo-rollup/benches/rollup_bench.rs +++ b/examples/demo-rollup/benches/rollup_bench.rs @@ -86,7 +86,8 @@ fn rollup_bench(_bench: &mut Criterion) { let mut data_to_commit = SlotCommit::new(filtered_block.clone()); let apply_block_result = demo.apply_slot( Default::default(), - data_to_commit.slot_data(), + &filtered_block.header, + &filtered_block.validity_cond, &mut blobs[height as usize], ); for receipts in apply_block_result.batch_receipts { diff --git a/examples/demo-rollup/benches/rollup_coarse_measure.rs b/examples/demo-rollup/benches/rollup_coarse_measure.rs index 651b084be..8229ed602 100644 --- a/examples/demo-rollup/benches/rollup_coarse_measure.rs +++ b/examples/demo-rollup/benches/rollup_coarse_measure.rs @@ -142,7 +142,8 @@ async fn main() -> Result<(), anyhow::Error> { let apply_block_results = demo.apply_slot( Default::default(), - data_to_commit.slot_data(), + &filtered_block.header, + &filtered_block.validity_cond, &mut blobs[height as usize], ); diff --git a/examples/demo-simple-stf/README.md b/examples/demo-simple-stf/README.md index 37da306ed..c576f9e4c 100644 --- a/examples/demo-simple-stf/README.md +++ b/examples/demo-simple-stf/README.md @@ -161,7 +161,7 @@ You can find more details in the `stf_test.rs` file. The following test checks the rollup logic. In the test, we call `init_chain, begin_slot, and end_slot` for completeness, even though these methods do nothing. -```rust +```rust use demo_simple_stf::{ApplySlotResult, CheckHashPreimageStf}; use sov_rollup_interface::mocks::{MockAddress, MockBlob, MockBlock, MockValidityCond, MockZkvm}; use sov_rollup_interface::stf::StateTransitionFunction; @@ -177,9 +177,9 @@ fn test_stf() { let data = MockBlock::default(); let mut blobs = [test_blob]; - StateTransitionFunction::::init_chain(stf, ()); + StateTransitionFunction::::init_chain(stf, ()); - let result = StateTransitionFunction::::apply_slot( + let result = StateTransitionFunction::::apply_slot( stf, (), &data, diff --git a/examples/demo-simple-stf/src/lib.rs b/examples/demo-simple-stf/src/lib.rs index 971350b80..bf9cd7bd6 100644 --- a/examples/demo-simple-stf/src/lib.rs +++ b/examples/demo-simple-stf/src/lib.rs @@ -3,8 +3,7 @@ use std::marker::PhantomData; use sha2::Digest; -use sov_rollup_interface::da::BlobReaderTrait; -use sov_rollup_interface::services::da::SlotData; +use sov_rollup_interface::da::{BlobReaderTrait, DaSpec}; use sov_rollup_interface::stf::{BatchReceipt, SlotResult, StateTransitionFunction}; use sov_rollup_interface::zk::{ValidityCondition, Zkvm}; @@ -25,7 +24,7 @@ pub enum ApplySlotResult { Success, } -impl StateTransitionFunction +impl StateTransitionFunction for CheckHashPreimageStf { // Since our rollup is stateless, we don't need to consider the StateRoot. @@ -51,10 +50,11 @@ impl StateTransitionFunct // Do nothing } - fn apply_slot<'a, I, Data>( + fn apply_slot<'a, I>( &mut self, _witness: Self::Witness, - _slot_data: &Data, + _slot_header: &Da::BlockHeader, + _validity_condition: &Da::ValidityCondition, blobs: I, ) -> SlotResult< Self::StateRoot, @@ -63,8 +63,7 @@ impl StateTransitionFunct Self::Witness, > where - I: IntoIterator, - Data: SlotData, + I: IntoIterator, { let mut receipts = vec![]; for blob in blobs { diff --git a/examples/demo-simple-stf/tests/stf_test.rs b/examples/demo-simple-stf/tests/stf_test.rs index b9d1f48a1..ee1c53314 100644 --- a/examples/demo-simple-stf/tests/stf_test.rs +++ b/examples/demo-simple-stf/tests/stf_test.rs @@ -1,5 +1,7 @@ use demo_simple_stf::{ApplySlotResult, CheckHashPreimageStf}; -use sov_rollup_interface::mocks::{MockAddress, MockBlob, MockBlock, MockValidityCond, MockZkvm}; +use sov_rollup_interface::mocks::{ + MockAddress, MockBlob, MockBlockHeader, MockDaSpec, MockValidityCond, MockZkvm, +}; use sov_rollup_interface::stf::StateTransitionFunction; #[test] @@ -7,7 +9,7 @@ fn test_stf_success() { let address = MockAddress { addr: [1; 32] }; let stf = &mut CheckHashPreimageStf::::default(); - StateTransitionFunction::::init_chain(stf, ()); + StateTransitionFunction::::init_chain(stf, ()); let mut blobs = { let incorrect_preimage = vec![1; 32]; @@ -19,10 +21,11 @@ fn test_stf_success() { ] }; - let result = StateTransitionFunction::::apply_slot( + let result = StateTransitionFunction::::apply_slot( stf, (), - &MockBlock::default(), + &MockBlockHeader::default(), + &MockValidityCond::default(), &mut blobs, ); diff --git a/examples/demo-stf/Cargo.toml b/examples/demo-stf/Cargo.toml index bbc6dd33f..d55b6aaec 100644 --- a/examples/demo-stf/Cargo.toml +++ b/examples/demo-stf/Cargo.toml @@ -61,7 +61,7 @@ native = [ "sov-rollup-interface/mocks", "sov-modules-stf-template/native", "sov-sequencer", - "sov-stf-runner", + "sov-stf-runner/native", "clap", "serde_json", "jsonrpsee", diff --git a/full-node/sov-stf-runner/src/runner.rs b/full-node/sov-stf-runner/src/runner.rs index 065c8fc04..4bf9a0430 100644 --- a/full-node/sov-stf-runner/src/runner.rs +++ b/full-node/sov-stf-runner/src/runner.rs @@ -2,6 +2,7 @@ use std::net::SocketAddr; use jsonrpsee::RpcModule; use sov_db::ledger_db::{LedgerDB, SlotCommit}; +use sov_modules_api::SlotData; use sov_rollup_interface::da::{BlobReaderTrait, DaSpec}; use sov_rollup_interface::services::da::DaService; use sov_rollup_interface::stf::StateTransitionFunction; @@ -11,32 +12,22 @@ use tracing::{debug, info}; use crate::RunnerConfig; -type StateRoot = ::Spec as DaSpec>::BlobTransaction, ->>::StateRoot; +type StateRoot = >::StateRoot; -type InitialState = ::Spec as DaSpec>::BlobTransaction, ->>::InitialState; +type InitialState = >::InitialState; /// Combines `DaService` with `StateTransitionFunction` and "runs" the rollup. pub struct StateTransitionRunner where Da: DaService, Vm: Zkvm, - ST: StateTransitionFunction< - Vm, - <::Spec as DaSpec>::BlobTransaction, - Condition = ::ValidityCondition, - >, + ST: StateTransitionFunction::ValidityCondition>, { start_height: u64, da_service: Da, app: ST, ledger_db: LedgerDB, - state_root: StateRoot, + state_root: StateRoot, listen_address: SocketAddr, } @@ -44,11 +35,7 @@ impl StateTransitionRunner where Da: DaService + Clone + Send + Sync + 'static, Vm: Zkvm, - ST: StateTransitionFunction< - Vm, - <::Spec as DaSpec>::BlobTransaction, - Condition = ::ValidityCondition, - >, + ST: StateTransitionFunction::ValidityCondition>, { /// Creates a new `StateTransitionRunner` runner. pub fn new( @@ -57,7 +44,7 @@ where ledger_db: LedgerDB, mut app: ST, should_init_chain: bool, - genesis_config: InitialState, + genesis_config: InitialState, ) -> Result { let rpc_config = runner_config.rpc_config; @@ -139,9 +126,12 @@ where let mut data_to_commit = SlotCommit::new(filtered_block.clone()); - let slot_result = self - .app - .apply_slot(Default::default(), &filtered_block, &mut blobs); + let slot_result = self.app.apply_slot( + Default::default(), + &filtered_block.header(), + &filtered_block.validity_condition(), + &mut blobs, + ); for receipt in slot_result.batch_receipts { data_to_commit.add_batch(receipt); } diff --git a/module-system/module-implementations/integration-tests/src/chain_state/helpers.rs b/module-system/module-implementations/integration-tests/src/chain_state/helpers.rs index da39054be..8aa0bddd1 100644 --- a/module-system/module-implementations/integration-tests/src/chain_state/helpers.rs +++ b/module-system/module-implementations/integration-tests/src/chain_state/helpers.rs @@ -1,3 +1,4 @@ +use borsh::{BorshDeserialize, BorshSerialize}; use sov_chain_state::{ChainState, ChainStateConfig}; use sov_modules_api::capabilities::{BlobRefOrOwned, BlobSelector}; use sov_modules_api::hooks::{ApplyBlobHooks, SlotHooks, TxHooks}; @@ -59,15 +60,21 @@ impl ApplyBlobHooks for TestRuntime } } -impl SlotHooks for TestRuntime { +impl SlotHooks for TestRuntime +where + Da::SlotHash: BorshDeserialize + BorshSerialize, + Da::ValidityCondition: BorshDeserialize + BorshSerialize, +{ type Context = C; fn begin_slot_hook( &self, - slot_data: &impl sov_modules_api::SlotData, + slot_header: &Da::BlockHeader, + validity_condition: &Da::ValidityCondition, working_set: &mut sov_state::WorkingSet<::Storage>, ) { - self.chain_state.begin_slot_hook(slot_data, working_set) + self.chain_state + .begin_slot_hook(slot_header, validity_condition, working_set) } fn end_slot_hook( @@ -97,7 +104,12 @@ where } } -impl Runtime for TestRuntime {} +impl Runtime for TestRuntime +where + Da::SlotHash: BorshDeserialize + BorshSerialize, + Da::ValidityCondition: BorshDeserialize + BorshSerialize, +{ +} pub(crate) fn create_demo_genesis_config( admin: ::Address, @@ -112,6 +124,10 @@ pub(crate) fn create_demo_genesis_config( /// Clones the [`AppTemplate`]'s [`Storage`] and extract the underlying [`WorkingSet`] pub(crate) fn get_working_set( app_template: &AppTemplate>, -) -> sov_state::WorkingSet<::Storage> { +) -> sov_state::WorkingSet<::Storage> +where + Da::SlotHash: BorshDeserialize + BorshSerialize, + Da::ValidityCondition: BorshDeserialize + BorshSerialize, +{ sov_state::WorkingSet::new(app_template.current_storage.clone()) } diff --git a/module-system/module-implementations/integration-tests/src/chain_state/tests.rs b/module-system/module-implementations/integration-tests/src/chain_state/tests.rs index 6ef675bfd..5df74427f 100644 --- a/module-system/module-implementations/integration-tests/src/chain_state/tests.rs +++ b/module-system/module-implementations/integration-tests/src/chain_state/tests.rs @@ -66,7 +66,12 @@ fn test_simple_value_setter_with_chain_state() { assert_eq!(new_height_storage, 0, "The initial height was not computed"); - let result = app_template.apply_slot(Default::default(), &slot_data, &mut [blob.clone()]); + let result = app_template.apply_slot( + Default::default(), + &slot_data.header, + &slot_data.validity_cond, + &mut [blob.clone()], + ); assert_eq!(1, result.batch_receipts.len()); let apply_blob_outcome = result.batch_receipts[0].clone(); @@ -96,13 +101,13 @@ fn test_simple_value_setter_with_chain_state() { assert_eq!(new_height_storage, 1, "The new height did not update"); // Check the tx in progress - let new_tx_in_progress: TransitionInProgress = chain_state_ref + let new_tx_in_progress: TransitionInProgress = chain_state_ref .get_in_progress_transition(&mut working_set) .unwrap(); assert_eq!( new_tx_in_progress, - TransitionInProgress::::new([10; 32], MockValidityCond::default()), + TransitionInProgress::::new(MockHash([10; 32]), MockValidityCond::default()), "The new transition has not been correctly stored" ); @@ -119,7 +124,12 @@ fn test_simple_value_setter_with_chain_state() { blobs: Default::default(), }; - let result = app_template.apply_slot(Default::default(), &new_slot_data, &mut [blob]); + let result = app_template.apply_slot( + Default::default(), + &new_slot_data.header, + &new_slot_data.validity_cond, + &mut [blob], + ); assert_eq!(1, result.batch_receipts.len()); let apply_blob_outcome = result.batch_receipts[0].clone(); @@ -143,24 +153,24 @@ fn test_simple_value_setter_with_chain_state() { assert_eq!(new_height_storage, 2, "The new height did not update"); // Check the tx in progress - let new_tx_in_progress: TransitionInProgress = chain_state_ref + let new_tx_in_progress: TransitionInProgress = chain_state_ref .get_in_progress_transition(&mut working_set) .unwrap(); assert_eq!( new_tx_in_progress, - TransitionInProgress::::new([20; 32], MockValidityCond::default()), + TransitionInProgress::::new([20; 32].into(), MockValidityCond::default()), "The new transition has not been correctly stored" ); - let last_tx_stored: StateTransitionId = chain_state_ref + let last_tx_stored: StateTransitionId = chain_state_ref .get_historical_transitions(1, &mut working_set) .unwrap(); assert_eq!( last_tx_stored, StateTransitionId::new( - [10; 32], + [10; 32].into(), new_root_hash.unwrap(), MockValidityCond::default() ) diff --git a/module-system/module-implementations/sov-attester-incentives/src/call.rs b/module-system/module-implementations/sov-attester-incentives/src/call.rs index b3916d922..468732806 100644 --- a/module-system/module-implementations/sov-attester-incentives/src/call.rs +++ b/module-system/module-implementations/sov-attester-incentives/src/call.rs @@ -5,7 +5,7 @@ use borsh::{BorshDeserialize, BorshSerialize}; use sov_bank::{Amount, Coins}; use sov_chain_state::TransitionHeight; use sov_modules_api::optimistic::Attestation; -use sov_modules_api::{CallResponse, Spec, StateTransition, ValidityConditionChecker}; +use sov_modules_api::{CallResponse, DaSpec, Spec, StateTransition, ValidityConditionChecker}; use sov_state::storage::StorageProof; use sov_state::{Storage, WorkingSet}; use thiserror::Error; @@ -14,7 +14,7 @@ use crate::{AttesterIncentives, UnbondingInfo}; /// This enumeration represents the available call messages for interacting with the `AttesterIncentives` module. #[derive(BorshDeserialize, BorshSerialize, Debug)] -pub enum CallMessage { +pub enum CallMessage { /// Bonds an attester, the parameter is the bond amount BondAttester(Amount), /// Start the first phase of the two-phase unbonding process @@ -26,7 +26,7 @@ pub enum CallMessage { /// Unbonds a challenger UnbondChallenger, /// Processes an attestation. - ProcessAttestation(Attestation::Storage as Storage>::Proof>>), + ProcessAttestation(Attestation::Storage as Storage>::Proof>>), /// Processes a challenge. The challenge is encoded as a [`Vec`]. The second parameter is the transition number ProcessChallenge(Vec, TransitionHeight), } @@ -118,6 +118,8 @@ where Vm: sov_modules_api::Zkvm, Da: sov_modules_api::DaSpec, Checker: ValidityConditionChecker, + Da::SlotHash: BorshDeserialize + BorshSerialize, + Da::ValidityCondition: BorshDeserialize + BorshSerialize, { /// This returns the address of the reward token supply pub fn get_reward_token_supply_address( @@ -383,7 +385,7 @@ where fn check_bonding_proof( &self, context: &C, - attestation: &Attestation::Proof>>, + attestation: &Attestation::Proof>>, working_set: &mut WorkingSet, ) -> anyhow::Result<(), AttesterIncentiveErrors> { let bonding_root = { @@ -440,7 +442,7 @@ where &self, claimed_transition_height: TransitionHeight, attester: &C::Address, - attestation: &Attestation::Proof>>, + attestation: &Attestation::Proof>>, working_set: &mut WorkingSet, ) -> anyhow::Result { if let Some(curr_tx) = self @@ -475,7 +477,7 @@ where &self, claimed_transition_height: TransitionHeight, attester: &C::Address, - attestation: &Attestation::Proof>>, + attestation: &Attestation::Proof>>, working_set: &mut WorkingSet, ) -> anyhow::Result { // Normal state @@ -540,7 +542,7 @@ where pub(crate) fn process_attestation( &self, context: &C, - attestation: Attestation::Proof>>, + attestation: Attestation::Proof>>, working_set: &mut WorkingSet, ) -> anyhow::Result { // We first need to check that the attester is still in the bonding set @@ -636,7 +638,7 @@ where fn check_challenge_outputs_against_transition( &self, - public_outputs: StateTransition, + public_outputs: StateTransition, height: &TransitionHeight, condition_checker: &mut impl ValidityConditionChecker, working_set: &mut WorkingSet, @@ -663,7 +665,7 @@ where return Err(SlashingReason::InvalidInitialHash); } - if public_outputs.slot_hash != transition.da_block_hash() { + if &public_outputs.slot_hash != transition.da_block_hash() { return Err(SlashingReason::TransitionInvalid); } @@ -723,12 +725,9 @@ where ) })?; - let public_outputs_opt: anyhow::Result> = - Vm::verify_and_extract_output::( - proof, - &code_commitment, - ) - .map_err(|e| anyhow::format_err!("{:?}", e)); + let public_outputs_opt: anyhow::Result> = + Vm::verify_and_extract_output::(proof, &code_commitment) + .map_err(|e| anyhow::format_err!("{:?}", e)); // Don't return an error for invalid proofs - those are expected and shouldn't cause reverts. match public_outputs_opt { diff --git a/module-system/module-implementations/sov-attester-incentives/src/genesis.rs b/module-system/module-implementations/sov-attester-incentives/src/genesis.rs index 6b620b800..c3e084333 100644 --- a/module-system/module-implementations/sov-attester-incentives/src/genesis.rs +++ b/module-system/module-implementations/sov-attester-incentives/src/genesis.rs @@ -14,6 +14,8 @@ where P: BorshDeserialize + BorshSerialize, Da: sov_modules_api::DaSpec, Checker: ValidityConditionChecker, + Da::ValidityCondition: BorshSerialize + BorshDeserialize, + Da::SlotHash: BorshSerialize + BorshDeserialize, { pub(crate) fn init_module( &self, diff --git a/module-system/module-implementations/sov-attester-incentives/src/lib.rs b/module-system/module-implementations/sov-attester-incentives/src/lib.rs index b9e335dfd..b216729e5 100644 --- a/module-system/module-implementations/sov-attester-incentives/src/lib.rs +++ b/module-system/module-implementations/sov-attester-incentives/src/lib.rs @@ -157,12 +157,14 @@ where P: BorshDeserialize + BorshSerialize, Da: DaSpec, Checker: ValidityConditionChecker, + Da::ValidityCondition: BorshSerialize + BorshDeserialize, + Da::SlotHash: BorshSerialize + BorshDeserialize, { type Context = C; type Config = AttesterIncentivesConfig; - type CallMessage = call::CallMessage; + type CallMessage = call::CallMessage; fn genesis( &self, diff --git a/module-system/module-implementations/sov-attester-incentives/src/tests/attestation_proccessing.rs b/module-system/module-implementations/sov-attester-incentives/src/tests/attestation_proccessing.rs index 6e9ade45d..ebb092bac 100644 --- a/module-system/module-implementations/sov-attester-incentives/src/tests/attestation_proccessing.rs +++ b/module-system/module-implementations/sov-attester-incentives/src/tests/attestation_proccessing.rs @@ -44,7 +44,7 @@ fn test_process_valid_attestation() { { let attestation = Attestation { initial_state_root: initial_transition.state_root, - da_block_hash: [1; 32], + da_block_hash: [1; 32].into(), post_state_root: transition_1.state_root, proof_of_bond: sov_modules_api::optimistic::ProofOfBond { claimed_transition_num: INIT_HEIGHT + 1, @@ -61,7 +61,7 @@ fn test_process_valid_attestation() { { let attestation = Attestation { initial_state_root: transition_1.state_root, - da_block_hash: [2; 32], + da_block_hash: [2; 32].into(), post_state_root: transition_2.state_root, proof_of_bond: sov_modules_api::optimistic::ProofOfBond { claimed_transition_num: INIT_HEIGHT + 2, @@ -135,7 +135,7 @@ fn test_burn_on_invalid_attestation() { { let attestation = Attestation { initial_state_root: initial_transition.state_root, - da_block_hash: [1; 32], + da_block_hash: [1; 32].into(), post_state_root: transition_1.state_root, proof_of_bond: sov_modules_api::optimistic::ProofOfBond { claimed_transition_num: INIT_HEIGHT + 1, @@ -170,7 +170,7 @@ fn test_burn_on_invalid_attestation() { { let attestation = Attestation { initial_state_root: initial_transition.state_root, - da_block_hash: [1; 32], + da_block_hash: [1; 32].into(), post_state_root: transition_1.state_root, proof_of_bond: sov_modules_api::optimistic::ProofOfBond { claimed_transition_num: INIT_HEIGHT + 1, @@ -187,7 +187,7 @@ fn test_burn_on_invalid_attestation() { { let attestation = Attestation { initial_state_root: initial_transition.state_root, - da_block_hash: [2; 32], + da_block_hash: [2; 32].into(), post_state_root: transition_2.state_root, proof_of_bond: sov_modules_api::optimistic::ProofOfBond { claimed_transition_num: INIT_HEIGHT + 2, @@ -240,7 +240,7 @@ fn test_burn_on_invalid_attestation() { { let attestation = Attestation { initial_state_root: transition_1.state_root, - da_block_hash: [2; 32], + da_block_hash: [2; 32].into(), post_state_root: transition_1.state_root, proof_of_bond: sov_modules_api::optimistic::ProofOfBond { claimed_transition_num: INIT_HEIGHT + 2, diff --git a/module-system/module-implementations/sov-attester-incentives/src/tests/challenger.rs b/module-system/module-implementations/sov-attester-incentives/src/tests/challenger.rs index 01e5a7303..942255d00 100644 --- a/module-system/module-implementations/sov-attester-incentives/src/tests/challenger.rs +++ b/module-system/module-implementations/sov-attester-incentives/src/tests/challenger.rs @@ -63,9 +63,9 @@ fn test_valid_challenge() { }; { - let transition = StateTransition { + let transition = StateTransition:: { initial_state_root: initial_transition.state_root, - slot_hash: [1; 32], + slot_hash: [1; 32].into(), final_state_root: transition_1.state_root, rewarded_address: challenger_address, validity_condition: MockValidityCond { is_valid: true }, @@ -196,9 +196,9 @@ fn test_invalid_challenge() { sender: challenger_address, }; - let transition = StateTransition { + let transition: StateTransition = StateTransition { initial_state_root: initial_transition.state_root, - slot_hash: [1; 32], + slot_hash: [1; 32].into(), final_state_root: transition_1.state_root, rewarded_address: challenger_address, validity_condition: MockValidityCond { is_valid: true }, @@ -258,9 +258,9 @@ fn test_invalid_challenge() { ); // Bad slot hash - let bad_transition = StateTransition { + let bad_transition = StateTransition:: { initial_state_root: initial_transition.state_root, - slot_hash: [2; 32], + slot_hash: [2; 32].into(), final_state_root: transition_1.state_root, rewarded_address: challenger_address, validity_condition: MockValidityCond { is_valid: true }, @@ -286,9 +286,9 @@ fn test_invalid_challenge() { ); // Bad validity condition - let bad_transition = StateTransition { + let bad_transition = StateTransition:: { initial_state_root: initial_transition.state_root, - slot_hash: [1; 32], + slot_hash: [1; 32].into(), final_state_root: transition_1.state_root, rewarded_address: challenger_address, validity_condition: MockValidityCond { is_valid: false }, @@ -314,9 +314,9 @@ fn test_invalid_challenge() { ); // Bad initial root - let bad_transition = StateTransition { + let bad_transition = StateTransition:: { initial_state_root: transition_1.state_root, - slot_hash: [1; 32], + slot_hash: [1; 32].into(), final_state_root: transition_1.state_root, rewarded_address: challenger_address, validity_condition: MockValidityCond { is_valid: true }, diff --git a/module-system/module-implementations/sov-attester-incentives/src/tests/helpers.rs b/module-system/module-implementations/sov-attester-incentives/src/tests/helpers.rs index 5ee2f0c86..4c06a3828 100644 --- a/module-system/module-implementations/sov-attester-incentives/src/tests/helpers.rs +++ b/module-system/module-implementations/sov-attester-incentives/src/tests/helpers.rs @@ -173,9 +173,11 @@ pub(crate) fn execution_simulation BlobSelector for BlobStorage { +impl BlobSelector for BlobStorage +where + Da::ValidityCondition: BorshDeserialize + BorshSerialize, + Da::SlotHash: BorshDeserialize + BorshSerialize, +{ type Context = C; fn get_blobs_for_this_slot<'a, I>( diff --git a/module-system/module-implementations/sov-blob-storage/src/lib.rs b/module-system/module-implementations/sov-blob-storage/src/lib.rs index 3a06fdbac..a799a4a3b 100644 --- a/module-system/module-implementations/sov-blob-storage/src/lib.rs +++ b/module-system/module-implementations/sov-blob-storage/src/lib.rs @@ -4,6 +4,7 @@ mod capabilities; #[cfg(feature = "native")] mod query; +use borsh::{BorshDeserialize, BorshSerialize}; #[cfg(feature = "native")] pub use query::{BlobStorageRpcImpl, BlobStorageRpcServer, Response}; use sov_chain_state::TransitionHeight; @@ -36,7 +37,11 @@ pub struct BlobStorage } /// Non standard methods for blob storage -impl BlobStorage { +impl BlobStorage +where + Da::ValidityCondition: BorshDeserialize + BorshSerialize, + Da::SlotHash: BorshDeserialize + BorshSerialize, +{ /// Store blobs for given block number, overwrite if already exists pub fn store_blobs( &self, diff --git a/module-system/module-implementations/sov-blob-storage/tests/capability_tests.rs b/module-system/module-implementations/sov-blob-storage/tests/capability_tests.rs index 957dff79d..f31d1866a 100644 --- a/module-system/module-implementations/sov-blob-storage/tests/capability_tests.rs +++ b/module-system/module-implementations/sov-blob-storage/tests/capability_tests.rs @@ -133,7 +133,11 @@ fn priority_sequencer_flow() { validity_cond: valid_condition, blobs: slot_1_blobs, }; - chain_state.begin_slot_hook(&slot_1_data, &mut working_set); + chain_state.begin_slot_hook( + &slot_1_data.header, + &slot_1_data.validity_cond, + &mut working_set, + ); let mut execute_in_slot_1 = as BlobSelector>::get_blobs_for_this_slot( &blob_storage, &mut slot_1_data.blobs, @@ -166,7 +170,11 @@ fn priority_sequencer_flow() { validity_cond: valid_condition, blobs: slot_2_blobs, }; - chain_state.begin_slot_hook(&slot_2_data, &mut working_set); + chain_state.begin_slot_hook( + &slot_2_data.header, + &slot_2_data.validity_cond, + &mut working_set, + ); let mut execute_in_slot_2 = as BlobSelector>::get_blobs_for_this_slot( &blob_storage, &mut slot_2_data.blobs, @@ -188,7 +196,11 @@ fn priority_sequencer_flow() { validity_cond: valid_condition, blobs: slot_3_blobs, }; - chain_state.begin_slot_hook(&slot_3_data, &mut working_set); + chain_state.begin_slot_hook( + &slot_3_data.header, + &slot_3_data.validity_cond, + &mut working_set, + ); let mut execute_in_slot_3 = as BlobSelector>::get_blobs_for_this_slot( &blob_storage, &mut slot_3_data.blobs, @@ -209,7 +221,11 @@ fn priority_sequencer_flow() { validity_cond: valid_condition, blobs: Vec::new(), }; - chain_state.begin_slot_hook(&slot_4_data, &mut working_set); + chain_state.begin_slot_hook( + &slot_4_data.header, + &slot_4_data.validity_cond, + &mut working_set, + ); let mut execute_in_slot_4 = as BlobSelector>::get_blobs_for_this_slot( &blob_storage, &mut slot_4_data.blobs, @@ -300,7 +316,11 @@ fn test_blobs_from_non_registered_sequencers_are_not_saved() { validity_cond: valid_condition, blobs: slot_1_blobs, }; - chain_state.begin_slot_hook(&slot_1_data, &mut working_set); + chain_state.begin_slot_hook( + &slot_1_data.header, + &slot_1_data.validity_cond, + &mut working_set, + ); let mut execute_in_slot_1 = as BlobSelector>::get_blobs_for_this_slot( &blob_storage, &mut slot_1_data.blobs, @@ -319,7 +339,11 @@ fn test_blobs_from_non_registered_sequencers_are_not_saved() { validity_cond: valid_condition, blobs: Vec::new(), }; - chain_state.begin_slot_hook(&slot_2_data, &mut working_set); + chain_state.begin_slot_hook( + &slot_2_data.header, + &slot_2_data.validity_cond, + &mut working_set, + ); let mut execute_in_slot_2 = as BlobSelector>::get_blobs_for_this_slot( &blob_storage, &mut slot_2_data.blobs, @@ -407,7 +431,11 @@ fn test_blobs_no_deferred_without_preferred_sequencer() { validity_cond: valid_condition, blobs: slot_1_blobs, }; - chain_state.begin_slot_hook(&slot_1_data, &mut working_set); + chain_state.begin_slot_hook( + &slot_1_data.header, + &slot_1_data.validity_cond, + &mut working_set, + ); let mut execute_in_slot_1 = as BlobSelector>::get_blobs_for_this_slot( &blob_storage, &mut slot_1_data.blobs, @@ -428,7 +456,11 @@ fn test_blobs_no_deferred_without_preferred_sequencer() { validity_cond: valid_condition, blobs: Vec::new(), }; - chain_state.begin_slot_hook(&slot_2_data, &mut working_set); + chain_state.begin_slot_hook( + &slot_2_data.header, + &slot_2_data.validity_cond, + &mut working_set, + ); let execute_in_slot_2: Vec> = as BlobSelector>::get_blobs_for_this_slot( &blob_storage, @@ -518,7 +550,11 @@ fn deferred_blobs_are_first_after_preferred_sequencer_exit() { validity_cond: valid_condition, blobs: slot_1_blobs, }; - chain_state.begin_slot_hook(&slot_1_data, &mut working_set); + chain_state.begin_slot_hook( + &slot_1_data.header, + &slot_1_data.validity_cond, + &mut working_set, + ); let mut execute_in_slot_1 = as BlobSelector>::get_blobs_for_this_slot( &blob_storage, &mut slot_1_data.blobs, @@ -554,7 +590,11 @@ fn deferred_blobs_are_first_after_preferred_sequencer_exit() { validity_cond: valid_condition, blobs: slot_2_blobs, }; - chain_state.begin_slot_hook(&slot_2_data, &mut working_set); + chain_state.begin_slot_hook( + &slot_2_data.header, + &slot_2_data.validity_cond, + &mut working_set, + ); let mut execute_in_slot_2 = as BlobSelector>::get_blobs_for_this_slot( &blob_storage, &mut slot_2_data.blobs, @@ -576,7 +616,11 @@ fn deferred_blobs_are_first_after_preferred_sequencer_exit() { validity_cond: valid_condition, blobs: Vec::new(), }; - chain_state.begin_slot_hook(&slot_3_data, &mut working_set); + chain_state.begin_slot_hook( + &slot_3_data.header, + &slot_3_data.validity_cond, + &mut working_set, + ); let execute_in_slot_3: Vec> = as BlobSelector>::get_blobs_for_this_slot( &blob_storage, diff --git a/module-system/module-implementations/sov-chain-state/Cargo.toml b/module-system/module-implementations/sov-chain-state/Cargo.toml index 7855b8aa5..470941a50 100644 --- a/module-system/module-implementations/sov-chain-state/Cargo.toml +++ b/module-system/module-implementations/sov-chain-state/Cargo.toml @@ -20,6 +20,7 @@ jsonrpsee = { workspace = true, features = ["macros", "client-core", "server"], sov-modules-api = { path = "../../sov-modules-api", version = "0.1" } sov-state = { path = "../../sov-state", version = "0.1" } +sov-rollup-interface = { path = "../../../rollup-interface", version = "0.1" } [dev-dependencies] diff --git a/module-system/module-implementations/sov-chain-state/src/call.rs b/module-system/module-implementations/sov-chain-state/src/call.rs index 0112a54c7..d50f7dba6 100644 --- a/module-system/module-implementations/sov-chain-state/src/call.rs +++ b/module-system/module-implementations/sov-chain-state/src/call.rs @@ -1,3 +1,4 @@ +use borsh::{BorshDeserialize, BorshSerialize}; use sov_state::WorkingSet; use crate::{ChainState, StateTransitionId, TransitionHeight}; @@ -6,6 +7,8 @@ impl ChainState where C: sov_modules_api::Context, Da: sov_modules_api::DaSpec, + Da::ValidityCondition: BorshSerialize + BorshDeserialize, + Da::SlotHash: BorshSerialize + BorshDeserialize, { /// Increment the current slot height pub(crate) fn increment_slot_height(&self, working_set: &mut WorkingSet) { @@ -21,7 +24,7 @@ where pub(crate) fn store_state_transition( &self, height: TransitionHeight, - transition: StateTransitionId, + transition: StateTransitionId, working_set: &mut WorkingSet, ) { self.historical_transitions diff --git a/module-system/module-implementations/sov-chain-state/src/hooks.rs b/module-system/module-implementations/sov-chain-state/src/hooks.rs index 5b16f2d24..fa7f4d1ba 100644 --- a/module-system/module-implementations/sov-chain-state/src/hooks.rs +++ b/module-system/module-implementations/sov-chain-state/src/hooks.rs @@ -1,16 +1,23 @@ +use borsh::{BorshDeserialize, BorshSerialize}; use sov_modules_api::hooks::SlotHooks; -use sov_modules_api::{Context, SlotData, Spec}; +use sov_modules_api::{Context, Spec}; +use sov_rollup_interface::da::BlockHeaderTrait; use sov_state::{Storage, WorkingSet}; use super::ChainState; use crate::{StateTransitionId, TransitionInProgress}; -impl SlotHooks for ChainState { +impl SlotHooks for ChainState +where + Da::ValidityCondition: BorshSerialize + BorshDeserialize, + Da::SlotHash: BorshSerialize + BorshDeserialize, +{ type Context = C; fn begin_slot_hook( &self, - slot: &impl SlotData, + slot_header: &Da::BlockHeader, + validity_condition: &Da::ValidityCondition, working_set: &mut WorkingSet<::Storage>, ) { if self.genesis_hash.get(working_set).is_none() { @@ -24,7 +31,7 @@ impl SlotHooks for ChainState = { + let transition: StateTransitionId = { let last_transition_in_progress = self .in_progress_transition .get(working_set) @@ -50,12 +57,11 @@ impl SlotHooks for ChainState { - da_block_hash: [u8; 32], +pub struct StateTransitionId { + da_block_hash: Da::SlotHash, post_state_root: [u8; 32], - validity_condition: Cond, + validity_condition: Da::ValidityCondition, } -impl StateTransitionId { +impl StateTransitionId { /// Creates a new state transition. Only available for testing as we only want to create /// new state transitions from existing [`TransitionInProgress`]. pub fn new( - da_block_hash: [u8; 32], + da_block_hash: Da::SlotHash, post_state_root: [u8; 32], - validity_condition: Cond, + validity_condition: Da::ValidityCondition, ) -> Self { Self { da_block_hash, @@ -46,10 +46,10 @@ impl StateTransitionId { } } -impl StateTransitionId { +impl StateTransitionId { /// Compare the transition block hash and state root with the provided input couple. If /// the pairs are equal, return [`true`]. - pub fn compare_hashes(&self, da_block_hash: &[u8; 32], post_state_root: &[u8; 32]) -> bool { + pub fn compare_hashes(&self, da_block_hash: &Da::SlotHash, post_state_root: &[u8; 32]) -> bool { self.da_block_hash == *da_block_hash && self.post_state_root == *post_state_root } @@ -59,34 +59,34 @@ impl StateTransitionId { } /// Returns the da block hash of a state transition - pub fn da_block_hash(&self) -> [u8; 32] { - self.da_block_hash + pub fn da_block_hash(&self) -> &Da::SlotHash { + &self.da_block_hash } /// Returns the validity condition associated with the transition - pub fn validity_condition(&self) -> &Cond { + pub fn validity_condition(&self) -> &Da::ValidityCondition { &self.validity_condition } /// Checks the validity condition of a state transition - pub fn validity_condition_check>( + pub fn validity_condition_check>( &self, checker: &mut Checker, - ) -> Result<(), >::Error> { + ) -> Result<(), >::Error> { checker.check(&self.validity_condition) } } -#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, PartialEq, Eq)] +#[derive(BorshDeserialize, BorshSerialize, Debug, PartialEq, Eq, Clone)] /// Represents a transition in progress for the rollup. -pub struct TransitionInProgress { - da_block_hash: [u8; 32], - validity_condition: Cond, +pub struct TransitionInProgress { + da_block_hash: Da::SlotHash, + validity_condition: Da::ValidityCondition, } -impl TransitionInProgress { +impl TransitionInProgress { /// Creates a new transition in progress - pub fn new(da_block_hash: [u8; 32], validity_condition: Cond) -> Self { + pub fn new(da_block_hash: Da::SlotHash, validity_condition: Da::ValidityCondition) -> Self { Self { da_block_hash, validity_condition, @@ -114,12 +114,11 @@ pub struct ChainState /// is stored during transition i+1. This is mainly due to the fact that this structure depends on the /// rollup's root hash which is only stored once the transition has completed. #[state] - historical_transitions: - sov_state::StateMap>, + historical_transitions: sov_state::StateMap>, /// The transition that is currently processed #[state] - in_progress_transition: sov_state::StateValue>, + in_progress_transition: sov_state::StateValue>, /// The genesis root hash. /// Set after the first transaction of the rollup is executed, using the `begin_slot` hook. @@ -137,7 +136,11 @@ pub struct ChainStateConfig { pub initial_slot_height: TransitionHeight, } -impl ChainState { +impl ChainState +where + Da::ValidityCondition: BorshSerialize + BorshDeserialize, + Da::SlotHash: BorshSerialize + BorshDeserialize, +{ /// Returns transition height in the current slot pub fn get_slot_height(&self, working_set: &mut WorkingSet) -> TransitionHeight { self.slot_height @@ -162,7 +165,7 @@ impl ChainState pub fn get_in_progress_transition( &self, working_set: &mut WorkingSet, - ) -> Option> { + ) -> Option> { self.in_progress_transition.get(working_set) } @@ -171,7 +174,7 @@ impl ChainState &self, transition_num: TransitionHeight, working_set: &mut WorkingSet, - ) -> Option> { + ) -> Option> { self.historical_transitions .get(&transition_num, working_set) } diff --git a/module-system/module-implementations/sov-chain-state/src/query.rs b/module-system/module-implementations/sov-chain-state/src/query.rs index f93536a04..81cf43413 100644 --- a/module-system/module-implementations/sov-chain-state/src/query.rs +++ b/module-system/module-implementations/sov-chain-state/src/query.rs @@ -1,3 +1,4 @@ +use borsh::{BorshDeserialize, BorshSerialize}; use jsonrpsee::core::RpcResult; use sov_modules_api::macros::rpc_gen; use sov_state::WorkingSet; @@ -5,7 +6,11 @@ use sov_state::WorkingSet; use crate::{ChainState, TransitionHeight}; #[rpc_gen(client, server, namespace = "chainState")] -impl ChainState { +impl ChainState +where + Da::SlotHash: BorshSerialize + BorshDeserialize, + Da::ValidityCondition: BorshSerialize + BorshDeserialize, +{ /// Get the height of the current slot. /// Panics if the slot height is not set #[rpc_method(name = "getSlotHeight")] diff --git a/module-system/module-implementations/sov-chain-state/tests/all_tests.rs b/module-system/module-implementations/sov-chain-state/tests/all_tests.rs index b8755d0bf..dc42644b9 100644 --- a/module-system/module-implementations/sov-chain-state/tests/all_tests.rs +++ b/module-system/module-implementations/sov-chain-state/tests/all_tests.rs @@ -53,7 +53,11 @@ fn test_simple_chain_state() { blobs: Default::default(), }; - chain_state.begin_slot_hook(&slot_data, &mut working_set); + chain_state.begin_slot_hook( + &slot_data.header, + &slot_data.validity_cond, + &mut working_set, + ); // Check that the root hash has been stored correctly let stored_root: [u8; 32] = chain_state.get_genesis_hash(&mut working_set).unwrap(); @@ -71,13 +75,16 @@ fn test_simple_chain_state() { ); // Check that the new state transition is being stored - let new_tx_in_progress: TransitionInProgress = chain_state + let new_tx_in_progress: TransitionInProgress = chain_state .get_in_progress_transition(&mut working_set) .unwrap(); assert_eq!( new_tx_in_progress, - TransitionInProgress::::new([1; 32], MockValidityCond { is_valid: true }), + TransitionInProgress::::new( + [1; 32].into(), + MockValidityCond { is_valid: true } + ), "The new transition has not been correctly stored" ); @@ -100,7 +107,11 @@ fn test_simple_chain_state() { blobs: Default::default(), }; - chain_state.begin_slot_hook(&new_slot_data, &mut working_set); + chain_state.begin_slot_hook( + &new_slot_data.header, + &new_slot_data.validity_cond, + &mut working_set, + ); // Check that the slot height has been updated correctly let new_height_storage = chain_state.get_slot_height(&mut working_set); @@ -111,28 +122,28 @@ fn test_simple_chain_state() { ); // Check the transition in progress - let new_tx_in_progress: TransitionInProgress = chain_state + let new_tx_in_progress: TransitionInProgress = chain_state .get_in_progress_transition(&mut working_set) .unwrap(); assert_eq!( new_tx_in_progress, - TransitionInProgress::::new( - [2; 32], + TransitionInProgress::::new( + [2; 32].into(), MockValidityCond { is_valid: false } ), "The new transition has not been correctly stored" ); // Check the transition stored - let last_tx_stored: StateTransitionId = chain_state + let last_tx_stored: StateTransitionId = chain_state .get_historical_transitions(INIT_HEIGHT + 1, &mut working_set) .unwrap(); assert_eq!( last_tx_stored, StateTransitionId::new( - [1; 32], + [1; 32].into(), new_root_hash.unwrap(), MockValidityCond { is_valid: true } ) diff --git a/module-system/sov-modules-api/src/hooks.rs b/module-system/sov-modules-api/src/hooks.rs index aedf68106..deb51ea3f 100644 --- a/module-system/sov-modules-api/src/hooks.rs +++ b/module-system/sov-modules-api/src/hooks.rs @@ -1,5 +1,4 @@ use sov_rollup_interface::da::{BlobReaderTrait, DaSpec}; -use sov_rollup_interface::services::da::SlotData; use sov_state::WorkingSet; use crate::transaction::Transaction; @@ -58,7 +57,8 @@ pub trait SlotHooks { fn begin_slot_hook( &self, - slot_data: &impl SlotData, + slot_header: &Da::BlockHeader, + validity_condition: &Da::ValidityCondition, working_set: &mut WorkingSet<::Storage>, ); diff --git a/module-system/sov-modules-stf-template/src/lib.rs b/module-system/sov-modules-stf-template/src/lib.rs index 4861084ea..bb347d08b 100644 --- a/module-system/sov-modules-stf-template/src/lib.rs +++ b/module-system/sov-modules-stf-template/src/lib.rs @@ -9,7 +9,7 @@ pub use batch::Batch; use sov_modules_api::capabilities::BlobSelector; use sov_modules_api::hooks::{ApplyBlobHooks, SlotHooks, TxHooks}; use sov_modules_api::{ - BasicAddress, BlobReaderTrait, Context, DaSpec, DispatchCall, Genesis, SlotData, Spec, Zkvm, + BasicAddress, BlobReaderTrait, Context, DaSpec, DispatchCall, Genesis, Spec, Zkvm, }; use sov_rollup_interface::stf::{SlotResult, StateTransitionFunction}; use sov_state::{StateCheckpoint, Storage}; @@ -81,13 +81,15 @@ where #[cfg_attr(all(target_os = "zkvm", feature = "bench"), cycle_tracker)] fn begin_slot( &mut self, - slot_data: &impl SlotData, - witness: >::Witness, + slot_header: &Da::BlockHeader, + validity_condition: &Da::ValidityCondition, + witness: >::Witness, ) { let state_checkpoint = StateCheckpoint::with_witness(self.current_storage.clone(), witness); let mut working_set = state_checkpoint.to_revertable(); - self.runtime.begin_slot_hook(slot_data, &mut working_set); + self.runtime + .begin_slot_hook(slot_header, validity_condition, &mut working_set); self.checkpoint = Some(working_set.checkpoint()); } @@ -115,7 +117,7 @@ where } } -impl StateTransitionFunction for AppTemplate +impl StateTransitionFunction for AppTemplate where C: Context, Da: DaSpec, @@ -154,10 +156,11 @@ where jmt::RootHash(genesis_hash) } - fn apply_slot<'a, I, Data>( + fn apply_slot<'a, I>( &mut self, witness: Self::Witness, - slot_data: &Data, + slot_header: &Da::BlockHeader, + validity_condition: &Da::ValidityCondition, blobs: I, ) -> SlotResult< Self::StateRoot, @@ -167,9 +170,8 @@ where > where I: IntoIterator, - Data: SlotData, { - self.begin_slot(slot_data, witness); + self.begin_slot(slot_header, validity_condition, witness); // Initialize batch workspace let mut batch_workspace = self diff --git a/rollup-interface/src/state_machine/da.rs b/rollup-interface/src/state_machine/da.rs index c3e8191c0..3fb823bd9 100644 --- a/rollup-interface/src/state_machine/da.rs +++ b/rollup-interface/src/state_machine/da.rs @@ -13,7 +13,7 @@ use crate::zk::ValidityCondition; use crate::BasicAddress; /// A specification for the types used by a DA layer. -pub trait DaSpec: 'static { +pub trait DaSpec: 'static + Debug + PartialEq + Eq { /// The hash of a DA layer block type SlotHash: BlockHashTrait; @@ -179,7 +179,10 @@ pub trait BlobReaderTrait: Serialize + DeserializeOwned + Send + Sync + 'static } /// Trait with collection of trait bounds for a block hash. -pub trait BlockHashTrait: Serialize + DeserializeOwned + PartialEq + Debug + Send + Sync {} +pub trait BlockHashTrait: + Serialize + DeserializeOwned + PartialEq + Debug + Send + Sync + Clone + Eq +{ +} /// A block header, typically used in the context of an underlying DA blockchain. pub trait BlockHeaderTrait: PartialEq + Debug + Clone { diff --git a/rollup-interface/src/state_machine/mocks/da.rs b/rollup-interface/src/state_machine/mocks/da.rs index 815a5f08d..d39a08216 100644 --- a/rollup-interface/src/state_machine/mocks/da.rs +++ b/rollup-interface/src/state_machine/mocks/da.rs @@ -2,6 +2,7 @@ use std::fmt::Display; use std::sync::Arc; use async_trait::async_trait; +use borsh::{BorshDeserialize, BorshSerialize}; use bytes::Bytes; use serde::{Deserialize, Serialize}; use sha2::Digest; @@ -134,7 +135,17 @@ impl MockBlob { } /// A mock hash digest. -#[derive(Clone, Copy, Debug, PartialEq, serde::Serialize, serde::Deserialize)] +#[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + serde::Serialize, + serde::Deserialize, + BorshDeserialize, + BorshSerialize, +)] pub struct MockHash(pub [u8; 32]); impl AsRef<[u8]> for MockHash { @@ -143,6 +154,12 @@ impl AsRef<[u8]> for MockHash { } } +impl From<[u8; 32]> for MockHash { + fn from(value: [u8; 32]) -> Self { + Self(value) + } +} + impl BlockHashTrait for MockHash {} /// A mock block header used for testing. @@ -152,6 +169,14 @@ pub struct MockBlockHeader { pub prev_hash: MockHash, } +impl Default for MockBlockHeader { + fn default() -> Self { + Self { + prev_hash: MockHash([0u8; 32]), + } + } +} + impl BlockHeaderTrait for MockBlockHeader { type Hash = MockHash; @@ -211,7 +236,7 @@ impl SlotData for MockBlock { } /// A [`DaSpec`] suitable for testing. -#[derive(serde::Serialize, serde::Deserialize)] +#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)] pub struct MockDaSpec; impl DaSpec for MockDaSpec { diff --git a/rollup-interface/src/state_machine/mocks/validity_condition.rs b/rollup-interface/src/state_machine/mocks/validity_condition.rs index 250afb532..e96b72df4 100644 --- a/rollup-interface/src/state_machine/mocks/validity_condition.rs +++ b/rollup-interface/src/state_machine/mocks/validity_condition.rs @@ -9,7 +9,16 @@ use crate::zk::{ValidityCondition, ValidityConditionChecker}; /// A trivial test validity condition structure that only contains a boolean #[derive( - Debug, BorshDeserialize, BorshSerialize, Serialize, Deserialize, PartialEq, Clone, Copy, Default, + Debug, + BorshDeserialize, + BorshSerialize, + Serialize, + Deserialize, + PartialEq, + Clone, + Copy, + Default, + Eq, )] pub struct MockValidityCond { /// The associated validity condition field. If it is true, the validity condition is verified diff --git a/rollup-interface/src/state_machine/optimistic.rs b/rollup-interface/src/state_machine/optimistic.rs index 84668f7df..2019a1b46 100644 --- a/rollup-interface/src/state_machine/optimistic.rs +++ b/rollup-interface/src/state_machine/optimistic.rs @@ -2,6 +2,7 @@ use borsh::{BorshDeserialize, BorshSerialize}; use serde::{Deserialize, Serialize}; +use crate::da::DaSpec; use crate::zk::StateTransition; /// A proof that the attester was bonded at the transition num `transition_num`. @@ -20,11 +21,11 @@ pub struct ProofOfBond { #[derive( Debug, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize, Serialize, Deserialize, Default, )] -pub struct Attestation { +pub struct Attestation { /// The alleged state root before applying the contents of the da block pub initial_state_root: [u8; 32], /// The hash of the block in which the transition occurred - pub da_block_hash: [u8; 32], + pub da_block_hash: Da::SlotHash, /// The alleged post-state root pub post_state_root: [u8; 32], /// A proof that the attester was bonded at some point in time before the attestation is generated @@ -34,11 +35,11 @@ pub struct Attestation { /// The contents of a challenge to an attestation, which are contained as a public output of the proof /// Generic over an address type and a validity condition #[derive(Debug, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize, Serialize, Deserialize)] -pub struct ChallengeContents { +pub struct ChallengeContents { /// The rollup address of the originator of this challenge pub challenger_address: Address, /// The state transition that was proven - pub state_transition: StateTransition, + pub state_transition: StateTransition, } #[derive(Debug, Clone, PartialEq, Eq, BorshSerialize, Serialize, Deserialize)] diff --git a/rollup-interface/src/state_machine/stf.rs b/rollup-interface/src/state_machine/stf.rs index 06fcc747b..57855467a 100644 --- a/rollup-interface/src/state_machine/stf.rs +++ b/rollup-interface/src/state_machine/stf.rs @@ -7,8 +7,7 @@ use borsh::{BorshDeserialize, BorshSerialize}; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; -use crate::da::BlobReaderTrait; -use crate::services::da::SlotData; +use crate::da::DaSpec; use crate::zk::{ValidityCondition, Zkvm}; #[cfg(any(test, feature = "fuzzing"))] @@ -94,7 +93,7 @@ pub struct SlotResult { /// - block: DA layer block /// - batch: Set of transactions grouped together, or block on L2 /// - blob: Non serialised batch or anything else that can be posted on DA layer, like attestation or proof. -pub trait StateTransitionFunction { +pub trait StateTransitionFunction { /// Root hash of state merkle tree type StateRoot; /// The initial state of the rollup. @@ -130,10 +129,11 @@ pub trait StateTransitionFunction { /// which is why we use a generic here instead of an associated type. /// /// Commits state changes to the database - fn apply_slot<'a, I, Data>( + fn apply_slot<'a, I>( &mut self, witness: Self::Witness, - slot_data: &Data, + slot_header: &Da::BlockHeader, + validity_condition: &Da::ValidityCondition, blobs: I, ) -> SlotResult< Self::StateRoot, @@ -142,8 +142,7 @@ pub trait StateTransitionFunction { Self::Witness, > where - I: IntoIterator, - Data: SlotData; + I: IntoIterator; /// Gets the state root from the associated state. If not available (because the chain has not been initialized yet), /// return None. diff --git a/rollup-interface/src/state_machine/zk/mod.rs b/rollup-interface/src/state_machine/zk/mod.rs index e2644b5df..0d2cb6b21 100644 --- a/rollup-interface/src/state_machine/zk/mod.rs +++ b/rollup-interface/src/state_machine/zk/mod.rs @@ -13,6 +13,7 @@ use digest::Digest; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; +use crate::da::DaSpec; use crate::RollupAddress; /// A trait implemented by the prover ("host") of a zkVM program. @@ -45,12 +46,16 @@ pub trait Zkvm { /// as a serialized array, it returns a state transition structure. /// TODO: specify a deserializer for the output fn verify_and_extract_output< - C: ValidityCondition, Add: RollupAddress + BorshDeserialize + BorshSerialize, + Da: DaSpec, >( serialized_proof: &[u8], code_commitment: &Self::CodeCommitment, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> + where + Da::SlotHash: BorshDeserialize + BorshSerialize, + Da::ValidityCondition: BorshDeserialize + BorshSerialize, + { let mut output = Self::verify(serialized_proof, code_commitment)?; Ok(BorshDeserialize::deserialize_reader(&mut output)?) } @@ -99,6 +104,7 @@ pub trait ValidityCondition: + PartialEq + Send + Sync + + Eq { /// The error type returned when two [`ValidityCondition`]s cannot be combined. type Error: Into; @@ -113,13 +119,13 @@ pub trait ValidityCondition: /// /// The period of time covered by a state transition proof may be a single slot, or a range of slots on the DA layer. #[derive(Clone, Debug, Serialize, Deserialize, BorshSerialize, BorshDeserialize, PartialEq, Eq)] -pub struct StateTransition { +pub struct StateTransition { /// The state of the rollup before the transition pub initial_state_root: [u8; 32], /// The state of the rollup after the transition pub final_state_root: [u8; 32], /// The slot hash of the state transition - pub slot_hash: [u8; 32], + pub slot_hash: Da::SlotHash, /// Rewarded address: the account that has produced the transition proof. pub rewarded_address: Address, @@ -127,7 +133,7 @@ pub struct StateTransition { /// An additional validity condition for the state transition which needs /// to be checked outside of the zkVM circuit. This typically corresponds to /// some claim about the DA layer history, such as (X) is a valid block on the DA layer - pub validity_condition: C, + pub validity_condition: Da::ValidityCondition, } /// This trait expresses that a type can check a validity condition. From 6f35fe979f51f37aa46fd155797158042ebbddac Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Mon, 11 Sep 2023 12:54:42 -0500 Subject: [PATCH 04/21] Fix all interfaces --- Cargo.lock | 6 +- Cargo.toml | 2 +- adapters/celestia/src/verifier/mod.rs | 6 ++ adapters/risc0/src/guest.rs | 10 ++++ adapters/risc0/src/host.rs | 22 +++++++ examples/demo-rollup/benches/rng_xfers.rs | 2 +- examples/demo-stf/src/hooks_impl.rs | 8 ++- examples/demo-stf/src/tests/stf_tests.rs | 28 +++++++-- .../demo-stf/src/tests/tx_revert_tests.rs | 35 +++++++++-- .../src/chain_state/helpers.rs | 16 +---- .../sov-attester-incentives/Cargo.toml | 1 + .../sov-attester-incentives/src/call.rs | 58 +++++++++++++++++-- .../sov-attester-incentives/src/genesis.rs | 10 +--- .../sov-attester-incentives/src/lib.rs | 17 ++---- .../src/tests/attestation_proccessing.rs | 13 +++-- .../src/tests/challenger.rs | 6 +- .../src/tests/invariant.rs | 10 ++-- .../src/tests/unbonding.rs | 2 +- .../sov-blob-storage/src/capabilities.rs | 6 +- .../sov-blob-storage/src/lib.rs | 6 +- .../sov-chain-state/src/call.rs | 3 - .../sov-chain-state/src/hooks.rs | 6 +- .../sov-chain-state/src/lib.rs | 16 +++-- .../sov-chain-state/src/query.rs | 7 +-- .../sov-prover-incentives/src/call.rs | 3 +- .../sov-prover-incentives/src/genesis.rs | 8 +-- .../sov-prover-incentives/src/lib.rs | 5 +- module-system/sov-modules-api/src/lib.rs | 2 +- rollup-interface/src/state_machine/da.rs | 2 +- .../src/state_machine/mocks/da.rs | 6 ++ .../src/state_machine/mocks/zk_vm.rs | 8 +++ .../src/state_machine/optimistic.rs | 4 +- rollup-interface/src/state_machine/zk/mod.rs | 41 ++----------- 33 files changed, 221 insertions(+), 154 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 460e9bb4a..b36dbbe31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -474,9 +474,8 @@ dependencies = [ [[package]] name = "bcs" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd3ffe8b19a604421a5d461d4a70346223e535903fbc3067138bddbebddcf77" +version = "0.1.4" +source = "git+https://github.com/preston-evans98/bcs.git?rev=e4f1861#e4f1861509a996408baa540cda1f88c290214ce1" dependencies = [ "serde", "thiserror", @@ -6550,6 +6549,7 @@ name = "sov-attester-incentives" version = "0.1.0" dependencies = [ "anyhow", + "bcs", "borsh", "jmt", "serde", diff --git a/Cargo.toml b/Cargo.toml index 461b524d9..f9b19288d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -66,7 +66,7 @@ borsh = { version = "0.10.3", features = ["rc", "bytes"] } # TODO: Consider replacing this serialization format # https://github.com/Sovereign-Labs/sovereign-sdk/issues/283 bincode = "1.3.3" -bcs = "0.1.5" +bcs = { git = "https://github.com/preston-evans98/bcs.git", rev = "e4f1861" } byteorder = "1.4.3" bytes = "1.2.1" hex = "0.4.3" diff --git a/adapters/celestia/src/verifier/mod.rs b/adapters/celestia/src/verifier/mod.rs index 0f447fb95..8a36e8ba0 100644 --- a/adapters/celestia/src/verifier/mod.rs +++ b/adapters/celestia/src/verifier/mod.rs @@ -89,6 +89,12 @@ impl AsRef for tendermint::Hash { impl BlockHash for TmHash {} +impl Into<[u8; 32]> for TmHash { + fn into(self) -> [u8; 32] { + *self.inner() + } +} + #[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)] pub struct CelestiaSpec; diff --git a/adapters/risc0/src/guest.rs b/adapters/risc0/src/guest.rs index acc7e3d8f..a68cf1714 100644 --- a/adapters/risc0/src/guest.rs +++ b/adapters/risc0/src/guest.rs @@ -40,4 +40,14 @@ impl Zkvm for Risc0Guest { // Implement this method once risc0 supports recursion: issue #633 todo!("Implement once risc0 supports recursion: https://github.com/Sovereign-Labs/sovereign-sdk/issues/633") } + + fn verify_and_extract_output< + Add: sov_rollup_interface::RollupAddress, + Da: sov_rollup_interface::da::DaSpec, + >( + _serialized_proof: &[u8], + _code_commitment: &Self::CodeCommitment, + ) -> Result, Self::Error> { + todo!() + } } diff --git a/adapters/risc0/src/host.rs b/adapters/risc0/src/host.rs index 0829435bc..491c53932 100644 --- a/adapters/risc0/src/host.rs +++ b/adapters/risc0/src/host.rs @@ -78,6 +78,17 @@ impl<'prover> Zkvm for Risc0Host<'prover> { ) -> Result<&'a [u8], Self::Error> { verify_from_slice(serialized_proof, code_commitment) } + + fn verify_and_extract_output< + Add: sov_rollup_interface::RollupAddress, + Da: sov_rollup_interface::da::DaSpec, + >( + serialized_proof: &[u8], + code_commitment: &Self::CodeCommitment, + ) -> Result, Self::Error> { + let output = Self::verify(serialized_proof, code_commitment)?; + Ok(risc0_zkvm::serde::from_slice(output)?) + } } pub struct Risc0Verifier; @@ -93,6 +104,17 @@ impl Zkvm for Risc0Verifier { ) -> Result<&'a [u8], Self::Error> { verify_from_slice(serialized_proof, code_commitment) } + + fn verify_and_extract_output< + Add: sov_rollup_interface::RollupAddress, + Da: sov_rollup_interface::da::DaSpec, + >( + serialized_proof: &[u8], + code_commitment: &Self::CodeCommitment, + ) -> Result, Self::Error> { + let output = Self::verify(serialized_proof, code_commitment)?; + Ok(risc0_zkvm::serde::from_slice(output)?) + } } fn verify_from_slice<'a>( diff --git a/examples/demo-rollup/benches/rng_xfers.rs b/examples/demo-rollup/benches/rng_xfers.rs index 23e5251a2..2cd6fc0a9 100644 --- a/examples/demo-rollup/benches/rng_xfers.rs +++ b/examples/demo-rollup/benches/rng_xfers.rs @@ -92,7 +92,7 @@ impl Default for RngDaService { } /// A simple DaSpec for a random number generator. -#[derive(serde::Serialize, serde::Deserialize)] +#[derive(serde::Serialize, serde::Deserialize, PartialEq, Eq, Debug, Clone, Default)] pub struct RngDaSpec; impl DaSpec for RngDaSpec { diff --git a/examples/demo-stf/src/hooks_impl.rs b/examples/demo-stf/src/hooks_impl.rs index a21118f64..b6f1641d3 100644 --- a/examples/demo-stf/src/hooks_impl.rs +++ b/examples/demo-stf/src/hooks_impl.rs @@ -2,7 +2,7 @@ use sov_modules_api::hooks::{ApplyBlobHooks, SlotHooks, TxHooks}; use sov_modules_api::transaction::Transaction; use sov_modules_api::{Context, Spec}; use sov_modules_stf_template::SequencerOutcome; -use sov_rollup_interface::da::{BlobReaderTrait, DaSpec}; +use sov_rollup_interface::da::{BlobReaderTrait, BlockHeaderTrait, DaSpec}; use sov_sequencer_registry::SequencerRegistry; use sov_state::WorkingSet; use tracing::info; @@ -79,13 +79,15 @@ impl SlotHooks for Runtime { fn begin_slot_hook( &self, - #[allow(unused_variables)] slot_data: &impl sov_rollup_interface::services::da::SlotData, + #[allow(unused_variables)] slot_header: &Da::BlockHeader, + #[allow(unused_variables)] validity_condition: &Da::ValidityCondition, #[allow(unused_variables)] working_set: &mut sov_state::WorkingSet< ::Storage, >, ) { #[cfg(feature = "experimental")] - self.evm.begin_slot_hook(slot_data.hash(), working_set); + self.evm + .begin_slot_hook(slot_header.hash().into(), working_set); } fn end_slot_hook( diff --git a/examples/demo-stf/src/tests/stf_tests.rs b/examples/demo-stf/src/tests/stf_tests.rs index 3e9f310ff..29a358a14 100644 --- a/examples/demo-stf/src/tests/stf_tests.rs +++ b/examples/demo-stf/src/tests/stf_tests.rs @@ -35,7 +35,12 @@ pub mod test { let data = MockBlock::default(); - let result = demo.apply_slot(Default::default(), &data, &mut blobs); + let result = demo.apply_slot( + Default::default(), + &data.header, + &data.validity_cond, + &mut blobs, + ); assert_eq!(1, result.batch_receipts.len()); // 2 transactions from value setter // 2 transactions from bank @@ -89,7 +94,12 @@ pub mod test { let mut blobs = [blob]; let data = MockBlock::default(); - let apply_block_result = demo.apply_slot(Default::default(), &data, &mut blobs); + let apply_block_result = demo.apply_slot( + Default::default(), + &data.header, + &data.validity_cond, + &mut blobs, + ); assert_eq!(1, apply_block_result.batch_receipts.len()); let apply_blob_outcome = apply_block_result.batch_receipts[0].clone(); @@ -137,7 +147,12 @@ pub mod test { let mut blobs = [blob]; let data = MockBlock::default(); - let apply_block_result = demo.apply_slot(Default::default(), &data, &mut blobs); + let apply_block_result = demo.apply_slot( + Default::default(), + &data.header, + &data.validity_cond, + &mut blobs, + ); assert_eq!(1, apply_block_result.batch_receipts.len()); let apply_blob_outcome = apply_block_result.batch_receipts[0].clone(); @@ -189,7 +204,12 @@ pub mod test { let mut blobs = [blob]; let data = MockBlock::default(); - let apply_block_result = demo.apply_slot(Default::default(), &data, &mut blobs); + let apply_block_result = demo.apply_slot( + Default::default(), + &data.header, + &data.validity_cond, + &mut blobs, + ); assert_eq!(1, apply_block_result.batch_receipts.len()); let apply_blob_outcome = apply_block_result.batch_receipts[0].clone(); diff --git a/examples/demo-stf/src/tests/tx_revert_tests.rs b/examples/demo-stf/src/tests/tx_revert_tests.rs index ba2f4d0cd..57aaa8b7d 100644 --- a/examples/demo-stf/src/tests/tx_revert_tests.rs +++ b/examples/demo-stf/src/tests/tx_revert_tests.rs @@ -43,7 +43,12 @@ fn test_tx_revert() { let mut blobs = [blob]; let data = MockBlock::default(); - let apply_block_result = demo.apply_slot(Default::default(), &data, &mut blobs); + let apply_block_result = demo.apply_slot( + Default::default(), + &data.header, + &data.validity_cond, + &mut blobs, + ); assert_eq!(1, apply_block_result.batch_receipts.len()); let apply_blob_outcome = apply_block_result.batch_receipts[0].clone(); @@ -108,7 +113,12 @@ fn test_nonce_incremented_on_revert() { let mut blobs = [blob]; let data = MockBlock::default(); - let apply_block_result = demo.apply_slot(Default::default(), &data, &mut blobs); + let apply_block_result = demo.apply_slot( + Default::default(), + &data.header, + &data.validity_cond, + &mut blobs, + ); assert_eq!(1, apply_block_result.batch_receipts.len()); let apply_blob_outcome = apply_block_result.batch_receipts[0].clone(); @@ -172,7 +182,12 @@ fn test_tx_bad_sig() { let mut blobs = [blob]; let data = MockBlock::default(); - let apply_block_result = demo.apply_slot(Default::default(), &data, &mut blobs); + let apply_block_result = demo.apply_slot( + Default::default(), + &data.header, + &data.validity_cond, + &mut blobs, + ); assert_eq!(1, apply_block_result.batch_receipts.len()); let apply_blob_outcome = apply_block_result.batch_receipts[0].clone(); @@ -211,7 +226,12 @@ fn test_tx_bad_nonce() { let mut blobs = [blob]; let data = MockBlock::default(); - let apply_block_result = demo.apply_slot(Default::default(), &data, &mut blobs); + let apply_block_result = demo.apply_slot( + Default::default(), + &data.header, + &data.validity_cond, + &mut blobs, + ); assert_eq!(1, apply_block_result.batch_receipts.len()); let tx_receipts = apply_block_result.batch_receipts[0].tx_receipts.clone(); @@ -272,7 +292,12 @@ fn test_tx_bad_serialization() { let mut blobs = [blob]; let data = MockBlock::default(); - let apply_block_result = demo.apply_slot(Default::default(), &data, &mut blobs); + let apply_block_result = demo.apply_slot( + Default::default(), + &data.header, + &data.validity_cond, + &mut blobs, + ); assert_eq!(1, apply_block_result.batch_receipts.len()); let apply_blob_outcome = apply_block_result.batch_receipts[0].clone(); diff --git a/module-system/module-implementations/integration-tests/src/chain_state/helpers.rs b/module-system/module-implementations/integration-tests/src/chain_state/helpers.rs index 8aa0bddd1..5ba90787b 100644 --- a/module-system/module-implementations/integration-tests/src/chain_state/helpers.rs +++ b/module-system/module-implementations/integration-tests/src/chain_state/helpers.rs @@ -1,4 +1,3 @@ -use borsh::{BorshDeserialize, BorshSerialize}; use sov_chain_state::{ChainState, ChainStateConfig}; use sov_modules_api::capabilities::{BlobRefOrOwned, BlobSelector}; use sov_modules_api::hooks::{ApplyBlobHooks, SlotHooks, TxHooks}; @@ -60,11 +59,7 @@ impl ApplyBlobHooks for TestRuntime } } -impl SlotHooks for TestRuntime -where - Da::SlotHash: BorshDeserialize + BorshSerialize, - Da::ValidityCondition: BorshDeserialize + BorshSerialize, -{ +impl SlotHooks for TestRuntime { type Context = C; fn begin_slot_hook( @@ -104,12 +99,7 @@ where } } -impl Runtime for TestRuntime -where - Da::SlotHash: BorshDeserialize + BorshSerialize, - Da::ValidityCondition: BorshDeserialize + BorshSerialize, -{ -} +impl Runtime for TestRuntime {} pub(crate) fn create_demo_genesis_config( admin: ::Address, @@ -126,8 +116,6 @@ pub(crate) fn get_working_set( app_template: &AppTemplate>, ) -> sov_state::WorkingSet<::Storage> where - Da::SlotHash: BorshDeserialize + BorshSerialize, - Da::ValidityCondition: BorshDeserialize + BorshSerialize, { sov_state::WorkingSet::new(app_template.current_storage.clone()) } diff --git a/module-system/module-implementations/sov-attester-incentives/Cargo.toml b/module-system/module-implementations/sov-attester-incentives/Cargo.toml index 98c2ebf0f..05883e4f3 100644 --- a/module-system/module-implementations/sov-attester-incentives/Cargo.toml +++ b/module-system/module-implementations/sov-attester-incentives/Cargo.toml @@ -20,6 +20,7 @@ tempfile = { workspace = true } [dependencies] anyhow = { workspace = true } borsh = { workspace = true, features = ["rc"] } +bcs = { workspace = true } jmt = { workspace = true } thiserror = { workspace = true } serde = { workspace = true, optional = true } diff --git a/module-system/module-implementations/sov-attester-incentives/src/call.rs b/module-system/module-implementations/sov-attester-incentives/src/call.rs index 468732806..fdb98c29f 100644 --- a/module-system/module-implementations/sov-attester-incentives/src/call.rs +++ b/module-system/module-implementations/sov-attester-incentives/src/call.rs @@ -2,6 +2,8 @@ use core::result::Result::Ok; use std::fmt::Debug; use borsh::{BorshDeserialize, BorshSerialize}; +use serde::de::DeserializeOwned; +use serde::{Deserialize, Serialize}; use sov_bank::{Amount, Coins}; use sov_chain_state::TransitionHeight; use sov_modules_api::optimistic::Attestation; @@ -12,6 +14,50 @@ use thiserror::Error; use crate::{AttesterIncentives, UnbondingInfo}; +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +/// A wrapper for attestations which implements `borsh` serialization. This is necessary since +/// Attestations are treated as `CallMessage`s, and we only support borsh encoding for transactions. +pub struct WrappedAttestation { + #[serde( + bound = "Da::SlotHash: Serialize + DeserializeOwned, StorageProof: Serialize + DeserializeOwned" + )] + /// The inner attestation + pub inner: Attestation, +} + +impl From> + for WrappedAttestation +{ + fn from(value: Attestation) -> Self { + Self { inner: value } + } +} + +impl BorshSerialize for WrappedAttestation { + fn serialize(&self, writer: &mut W) -> std::io::Result<()> { + // TODO: Implement bcs `to_writer` + let value = bcs::to_bytes(&self.inner).map_err(|_| { + std::io::Error::new(std::io::ErrorKind::Other, "Failed to serialize attestation") + })?; + writer.write_all(&value)?; + Ok(()) + } +} + +impl BorshDeserialize + for WrappedAttestation +{ + fn deserialize_reader(reader: &mut R) -> std::io::Result { + bcs::from_reader(reader) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string())) + } + + fn deserialize(buf: &mut &[u8]) -> std::io::Result { + bcs::from_bytes(*buf) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string())) + } +} + /// This enumeration represents the available call messages for interacting with the `AttesterIncentives` module. #[derive(BorshDeserialize, BorshSerialize, Debug)] pub enum CallMessage { @@ -26,7 +72,9 @@ pub enum CallMessage { /// Unbonds a challenger UnbondChallenger, /// Processes an attestation. - ProcessAttestation(Attestation::Storage as Storage>::Proof>>), + ProcessAttestation( + WrappedAttestation::Storage as Storage>::Proof>>, + ), /// Processes a challenge. The challenge is encoded as a [`Vec`]. The second parameter is the transition number ProcessChallenge(Vec, TransitionHeight), } @@ -118,8 +166,6 @@ where Vm: sov_modules_api::Zkvm, Da: sov_modules_api::DaSpec, Checker: ValidityConditionChecker, - Da::SlotHash: BorshDeserialize + BorshSerialize, - Da::ValidityCondition: BorshDeserialize + BorshSerialize, { /// This returns the address of the reward token supply pub fn get_reward_token_supply_address( @@ -542,9 +588,10 @@ where pub(crate) fn process_attestation( &self, context: &C, - attestation: Attestation::Proof>>, + attestation: WrappedAttestation::Proof>>, working_set: &mut WorkingSet, ) -> anyhow::Result { + let attestation = attestation.inner; // We first need to check that the attester is still in the bonding set if self .bonded_attesters @@ -709,8 +756,7 @@ where let code_commitment = self .commitment_to_allowed_challenge_method .get(working_set) - .expect("Should be set at genesis") - .commitment; + .expect("Should be set at genesis"); // Find the faulty attestation pool and get the associated reward let attestation_reward: u64 = self diff --git a/module-system/module-implementations/sov-attester-incentives/src/genesis.rs b/module-system/module-implementations/sov-attester-incentives/src/genesis.rs index c3e084333..6730764c7 100644 --- a/module-system/module-implementations/sov-attester-incentives/src/genesis.rs +++ b/module-system/module-implementations/sov-attester-incentives/src/genesis.rs @@ -14,8 +14,6 @@ where P: BorshDeserialize + BorshSerialize, Da: sov_modules_api::DaSpec, Checker: ValidityConditionChecker, - Da::ValidityCondition: BorshSerialize + BorshDeserialize, - Da::SlotHash: BorshSerialize + BorshDeserialize, { pub(crate) fn init_module( &self, @@ -32,12 +30,8 @@ where self.minimum_challenger_bond .set(&config.minimum_challenger_bond, working_set); - self.commitment_to_allowed_challenge_method.set( - &crate::StoredCodeCommitment { - commitment: config.commitment_to_allowed_challenge_method.clone(), - }, - working_set, - ); + self.commitment_to_allowed_challenge_method + .set(&config.commitment_to_allowed_challenge_method, working_set); self.rollup_finality_period .set(&config.rollup_finality_period, working_set); diff --git a/module-system/module-implementations/sov-attester-incentives/src/lib.rs b/module-system/module-implementations/sov-attester-incentives/src/lib.rs index b216729e5..f6048e915 100644 --- a/module-system/module-implementations/sov-attester-incentives/src/lib.rs +++ b/module-system/module-implementations/sov-attester-incentives/src/lib.rs @@ -19,10 +19,9 @@ use borsh::{BorshDeserialize, BorshSerialize}; use call::Role; use sov_bank::Amount; use sov_chain_state::TransitionHeight; -use sov_modules_api::{ - Context, DaSpec, Error, ModuleInfo, StoredCodeCommitment, ValidityConditionChecker, Zkvm, -}; -use sov_state::{Storage, WorkingSet}; +use sov_modules_api::{Context, DaSpec, Error, ModuleInfo, ValidityConditionChecker, Zkvm}; +use sov_state::codec::BcsCodec; +use sov_state::WorkingSet; /// Configuration of the attester incentives module pub struct AttesterIncentivesConfig @@ -99,7 +98,7 @@ where /// The code commitment to be used for verifying proofs #[state] - pub commitment_to_allowed_challenge_method: sov_state::StateValue>, + pub commitment_to_allowed_challenge_method: sov_state::StateValue, /// Constant validity condition checker for the module. #[state] @@ -149,16 +148,12 @@ where pub(crate) chain_state: sov_chain_state::ChainState, } -impl sov_modules_api::Module for AttesterIncentives +impl sov_modules_api::Module for AttesterIncentives where - C: sov_modules_api::Context, + C: sov_modules_api::Context, Vm: Zkvm, - S: Storage, - P: BorshDeserialize + BorshSerialize, Da: DaSpec, Checker: ValidityConditionChecker, - Da::ValidityCondition: BorshSerialize + BorshDeserialize, - Da::SlotHash: BorshSerialize + BorshDeserialize, { type Context = C; diff --git a/module-system/module-implementations/sov-attester-incentives/src/tests/attestation_proccessing.rs b/module-system/module-implementations/sov-attester-incentives/src/tests/attestation_proccessing.rs index ebb092bac..31eb8dd31 100644 --- a/module-system/module-implementations/sov-attester-incentives/src/tests/attestation_proccessing.rs +++ b/module-system/module-implementations/sov-attester-incentives/src/tests/attestation_proccessing.rs @@ -50,7 +50,8 @@ fn test_process_valid_attestation() { claimed_transition_num: INIT_HEIGHT + 1, proof: initial_transition.state_proof, }, - }; + } + .into(); module .process_attestation(&context, attestation, &mut working_set) @@ -70,7 +71,7 @@ fn test_process_valid_attestation() { }; module - .process_attestation(&context, attestation, &mut working_set) + .process_attestation(&context, attestation.into(), &mut working_set) .expect("An invalid proof is an error"); } @@ -144,7 +145,7 @@ fn test_burn_on_invalid_attestation() { }; let attestation_error = module - .process_attestation(&context, attestation, &mut working_set) + .process_attestation(&context, attestation.into(), &mut working_set) .unwrap_err(); assert_eq!( @@ -179,7 +180,7 @@ fn test_burn_on_invalid_attestation() { }; module - .process_attestation(&context, attestation, &mut working_set) + .process_attestation(&context, attestation.into(), &mut working_set) .expect("An invalid proof is an error"); } @@ -196,7 +197,7 @@ fn test_burn_on_invalid_attestation() { }; let attestation_error = module - .process_attestation(&context, attestation, &mut working_set) + .process_attestation(&context, attestation.into(), &mut working_set) .unwrap_err(); assert_eq!( @@ -249,7 +250,7 @@ fn test_burn_on_invalid_attestation() { }; let attestation_error = module - .process_attestation(&context, attestation, &mut working_set) + .process_attestation(&context, attestation.into(), &mut working_set) .unwrap_err(); assert_eq!( diff --git a/module-system/module-implementations/sov-attester-incentives/src/tests/challenger.rs b/module-system/module-implementations/sov-attester-incentives/src/tests/challenger.rs index 942255d00..5017593a8 100644 --- a/module-system/module-implementations/sov-attester-incentives/src/tests/challenger.rs +++ b/module-system/module-implementations/sov-attester-incentives/src/tests/challenger.rs @@ -76,8 +76,7 @@ fn test_valid_challenge() { let commitment = module .commitment_to_allowed_challenge_method .get(&mut working_set) - .expect("Should be set at genesis") - .commitment; + .expect("Should be set at genesis"); let proof = &MockProof { program_id: commitment, @@ -209,8 +208,7 @@ fn test_invalid_challenge() { let commitment = module .commitment_to_allowed_challenge_method .get(&mut working_set) - .expect("Should be set at genesis") - .commitment; + .expect("Should be set at genesis"); { // A valid proof diff --git a/module-system/module-implementations/sov-attester-incentives/src/tests/invariant.rs b/module-system/module-implementations/sov-attester-incentives/src/tests/invariant.rs index 96e244934..e278e92c1 100644 --- a/module-system/module-implementations/sov-attester-incentives/src/tests/invariant.rs +++ b/module-system/module-implementations/sov-attester-incentives/src/tests/invariant.rs @@ -62,7 +62,7 @@ fn test_transition_invariant() { }; let err = module - .process_attestation(&context, attestation, &mut working_set) + .process_attestation(&context, attestation.into(), &mut working_set) .unwrap_err(); assert_eq!( @@ -136,11 +136,11 @@ fn test_transition_invariant() { ); module - .process_attestation(&context, old_attestation, &mut working_set) + .process_attestation(&context, old_attestation.into(), &mut working_set) .expect("Should succeed"); module - .process_attestation(&context, new_attestation, &mut working_set) + .process_attestation(&context, new_attestation.into(), &mut working_set) .expect("Should succeed"); } @@ -177,7 +177,7 @@ fn test_transition_invariant() { ); let err = module - .process_attestation(&context, old_attestation, &mut working_set) + .process_attestation(&context, old_attestation.into(), &mut working_set) .unwrap_err(); assert_eq!( @@ -207,7 +207,7 @@ fn test_transition_invariant() { ); let err = module - .process_attestation(&context, attestation, &mut working_set) + .process_attestation(&context, attestation.into(), &mut working_set) .unwrap_err(); assert_eq!( diff --git a/module-system/module-implementations/sov-attester-incentives/src/tests/unbonding.rs b/module-system/module-implementations/sov-attester-incentives/src/tests/unbonding.rs index 7f0a66350..b831b51c4 100644 --- a/module-system/module-implementations/sov-attester-incentives/src/tests/unbonding.rs +++ b/module-system/module-implementations/sov-attester-incentives/src/tests/unbonding.rs @@ -66,7 +66,7 @@ fn test_two_phase_unbonding() { }; let err = module - .process_attestation(&context, attestation, &mut working_set) + .process_attestation(&context, attestation.into(), &mut working_set) .unwrap_err(); assert_eq!( diff --git a/module-system/module-implementations/sov-blob-storage/src/capabilities.rs b/module-system/module-implementations/sov-blob-storage/src/capabilities.rs index b7a7f3938..08497e856 100644 --- a/module-system/module-implementations/sov-blob-storage/src/capabilities.rs +++ b/module-system/module-implementations/sov-blob-storage/src/capabilities.rs @@ -7,11 +7,7 @@ use tracing::info; use crate::BlobStorage; -impl BlobSelector for BlobStorage -where - Da::ValidityCondition: BorshDeserialize + BorshSerialize, - Da::SlotHash: BorshDeserialize + BorshSerialize, -{ +impl BlobSelector for BlobStorage { type Context = C; fn get_blobs_for_this_slot<'a, I>( diff --git a/module-system/module-implementations/sov-blob-storage/src/lib.rs b/module-system/module-implementations/sov-blob-storage/src/lib.rs index a799a4a3b..9e8c45119 100644 --- a/module-system/module-implementations/sov-blob-storage/src/lib.rs +++ b/module-system/module-implementations/sov-blob-storage/src/lib.rs @@ -37,11 +37,7 @@ pub struct BlobStorage } /// Non standard methods for blob storage -impl BlobStorage -where - Da::ValidityCondition: BorshDeserialize + BorshSerialize, - Da::SlotHash: BorshDeserialize + BorshSerialize, -{ +impl BlobStorage { /// Store blobs for given block number, overwrite if already exists pub fn store_blobs( &self, diff --git a/module-system/module-implementations/sov-chain-state/src/call.rs b/module-system/module-implementations/sov-chain-state/src/call.rs index d50f7dba6..9abb08c78 100644 --- a/module-system/module-implementations/sov-chain-state/src/call.rs +++ b/module-system/module-implementations/sov-chain-state/src/call.rs @@ -1,4 +1,3 @@ -use borsh::{BorshDeserialize, BorshSerialize}; use sov_state::WorkingSet; use crate::{ChainState, StateTransitionId, TransitionHeight}; @@ -7,8 +6,6 @@ impl ChainState where C: sov_modules_api::Context, Da: sov_modules_api::DaSpec, - Da::ValidityCondition: BorshSerialize + BorshDeserialize, - Da::SlotHash: BorshSerialize + BorshDeserialize, { /// Increment the current slot height pub(crate) fn increment_slot_height(&self, working_set: &mut WorkingSet) { diff --git a/module-system/module-implementations/sov-chain-state/src/hooks.rs b/module-system/module-implementations/sov-chain-state/src/hooks.rs index fa7f4d1ba..5ca03de9f 100644 --- a/module-system/module-implementations/sov-chain-state/src/hooks.rs +++ b/module-system/module-implementations/sov-chain-state/src/hooks.rs @@ -7,11 +7,7 @@ use sov_state::{Storage, WorkingSet}; use super::ChainState; use crate::{StateTransitionId, TransitionInProgress}; -impl SlotHooks for ChainState -where - Da::ValidityCondition: BorshSerialize + BorshDeserialize, - Da::SlotHash: BorshSerialize + BorshDeserialize, -{ +impl SlotHooks for ChainState { type Context = C; fn begin_slot_hook( diff --git a/module-system/module-implementations/sov-chain-state/src/lib.rs b/module-system/module-implementations/sov-chain-state/src/lib.rs index 6d6dfbff7..23c0d7a51 100644 --- a/module-system/module-implementations/sov-chain-state/src/lib.rs +++ b/module-system/module-implementations/sov-chain-state/src/lib.rs @@ -16,13 +16,15 @@ pub mod query; use borsh::{BorshDeserialize, BorshSerialize}; #[cfg(feature = "native")] pub use query::{ChainStateRpcImpl, ChainStateRpcServer}; +use serde::{Deserialize, Serialize}; use sov_modules_api::{DaSpec, Error, ModuleInfo, ValidityConditionChecker}; +use sov_state::codec::BcsCodec; use sov_state::WorkingSet; /// Type alias that contains the height of a given transition pub type TransitionHeight = u64; -#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, PartialEq, Eq)] +#[derive(BorshDeserialize, BorshSerialize, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] /// Structure that contains the information needed to represent a single state transition. pub struct StateTransitionId { da_block_hash: Da::SlotHash, @@ -77,7 +79,7 @@ impl StateTransitionId { } } -#[derive(BorshDeserialize, BorshSerialize, Debug, PartialEq, Eq, Clone)] +#[derive(BorshDeserialize, BorshSerialize, Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] /// Represents a transition in progress for the rollup. pub struct TransitionInProgress { da_block_hash: Da::SlotHash, @@ -114,11 +116,11 @@ pub struct ChainState /// is stored during transition i+1. This is mainly due to the fact that this structure depends on the /// rollup's root hash which is only stored once the transition has completed. #[state] - historical_transitions: sov_state::StateMap>, + historical_transitions: sov_state::StateMap, BcsCodec>, /// The transition that is currently processed #[state] - in_progress_transition: sov_state::StateValue>, + in_progress_transition: sov_state::StateValue, BcsCodec>, /// The genesis root hash. /// Set after the first transaction of the rollup is executed, using the `begin_slot` hook. @@ -136,11 +138,7 @@ pub struct ChainStateConfig { pub initial_slot_height: TransitionHeight, } -impl ChainState -where - Da::ValidityCondition: BorshSerialize + BorshDeserialize, - Da::SlotHash: BorshSerialize + BorshDeserialize, -{ +impl ChainState { /// Returns transition height in the current slot pub fn get_slot_height(&self, working_set: &mut WorkingSet) -> TransitionHeight { self.slot_height diff --git a/module-system/module-implementations/sov-chain-state/src/query.rs b/module-system/module-implementations/sov-chain-state/src/query.rs index 81cf43413..f93536a04 100644 --- a/module-system/module-implementations/sov-chain-state/src/query.rs +++ b/module-system/module-implementations/sov-chain-state/src/query.rs @@ -1,4 +1,3 @@ -use borsh::{BorshDeserialize, BorshSerialize}; use jsonrpsee::core::RpcResult; use sov_modules_api::macros::rpc_gen; use sov_state::WorkingSet; @@ -6,11 +5,7 @@ use sov_state::WorkingSet; use crate::{ChainState, TransitionHeight}; #[rpc_gen(client, server, namespace = "chainState")] -impl ChainState -where - Da::SlotHash: BorshSerialize + BorshDeserialize, - Da::ValidityCondition: BorshSerialize + BorshDeserialize, -{ +impl ChainState { /// Get the height of the current slot. /// Panics if the slot height is not set #[rpc_method(name = "getSlotHeight")] diff --git a/module-system/module-implementations/sov-prover-incentives/src/call.rs b/module-system/module-implementations/sov-prover-incentives/src/call.rs index b41b80400..3552981be 100644 --- a/module-system/module-implementations/sov-prover-incentives/src/call.rs +++ b/module-system/module-implementations/sov-prover-incentives/src/call.rs @@ -125,8 +125,7 @@ impl ProverIncentives= minimum_bond, "Prover is not bonded"); let code_commitment = self .commitment_of_allowed_verifier_method - .get_or_err(working_set)? - .commitment; + .get_or_err(working_set)?; // Lock the prover's bond amount. self.bonded_provers diff --git a/module-system/module-implementations/sov-prover-incentives/src/genesis.rs b/module-system/module-implementations/sov-prover-incentives/src/genesis.rs index f4b4fb123..13f99cadf 100644 --- a/module-system/module-implementations/sov-prover-incentives/src/genesis.rs +++ b/module-system/module-implementations/sov-prover-incentives/src/genesis.rs @@ -18,12 +18,8 @@ impl ProverIncentives { /// The code commitment to be used for verifying proofs #[state] - pub commitment_of_allowed_verifier_method: sov_state::StateValue>, + pub commitment_of_allowed_verifier_method: sov_state::StateValue, /// The set of registered provers and their bonded amount. #[state] diff --git a/module-system/sov-modules-api/src/lib.rs b/module-system/sov-modules-api/src/lib.rs index 8ad4df898..667230621 100644 --- a/module-system/sov-modules-api/src/lib.rs +++ b/module-system/sov-modules-api/src/lib.rs @@ -51,7 +51,7 @@ pub use sov_rollup_interface::da::{BlobReaderTrait, DaSpec}; pub use sov_rollup_interface::services::da::SlotData; pub use sov_rollup_interface::stf::Event; pub use sov_rollup_interface::zk::{ - StateTransition, StoredCodeCommitment, ValidityCondition, ValidityConditionChecker, Zkvm, + StateTransition, ValidityCondition, ValidityConditionChecker, Zkvm, }; pub use sov_rollup_interface::{digest, BasicAddress, RollupAddress}; use sov_state::{Storage, Witness, WorkingSet}; diff --git a/rollup-interface/src/state_machine/da.rs b/rollup-interface/src/state_machine/da.rs index 3fb823bd9..94b638fda 100644 --- a/rollup-interface/src/state_machine/da.rs +++ b/rollup-interface/src/state_machine/da.rs @@ -180,7 +180,7 @@ pub trait BlobReaderTrait: Serialize + DeserializeOwned + Send + Sync + 'static /// Trait with collection of trait bounds for a block hash. pub trait BlockHashTrait: - Serialize + DeserializeOwned + PartialEq + Debug + Send + Sync + Clone + Eq + Serialize + DeserializeOwned + PartialEq + Debug + Send + Sync + Clone + Eq + Into<[u8; 32]> { } diff --git a/rollup-interface/src/state_machine/mocks/da.rs b/rollup-interface/src/state_machine/mocks/da.rs index d39a08216..dad60892c 100644 --- a/rollup-interface/src/state_machine/mocks/da.rs +++ b/rollup-interface/src/state_machine/mocks/da.rs @@ -160,6 +160,12 @@ impl From<[u8; 32]> for MockHash { } } +impl From for [u8; 32] { + fn from(value: MockHash) -> Self { + value.0 + } +} + impl BlockHashTrait for MockHash {} /// A mock block header used for testing. diff --git a/rollup-interface/src/state_machine/mocks/zk_vm.rs b/rollup-interface/src/state_machine/mocks/zk_vm.rs index e066c0fc1..a057c59d7 100644 --- a/rollup-interface/src/state_machine/mocks/zk_vm.rs +++ b/rollup-interface/src/state_machine/mocks/zk_vm.rs @@ -77,6 +77,14 @@ impl Zkvm for MockZkvm { anyhow::ensure!(proof.is_valid, "Proof is not valid"); Ok(proof.log) } + + fn verify_and_extract_output( + serialized_proof: &[u8], + code_commitment: &Self::CodeCommitment, + ) -> Result, Self::Error> { + let mut output = Self::verify(serialized_proof, code_commitment)?; + Ok(bincode::deserialize(&mut output)?) + } } #[test] diff --git a/rollup-interface/src/state_machine/optimistic.rs b/rollup-interface/src/state_machine/optimistic.rs index 2019a1b46..84e4eb166 100644 --- a/rollup-interface/src/state_machine/optimistic.rs +++ b/rollup-interface/src/state_machine/optimistic.rs @@ -10,7 +10,7 @@ use crate::zk::StateTransition; #[derive( Debug, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize, Serialize, Deserialize, Default, )] -pub struct ProofOfBond { +pub struct ProofOfBond { /// The transition number for which the proof of bond applies pub claimed_transition_num: u64, /// The actual state proof that the attester was bonded @@ -21,7 +21,7 @@ pub struct ProofOfBond { #[derive( Debug, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize, Serialize, Deserialize, Default, )] -pub struct Attestation { +pub struct Attestation { /// The alleged state root before applying the contents of the da block pub initial_state_root: [u8; 32], /// The hash of the block in which the transition occurred diff --git a/rollup-interface/src/state_machine/zk/mod.rs b/rollup-interface/src/state_machine/zk/mod.rs index 0d2cb6b21..201d3dc5d 100644 --- a/rollup-interface/src/state_machine/zk/mod.rs +++ b/rollup-interface/src/state_machine/zk/mod.rs @@ -45,43 +45,14 @@ pub trait Zkvm { /// Same as [`verify`](Zkvm::verify), except that instead of returning the output /// as a serialized array, it returns a state transition structure. /// TODO: specify a deserializer for the output - fn verify_and_extract_output< - Add: RollupAddress + BorshDeserialize + BorshSerialize, - Da: DaSpec, - >( + fn verify_and_extract_output( serialized_proof: &[u8], code_commitment: &Self::CodeCommitment, - ) -> Result, Self::Error> - where - Da::SlotHash: BorshDeserialize + BorshSerialize, - Da::ValidityCondition: BorshDeserialize + BorshSerialize, - { - let mut output = Self::verify(serialized_proof, code_commitment)?; - Ok(BorshDeserialize::deserialize_reader(&mut output)?) - } -} - -/// A wrapper around a code commitment which implements borsh serialization -#[derive(Clone, Debug)] -pub struct StoredCodeCommitment { - /// The inner field of the wrapper that contains the code commitment. - pub commitment: Vm::CodeCommitment, -} - -impl BorshSerialize for StoredCodeCommitment { - fn serialize(&self, writer: &mut W) -> std::io::Result<()> { - bincode::serialize_into(writer, &self.commitment) - .expect("Serialization to vec is infallible"); - Ok(()) - } -} - -impl BorshDeserialize for StoredCodeCommitment { - fn deserialize_reader(reader: &mut R) -> std::io::Result { - let commitment: Vm::CodeCommitment = bincode::deserialize_from(reader) - .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?; - Ok(Self { commitment }) - } + ) -> Result, Self::Error>; + //{ + // let mut output = Self::verify(serialized_proof, code_commitment)?; + // Ok(BorshDeserialize::deserialize_reader(&mut output)?) + // } } /// A trait which is accessible from within a zkVM program. From 44ef20caccf4c5e61a8fe295b6382c6d92d24ada Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Mon, 11 Sep 2023 12:56:07 -0500 Subject: [PATCH 05/21] lint; clippy --- adapters/celestia/src/verifier/mod.rs | 6 +++--- full-node/sov-stf-runner/src/runner.rs | 2 +- .../sov-attester-incentives/src/call.rs | 2 +- .../sov-blob-storage/src/capabilities.rs | 1 - .../module-implementations/sov-blob-storage/src/lib.rs | 2 +- .../module-implementations/sov-chain-state/src/hooks.rs | 3 +-- rollup-interface/src/state_machine/mocks/zk_vm.rs | 4 ++-- 7 files changed, 9 insertions(+), 11 deletions(-) diff --git a/adapters/celestia/src/verifier/mod.rs b/adapters/celestia/src/verifier/mod.rs index 8a36e8ba0..3d1b1255a 100644 --- a/adapters/celestia/src/verifier/mod.rs +++ b/adapters/celestia/src/verifier/mod.rs @@ -89,9 +89,9 @@ impl AsRef for tendermint::Hash { impl BlockHash for TmHash {} -impl Into<[u8; 32]> for TmHash { - fn into(self) -> [u8; 32] { - *self.inner() +impl From for [u8; 32] { + fn from(val: TmHash) -> Self { + *val.inner() } } diff --git a/full-node/sov-stf-runner/src/runner.rs b/full-node/sov-stf-runner/src/runner.rs index 4bf9a0430..178ed5c6c 100644 --- a/full-node/sov-stf-runner/src/runner.rs +++ b/full-node/sov-stf-runner/src/runner.rs @@ -128,7 +128,7 @@ where let slot_result = self.app.apply_slot( Default::default(), - &filtered_block.header(), + filtered_block.header(), &filtered_block.validity_condition(), &mut blobs, ); diff --git a/module-system/module-implementations/sov-attester-incentives/src/call.rs b/module-system/module-implementations/sov-attester-incentives/src/call.rs index fdb98c29f..99279d34a 100644 --- a/module-system/module-implementations/sov-attester-incentives/src/call.rs +++ b/module-system/module-implementations/sov-attester-incentives/src/call.rs @@ -53,7 +53,7 @@ impl BorshDeserialize } fn deserialize(buf: &mut &[u8]) -> std::io::Result { - bcs::from_bytes(*buf) + bcs::from_bytes(buf) .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string())) } } diff --git a/module-system/module-implementations/sov-blob-storage/src/capabilities.rs b/module-system/module-implementations/sov-blob-storage/src/capabilities.rs index 08497e856..02bc0ea39 100644 --- a/module-system/module-implementations/sov-blob-storage/src/capabilities.rs +++ b/module-system/module-implementations/sov-blob-storage/src/capabilities.rs @@ -1,4 +1,3 @@ -use borsh::{BorshDeserialize, BorshSerialize}; use sov_chain_state::TransitionHeight; use sov_modules_api::capabilities::{BlobRefOrOwned, BlobSelector}; use sov_modules_api::{BlobReaderTrait, Context, DaSpec, Spec}; diff --git a/module-system/module-implementations/sov-blob-storage/src/lib.rs b/module-system/module-implementations/sov-blob-storage/src/lib.rs index 9e8c45119..e8c339a21 100644 --- a/module-system/module-implementations/sov-blob-storage/src/lib.rs +++ b/module-system/module-implementations/sov-blob-storage/src/lib.rs @@ -4,7 +4,7 @@ mod capabilities; #[cfg(feature = "native")] mod query; -use borsh::{BorshDeserialize, BorshSerialize}; + #[cfg(feature = "native")] pub use query::{BlobStorageRpcImpl, BlobStorageRpcServer, Response}; use sov_chain_state::TransitionHeight; diff --git a/module-system/module-implementations/sov-chain-state/src/hooks.rs b/module-system/module-implementations/sov-chain-state/src/hooks.rs index 5ca03de9f..a934ab1a6 100644 --- a/module-system/module-implementations/sov-chain-state/src/hooks.rs +++ b/module-system/module-implementations/sov-chain-state/src/hooks.rs @@ -1,4 +1,3 @@ -use borsh::{BorshDeserialize, BorshSerialize}; use sov_modules_api::hooks::SlotHooks; use sov_modules_api::{Context, Spec}; use sov_rollup_interface::da::BlockHeaderTrait; @@ -57,7 +56,7 @@ impl SlotHooks for ChainState Result, Self::Error> { - let mut output = Self::verify(serialized_proof, code_commitment)?; - Ok(bincode::deserialize(&mut output)?) + let output = Self::verify(serialized_proof, code_commitment)?; + Ok(bincode::deserialize(output)?) } } From 327db23441d0811e59b59d8452c1cb5d796e3611 Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Mon, 11 Sep 2023 13:10:48 -0500 Subject: [PATCH 06/21] Move curr_hash to MockBlockHeader --- examples/demo-rollup/benches/rng_xfers.rs | 4 +- examples/demo-rollup/benches/rollup_bench.rs | 4 +- .../benches/rollup_coarse_measure.rs | 4 +- examples/demo-rollup/src/test_rpc.rs | 6 +-- .../src/chain_state/tests.rs | 8 ++-- .../src/tests/helpers.rs | 4 +- .../tests/capability_tests.rs | 44 +++++++++---------- .../sov-chain-state/tests/all_tests.rs | 8 ++-- .../src/state_machine/mocks/da.rs | 14 +++--- 9 files changed, 48 insertions(+), 48 deletions(-) diff --git a/examples/demo-rollup/benches/rng_xfers.rs b/examples/demo-rollup/benches/rng_xfers.rs index 2cd6fc0a9..4b697718c 100644 --- a/examples/demo-rollup/benches/rng_xfers.rs +++ b/examples/demo-rollup/benches/rng_xfers.rs @@ -118,9 +118,9 @@ impl DaService for RngDaService { barray[..num_bytes.len()].copy_from_slice(&num_bytes); let block = MockBlock { - curr_hash: barray, header: MockBlockHeader { - prev_hash: MockHash([0u8; 32]), + hash: barray.into(), + prev_hash: [0u8; 32].into(), }, height, validity_cond: MockValidityCond { is_valid: true }, diff --git a/examples/demo-rollup/benches/rollup_bench.rs b/examples/demo-rollup/benches/rollup_bench.rs index 5bc52fe3a..3494bbce5 100644 --- a/examples/demo-rollup/benches/rollup_bench.rs +++ b/examples/demo-rollup/benches/rollup_bench.rs @@ -64,9 +64,9 @@ fn rollup_bench(_bench: &mut Criterion) { let mut barray = [0u8; 32]; barray[..num_bytes.len()].copy_from_slice(&num_bytes); let filtered_block = MockBlock { - curr_hash: barray, header: MockBlockHeader { - prev_hash: MockHash([0u8; 32]), + hash: barray.into(), + prev_hash: [0u8; 32].into(), }, height, validity_cond: Default::default(), diff --git a/examples/demo-rollup/benches/rollup_coarse_measure.rs b/examples/demo-rollup/benches/rollup_coarse_measure.rs index 8229ed602..f34feaf66 100644 --- a/examples/demo-rollup/benches/rollup_coarse_measure.rs +++ b/examples/demo-rollup/benches/rollup_coarse_measure.rs @@ -116,9 +116,9 @@ async fn main() -> Result<(), anyhow::Error> { let mut barray = [0u8; 32]; barray[..num_bytes.len()].copy_from_slice(&num_bytes); let filtered_block = MockBlock { - curr_hash: barray, header: MockBlockHeader { - prev_hash: MockHash([0u8; 32]), + prev_hash: [0u8; 32].into(), + hash: barray.into(), }, height, validity_cond: Default::default(), diff --git a/examples/demo-rollup/src/test_rpc.rs b/examples/demo-rollup/src/test_rpc.rs index d853b7109..55c8f6a66 100644 --- a/examples/demo-rollup/src/test_rpc.rs +++ b/examples/demo-rollup/src/test_rpc.rs @@ -110,9 +110,9 @@ fn batch2_tx_receipts() -> Vec> { fn regular_test_helper(payload: serde_json::Value, expected: &serde_json::Value) { let mut slots: Vec> = vec![SlotCommit::new(MockBlock { - curr_hash: sha2::Sha256::digest(b"slot_data"), header: MockBlockHeader { - prev_hash: MockHash(sha2::Sha256::digest(b"prev_header")), + prev_hash: sha2::Sha256::digest(b"prev_header").into(), + hash: sha2::Sha256::digest(b"slot_data").into(), }, height: 0, validity_cond: Default::default(), @@ -315,8 +315,8 @@ prop_compose! { for (batches, hash) in batches_and_hashes{ let mut new_slot = SlotCommit::new(MockBlock { - curr_hash: hash, header: MockBlockHeader { + hash: hash.into(), prev_hash, }, height: 0, diff --git a/module-system/module-implementations/integration-tests/src/chain_state/tests.rs b/module-system/module-implementations/integration-tests/src/chain_state/tests.rs index 5df74427f..97e34023c 100644 --- a/module-system/module-implementations/integration-tests/src/chain_state/tests.rs +++ b/module-system/module-implementations/integration-tests/src/chain_state/tests.rs @@ -46,9 +46,9 @@ fn test_simple_value_setter_with_chain_state() { ); let slot_data: MockBlock = MockBlock { - curr_hash: [10; 32], header: MockBlockHeader { - prev_hash: MockHash([0; 32]), + prev_hash: [0; 32].into(), + hash: [10; 32].into(), }, height: 0, validity_cond: MockValidityCond::default(), @@ -115,9 +115,9 @@ fn test_simple_value_setter_with_chain_state() { // We apply a new transaction with the same values let new_slot_data: MockBlock = MockBlock { - curr_hash: [20; 32], header: MockBlockHeader { - prev_hash: MockHash([10; 32]), + prev_hash: [10; 32].into(), + hash: [20; 32].into(), }, height: 1, validity_cond: MockValidityCond::default(), diff --git a/module-system/module-implementations/sov-attester-incentives/src/tests/helpers.rs b/module-system/module-implementations/sov-attester-incentives/src/tests/helpers.rs index 4c06a3828..87f47074c 100644 --- a/module-system/module-implementations/sov-attester-incentives/src/tests/helpers.rs +++ b/module-system/module-implementations/sov-attester-incentives/src/tests/helpers.rs @@ -165,9 +165,9 @@ pub(crate) fn execution_simulation Self { Self { prev_hash: MockHash([0u8; 32]), + hash: MockHash([1u8; 32]), } } } @@ -191,15 +193,13 @@ impl BlockHeaderTrait for MockBlockHeader { } fn hash(&self) -> Self::Hash { - MockHash(sha2::Sha256::digest(self.prev_hash.0).into()) + self.hash } } /// A mock block type used for testing. #[derive(Serialize, Deserialize, PartialEq, core::fmt::Debug, Clone)] pub struct MockBlock { - /// The hash of this block. - pub curr_hash: [u8; 32], /// The header of this block. pub header: MockBlockHeader, /// The height of this block @@ -213,9 +213,9 @@ pub struct MockBlock { impl Default for MockBlock { fn default() -> Self { Self { - curr_hash: [0; 32], header: MockBlockHeader { - prev_hash: MockHash([0; 32]), + prev_hash: [0; 32].into(), + hash: [1; 32].into(), }, height: 0, validity_cond: Default::default(), @@ -229,7 +229,7 @@ impl SlotData for MockBlock { type Cond = MockValidityCond; fn hash(&self) -> [u8; 32] { - self.curr_hash + self.header.hash.0 } fn header(&self) -> &Self::BlockHeader { From 6de2217b74e1075a26d717aca482d9a32bb7e113 Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Mon, 11 Sep 2023 13:12:23 -0500 Subject: [PATCH 07/21] lint --- examples/demo-rollup/benches/rollup_bench.rs | 2 +- examples/demo-rollup/benches/rollup_coarse_measure.rs | 2 +- .../sov-attester-incentives/src/tests/helpers.rs | 2 +- .../sov-blob-storage/tests/capability_tests.rs | 2 +- .../module-implementations/sov-chain-state/tests/all_tests.rs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/demo-rollup/benches/rollup_bench.rs b/examples/demo-rollup/benches/rollup_bench.rs index 3494bbce5..520073324 100644 --- a/examples/demo-rollup/benches/rollup_bench.rs +++ b/examples/demo-rollup/benches/rollup_bench.rs @@ -13,7 +13,7 @@ use rng_xfers::{RngDaService, RngDaSpec, SEQUENCER_DA_ADDRESS}; use sov_db::ledger_db::{LedgerDB, SlotCommit}; use sov_modules_api::default_signature::private_key::DefaultPrivateKey; use sov_modules_api::PrivateKey; -use sov_rollup_interface::mocks::{MockAddress, MockBlock, MockBlockHeader, MockHash}; +use sov_rollup_interface::mocks::{MockAddress, MockBlock, MockBlockHeader}; use sov_rollup_interface::services::da::DaService; use sov_rollup_interface::stf::StateTransitionFunction; use sov_stf_runner::{from_toml_path, RollupConfig}; diff --git a/examples/demo-rollup/benches/rollup_coarse_measure.rs b/examples/demo-rollup/benches/rollup_coarse_measure.rs index f34feaf66..456beb36d 100644 --- a/examples/demo-rollup/benches/rollup_coarse_measure.rs +++ b/examples/demo-rollup/benches/rollup_coarse_measure.rs @@ -16,7 +16,7 @@ use rng_xfers::{RngDaService, RngDaSpec}; use sov_db::ledger_db::{LedgerDB, SlotCommit}; use sov_modules_api::default_signature::private_key::DefaultPrivateKey; use sov_modules_api::PrivateKey; -use sov_rollup_interface::mocks::{MockBlock, MockBlockHeader, MockHash}; +use sov_rollup_interface::mocks::{MockBlock, MockBlockHeader}; use sov_rollup_interface::services::da::DaService; use sov_rollup_interface::stf::StateTransitionFunction; use sov_stf_runner::{from_toml_path, RollupConfig}; diff --git a/module-system/module-implementations/sov-attester-incentives/src/tests/helpers.rs b/module-system/module-implementations/sov-attester-incentives/src/tests/helpers.rs index 87f47074c..f558bf011 100644 --- a/module-system/module-implementations/sov-attester-incentives/src/tests/helpers.rs +++ b/module-system/module-implementations/sov-attester-incentives/src/tests/helpers.rs @@ -5,7 +5,7 @@ use sov_modules_api::hooks::SlotHooks; use sov_modules_api::utils::generate_address; use sov_modules_api::{Address, Genesis, Spec, ValidityConditionChecker}; use sov_rollup_interface::mocks::{ - MockBlock, MockBlockHeader, MockCodeCommitment, MockDaSpec, MockHash, MockValidityCond, + MockBlock, MockBlockHeader, MockCodeCommitment, MockDaSpec, MockValidityCond, MockValidityCondChecker, MockZkvm, }; use sov_state::storage::StorageProof; diff --git a/module-system/module-implementations/sov-blob-storage/tests/capability_tests.rs b/module-system/module-implementations/sov-blob-storage/tests/capability_tests.rs index 76a94ae5e..77b45e5d9 100644 --- a/module-system/module-implementations/sov-blob-storage/tests/capability_tests.rs +++ b/module-system/module-implementations/sov-blob-storage/tests/capability_tests.rs @@ -7,7 +7,7 @@ use sov_modules_api::digest::Digest; use sov_modules_api::hooks::SlotHooks; use sov_modules_api::{Address, BlobReaderTrait, Context, Module, Spec}; use sov_rollup_interface::mocks::{ - MockAddress, MockBlob, MockBlock, MockBlockHeader, MockDaSpec, MockHash, MockValidityCond, + MockAddress, MockBlob, MockBlock, MockBlockHeader, MockDaSpec, MockValidityCond, }; use sov_sequencer_registry::{SequencerConfig, SequencerRegistry}; use sov_state::{ProverStorage, Storage, WorkingSet}; diff --git a/module-system/module-implementations/sov-chain-state/tests/all_tests.rs b/module-system/module-implementations/sov-chain-state/tests/all_tests.rs index 361acc48e..9388e8afc 100644 --- a/module-system/module-implementations/sov-chain-state/tests/all_tests.rs +++ b/module-system/module-implementations/sov-chain-state/tests/all_tests.rs @@ -3,7 +3,7 @@ use sov_modules_api::default_context::DefaultContext; use sov_modules_api::hooks::SlotHooks; use sov_modules_api::Genesis; use sov_rollup_interface::mocks::{ - MockBlock, MockBlockHeader, MockDaSpec, MockHash, MockValidityCond, + MockBlock, MockBlockHeader, MockDaSpec, MockValidityCond, }; use sov_state::{ProverStorage, Storage, WorkingSet}; From e83cb8d852c30f711be8efa7cff7b707a483c54e Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Mon, 11 Sep 2023 13:29:21 -0500 Subject: [PATCH 08/21] fix benches --- examples/demo-rollup/benches/rollup_bench.rs | 1 + examples/demo-rollup/benches/rollup_coarse_measure.rs | 3 ++- .../module-implementations/sov-chain-state/tests/all_tests.rs | 4 +--- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/demo-rollup/benches/rollup_bench.rs b/examples/demo-rollup/benches/rollup_bench.rs index 535047c0f..74e95b51c 100644 --- a/examples/demo-rollup/benches/rollup_bench.rs +++ b/examples/demo-rollup/benches/rollup_bench.rs @@ -12,6 +12,7 @@ use rng_xfers::{RngDaService, RngDaSpec, SEQUENCER_DA_ADDRESS}; use sov_db::ledger_db::{LedgerDB, SlotCommit}; use sov_modules_api::default_signature::private_key::DefaultPrivateKey; use sov_modules_api::PrivateKey; +use sov_risc0_adapter::host::Risc0Verifier; use sov_rollup_interface::mocks::{MockAddress, MockBlock, MockBlockHeader}; use sov_rollup_interface::services::da::DaService; use sov_rollup_interface::stf::StateTransitionFunction; diff --git a/examples/demo-rollup/benches/rollup_coarse_measure.rs b/examples/demo-rollup/benches/rollup_coarse_measure.rs index 88a3a0275..0000f18f4 100644 --- a/examples/demo-rollup/benches/rollup_coarse_measure.rs +++ b/examples/demo-rollup/benches/rollup_coarse_measure.rs @@ -140,7 +140,8 @@ async fn main() -> Result<(), anyhow::Error> { let mut data_to_commit = SlotCommit::new(filtered_block.clone()); let apply_block_results = demo.apply_slot( Default::default(), - data_to_commit.slot_data(), + filtered_block.header, + filtered_block.validity_cond, &mut blobs[0usize], ); data_to_commit.add_batch(apply_block_results.batch_receipts[0].clone()); diff --git a/module-system/module-implementations/sov-chain-state/tests/all_tests.rs b/module-system/module-implementations/sov-chain-state/tests/all_tests.rs index 9388e8afc..fa7abaa90 100644 --- a/module-system/module-implementations/sov-chain-state/tests/all_tests.rs +++ b/module-system/module-implementations/sov-chain-state/tests/all_tests.rs @@ -2,9 +2,7 @@ use sov_chain_state::{ChainState, ChainStateConfig, StateTransitionId, Transitio use sov_modules_api::default_context::DefaultContext; use sov_modules_api::hooks::SlotHooks; use sov_modules_api::Genesis; -use sov_rollup_interface::mocks::{ - MockBlock, MockBlockHeader, MockDaSpec, MockValidityCond, -}; +use sov_rollup_interface::mocks::{MockBlock, MockBlockHeader, MockDaSpec, MockValidityCond}; use sov_state::{ProverStorage, Storage, WorkingSet}; /// This simply tests that the chain_state reacts properly with the invocation of the `begin_slot` From a5a0f7bc6ed45b48b3eef68a9f34c2fc08b298c6 Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Mon, 11 Sep 2023 13:32:44 -0500 Subject: [PATCH 09/21] add missing borrow --- examples/demo-rollup/benches/rollup_coarse_measure.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/demo-rollup/benches/rollup_coarse_measure.rs b/examples/demo-rollup/benches/rollup_coarse_measure.rs index 0000f18f4..520e399fe 100644 --- a/examples/demo-rollup/benches/rollup_coarse_measure.rs +++ b/examples/demo-rollup/benches/rollup_coarse_measure.rs @@ -140,8 +140,8 @@ async fn main() -> Result<(), anyhow::Error> { let mut data_to_commit = SlotCommit::new(filtered_block.clone()); let apply_block_results = demo.apply_slot( Default::default(), - filtered_block.header, - filtered_block.validity_cond, + &filtered_block.header, + &filtered_block.validity_cond, &mut blobs[0usize], ); data_to_commit.add_batch(apply_block_results.batch_receipts[0].clone()); From ce5fb24defe4d345f8ae0a392ec28653babdc293 Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Mon, 11 Sep 2023 13:32:57 -0500 Subject: [PATCH 10/21] remove commented code --- rollup-interface/src/state_machine/zk/mod.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/rollup-interface/src/state_machine/zk/mod.rs b/rollup-interface/src/state_machine/zk/mod.rs index 201d3dc5d..41483dba2 100644 --- a/rollup-interface/src/state_machine/zk/mod.rs +++ b/rollup-interface/src/state_machine/zk/mod.rs @@ -49,10 +49,6 @@ pub trait Zkvm { serialized_proof: &[u8], code_commitment: &Self::CodeCommitment, ) -> Result, Self::Error>; - //{ - // let mut output = Self::verify(serialized_proof, code_commitment)?; - // Ok(BorshDeserialize::deserialize_reader(&mut output)?) - // } } /// A trait which is accessible from within a zkVM program. From fe61cfe131d20034f7761bdb024637121ccc115e Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Mon, 11 Sep 2023 15:03:46 -0500 Subject: [PATCH 11/21] fix feature gating. Fix demo-prover --- examples/demo-prover/Cargo.lock | 23 ++++---- examples/demo-prover/host/src/main.rs | 4 +- examples/demo-prover/methods/guest/Cargo.lock | 52 ++++++++++++++----- .../methods/guest/src/bin/rollup.rs | 10 ++-- examples/demo-stf/src/hooks_impl.rs | 4 +- .../sov-chain-state/Cargo.toml | 4 +- 6 files changed, 63 insertions(+), 34 deletions(-) diff --git a/examples/demo-prover/Cargo.lock b/examples/demo-prover/Cargo.lock index 87118da03..9c8413394 100644 --- a/examples/demo-prover/Cargo.lock +++ b/examples/demo-prover/Cargo.lock @@ -202,9 +202,8 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bcs" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd3ffe8b19a604421a5d461d4a70346223e535903fbc3067138bddbebddcf77" +version = "0.1.4" +source = "git+https://github.com/preston-evans98/bcs.git?rev=e4f1861#e4f1861509a996408baa540cda1f88c290214ce1" dependencies = [ "serde", "thiserror", @@ -3671,6 +3670,7 @@ dependencies = [ "serde", "serde_json", "sov-modules-api", + "sov-rollup-interface", "sov-state", ] @@ -3761,6 +3761,7 @@ dependencies = [ "jsonrpsee 0.18.2", "serde", "serde_json", + "sov-celestia-adapter", "sov-cli", "sov-db", "sov-modules-api", @@ -3978,6 +3979,14 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "sov-zk-cycle-utils" +version = "0.1.0" +dependencies = [ + "risc0-zkvm", + "risc0-zkvm-platform", +] + [[package]] name = "spin" version = "0.5.2" @@ -4884,14 +4893,6 @@ dependencies = [ "zstd", ] -[[package]] -name = "sov-zk-cycle-utils" -version = "0.1.0" -dependencies = [ - "risc0-zkvm", - "risc0-zkvm-platform", -] - [[package]] name = "zstd" version = "0.11.2+zstd.1.5.2" diff --git a/examples/demo-prover/host/src/main.rs b/examples/demo-prover/host/src/main.rs index bcce1bd73..0c550a316 100644 --- a/examples/demo-prover/host/src/main.rs +++ b/examples/demo-prover/host/src/main.rs @@ -10,7 +10,7 @@ use sov_celestia_adapter::types::NamespaceId; use sov_celestia_adapter::verifier::address::CelestiaAddress; use sov_celestia_adapter::verifier::{CelestiaSpec, RollupParams}; use sov_celestia_adapter::{CelestiaService, DaServiceConfig}; -use sov_modules_api::PrivateKey; +use sov_modules_api::{PrivateKey, SlotData}; use sov_risc0_adapter::host::{Risc0Host, Risc0Verifier}; use sov_rollup_interface::services::da::DaService; use sov_rollup_interface::stf::StateTransitionFunction; @@ -120,7 +120,7 @@ async fn main() -> Result<(), anyhow::Error> { let result = app .stf - .apply_slot(Default::default(), &filtered_block, &mut blobs); + .apply_slot(Default::default(), filtered_block.header(), &filtered_block.validity_condition(), &mut blobs); // The extracted blobs need to be passed to the prover after execution. // (Without executing, the host couldn't prune any data that turned out to be irrelevant to the guest) diff --git a/examples/demo-prover/methods/guest/Cargo.lock b/examples/demo-prover/methods/guest/Cargo.lock index 336fe3479..33571db8d 100644 --- a/examples/demo-prover/methods/guest/Cargo.lock +++ b/examples/demo-prover/methods/guest/Cargo.lock @@ -106,9 +106,8 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bcs" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd3ffe8b19a604421a5d461d4a70346223e535903fbc3067138bddbebddcf77" +version = "0.1.4" +source = "git+https://github.com/preston-evans98/bcs.git?rev=e4f1861#e4f1861509a996408baa540cda1f88c290214ce1" dependencies = [ "serde", "thiserror", @@ -2019,13 +2018,42 @@ dependencies = [ "tracing", ] +[[package]] +name = "sov-celestia-adapter" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "base64 0.21.2", + "bech32", + "borsh", + "hex", + "hex-literal", + "nmt-rs", + "prost", + "prost-build", + "prost-types", + "risc0-zkvm", + "risc0-zkvm-platform", + "serde", + "sha2 0.10.6", + "sov-rollup-interface", + "sov-zk-cycle-macros", + "tendermint", + "tendermint-proto", + "thiserror", + "tracing", +] + [[package]] name = "sov-chain-state" version = "0.1.0" dependencies = [ "anyhow", "borsh", + "serde", "sov-modules-api", + "sov-rollup-interface", "sov-state", ] @@ -2111,9 +2139,9 @@ dependencies = [ "sov-rollup-interface", "sov-state", "sov-zk-cycle-macros", + "sov-zk-cycle-utils", "thiserror", "tracing", - "sov-zk-cycle-utils", ] [[package]] @@ -2201,6 +2229,14 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "sov-zk-cycle-utils" +version = "0.1.0" +dependencies = [ + "risc0-zkvm", + "risc0-zkvm-platform", +] + [[package]] name = "spki" version = "0.7.2" @@ -2825,14 +2861,6 @@ dependencies = [ "zstd", ] -[[package]] -name = "sov-zk-cycle-utils" -version = "0.1.0" -dependencies = [ - "risc0-zkvm", - "risc0-zkvm-platform", -] - [[package]] name = "zstd" version = "0.11.2+zstd.1.5.2" diff --git a/examples/demo-prover/methods/guest/src/bin/rollup.rs b/examples/demo-prover/methods/guest/src/bin/rollup.rs index c22991941..ec2244630 100644 --- a/examples/demo-prover/methods/guest/src/bin/rollup.rs +++ b/examples/demo-prover/methods/guest/src/bin/rollup.rs @@ -7,7 +7,6 @@ use std::str::FromStr; use const_rollup_config::{ROLLUP_NAMESPACE_RAW, SEQUENCER_DA_ADDRESS}; use demo_stf::app::create_zk_app_template; use demo_stf::ArrayWitness; -use risc0_adapter::guest::Risc0Guest; use risc0_zkvm::guest::env; use sov_celestia_adapter::types::NamespaceId; use sov_celestia_adapter::verifier::address::CelestiaAddress; @@ -15,8 +14,7 @@ use sov_celestia_adapter::verifier::{CelestiaSpec, CelestiaVerifier}; use sov_celestia_adapter::{BlobWithSender, CelestiaHeader}; use sov_risc0_adapter::guest::Risc0Guest; use sov_rollup_interface::crypto::NoOpHasher; -use sov_rollup_interface::da::{DaSpec, DaVerifier}; -use sov_rollup_interface::services::da::SlotData; +use sov_rollup_interface::da::{BlockHeaderTrait, DaSpec, DaVerifier}; use sov_rollup_interface::stf::StateTransitionFunction; use sov_rollup_interface::zk::{StateTransition, ZkvmGuest}; @@ -51,7 +49,7 @@ pub fn main() { env::write(&"blobs have been read\n"); // Step 2: Verify tx list - let verifier = CelestiaVerifier::new(celestia::verifier::RollupParams { + let verifier = CelestiaVerifier::new(sov_celestia_adapter::verifier::RollupParams { namespace: ROLLUP_NAMESPACE, }); @@ -67,13 +65,13 @@ pub fn main() { env::write(&"Witness have been read\n"); env::write(&"Applying slot...\n"); - let result = app.apply_slot(witness, &header, &mut blobs); + let result = app.apply_slot(witness, &header, &validity_condition, &mut blobs); env::write(&"Slot has been applied\n"); // TODO: https://github.com/Sovereign-Labs/sovereign-sdk/issues/647 let rewarded_address = CelestiaAddress::from_str(SEQUENCER_DA_ADDRESS).unwrap(); - let output = StateTransition { + let output = StateTransition:: { initial_state_root: prev_state_root_hash, final_state_root: result.state_root.0, validity_condition, diff --git a/examples/demo-stf/src/hooks_impl.rs b/examples/demo-stf/src/hooks_impl.rs index b6f1641d3..7df4ee00c 100644 --- a/examples/demo-stf/src/hooks_impl.rs +++ b/examples/demo-stf/src/hooks_impl.rs @@ -2,7 +2,9 @@ use sov_modules_api::hooks::{ApplyBlobHooks, SlotHooks, TxHooks}; use sov_modules_api::transaction::Transaction; use sov_modules_api::{Context, Spec}; use sov_modules_stf_template::SequencerOutcome; -use sov_rollup_interface::da::{BlobReaderTrait, BlockHeaderTrait, DaSpec}; +use sov_rollup_interface::da::{BlobReaderTrait, DaSpec}; +#[cfg(feature = "experimental")] +use sov_rollup_interface::da::BlockHeaderTrait; use sov_sequencer_registry::SequencerRegistry; use sov_state::WorkingSet; use tracing::info; diff --git a/module-system/module-implementations/sov-chain-state/Cargo.toml b/module-system/module-implementations/sov-chain-state/Cargo.toml index 470941a50..500f17879 100644 --- a/module-system/module-implementations/sov-chain-state/Cargo.toml +++ b/module-system/module-implementations/sov-chain-state/Cargo.toml @@ -14,7 +14,7 @@ resolver = "2" [dependencies] anyhow = { workspace = true } borsh = { workspace = true, features = ["rc"] } -serde = { workspace = true, optional = true } +serde = { workspace = true } serde_json = { workspace = true, optional = true } jsonrpsee = { workspace = true, features = ["macros", "client-core", "server"], optional = true } @@ -35,4 +35,4 @@ sov-rollup-interface = { path = "../../../rollup-interface", features = ["mocks" [features] default = [] -native = ["serde", "serde_json", "jsonrpsee", "sov-state/native", "sov-modules-api/native"] +native = ["serde_json", "jsonrpsee", "sov-state/native", "sov-modules-api/native"] From c945871ce9aac5ff2a5e6b803adf712e01f06d9e Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Mon, 11 Sep 2023 15:04:00 -0500 Subject: [PATCH 12/21] fmt demo prover --- examples/demo-prover/host/src/main.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/examples/demo-prover/host/src/main.rs b/examples/demo-prover/host/src/main.rs index 0c550a316..d2885e068 100644 --- a/examples/demo-prover/host/src/main.rs +++ b/examples/demo-prover/host/src/main.rs @@ -117,12 +117,15 @@ async fn main() -> Result<(), anyhow::Error> { // The above proofs of correctness and completeness need to passed to the prover host.write_to_guest(&inclusion_proof); host.write_to_guest(&completeness_proof); - - let result = app - .stf - .apply_slot(Default::default(), filtered_block.header(), &filtered_block.validity_condition(), &mut blobs); - // The extracted blobs need to be passed to the prover after execution. + let result = app.stf.apply_slot( + Default::default(), + filtered_block.header(), + &filtered_block.validity_condition(), + &mut blobs, + ); + + // The extracted blobs need to be passed to the prover after execution. // (Without executing, the host couldn't prune any data that turned out to be irrelevant to the guest) host.write_to_guest(&blobs); From 41d9e53a2c461180b644680553b7f8a52734dc9e Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Mon, 11 Sep 2023 15:14:11 -0500 Subject: [PATCH 13/21] lint --- examples/demo-stf/src/hooks_impl.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/demo-stf/src/hooks_impl.rs b/examples/demo-stf/src/hooks_impl.rs index 7df4ee00c..5c80199a8 100644 --- a/examples/demo-stf/src/hooks_impl.rs +++ b/examples/demo-stf/src/hooks_impl.rs @@ -2,9 +2,9 @@ use sov_modules_api::hooks::{ApplyBlobHooks, SlotHooks, TxHooks}; use sov_modules_api::transaction::Transaction; use sov_modules_api::{Context, Spec}; use sov_modules_stf_template::SequencerOutcome; -use sov_rollup_interface::da::{BlobReaderTrait, DaSpec}; #[cfg(feature = "experimental")] use sov_rollup_interface::da::BlockHeaderTrait; +use sov_rollup_interface::da::{BlobReaderTrait, DaSpec}; use sov_sequencer_registry::SequencerRegistry; use sov_state::WorkingSet; use tracing::info; From 3fbd9d7576ecd3434220432fb11bbc50a691c73b Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Mon, 11 Sep 2023 14:52:26 -0500 Subject: [PATCH 14/21] implement stv --- adapters/celestia/src/verifier/mod.rs | 2 +- .../methods/guest/src/bin/rollup.rs | 2 +- full-node/sov-stf-runner/src/lib.rs | 30 ++++++++++ full-node/sov-stf-runner/src/verifier.rs | 56 +++++++++++++++++++ module-system/sov-state/src/witness.rs | 3 +- rollup-interface/src/state_machine/da.rs | 5 +- rollup-interface/src/state_machine/stf.rs | 4 +- 7 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 full-node/sov-stf-runner/src/verifier.rs diff --git a/adapters/celestia/src/verifier/mod.rs b/adapters/celestia/src/verifier/mod.rs index 388a38388..1e3c9ea7f 100644 --- a/adapters/celestia/src/verifier/mod.rs +++ b/adapters/celestia/src/verifier/mod.rs @@ -166,7 +166,7 @@ impl da::DaVerifier for CelestiaVerifier { } #[cfg_attr(all(target_os = "zkvm", feature = "bench"), cycle_tracker)] - fn verify_relevant_tx_list( + fn verify_relevant_tx_list( &self, block_header: &::BlockHeader, txs: &[::BlobTransaction], diff --git a/examples/demo-prover/methods/guest/src/bin/rollup.rs b/examples/demo-prover/methods/guest/src/bin/rollup.rs index ec2244630..c04036a09 100644 --- a/examples/demo-prover/methods/guest/src/bin/rollup.rs +++ b/examples/demo-prover/methods/guest/src/bin/rollup.rs @@ -54,7 +54,7 @@ pub fn main() { }); let validity_condition = verifier - .verify_relevant_tx_list::(&header, &blobs, inclusion_proof, completeness_proof) + .verify_relevant_tx_list(&header, &blobs, inclusion_proof, completeness_proof) .expect("Transaction list must be correct"); env::write(&"Relevant txs verified\n"); diff --git a/full-node/sov-stf-runner/src/lib.rs b/full-node/sov-stf-runner/src/lib.rs index 2db8ae86d..defc63c28 100644 --- a/full-node/sov-stf-runner/src/lib.rs +++ b/full-node/sov-stf-runner/src/lib.rs @@ -6,6 +6,7 @@ mod batch_builder; #[cfg(feature = "native")] mod config; +use borsh::{BorshDeserialize, BorshSerialize}; #[cfg(feature = "native")] pub use config::RpcConfig; #[cfg(feature = "native")] @@ -20,3 +21,32 @@ pub use config::{from_toml_path, RollupConfig, RunnerConfig, StorageConfig}; pub use ledger_rpc::get_ledger_rpc; #[cfg(feature = "native")] pub use runner::*; +use serde::{Deserialize, Serialize}; +use sov_modules_api::{DaSpec, Zkvm}; +use sov_rollup_interface::stf::StateTransitionFunction; + +/// Implements the `StateTransitionVerifier` type for checking the validity of a state transition +pub mod verifier; + +#[derive(Serialize, BorshDeserialize, BorshSerialize, Deserialize)] +// Prevent serde from generating spurious trait bounds. The correct serde bounds are already enforced by the +// StateTransitionFunction, DA, and Zkvm traits. +#[serde(bound = "")] +/// Data required to verify a state transition. +pub struct StateTransitionData, DA: DaSpec, Zk> +where + Zk: Zkvm, +{ + /// The state root before the state transition + pub pre_state_root: ST::StateRoot, + /// The header of the da block that is being processed + pub da_block_header: DA::BlockHeader, + /// The proof of inclusion for all blobs + pub inclusion_proof: DA::InclusionMultiProof, + /// The proof that the provided set of blobs is complete + pub completeness_proof: DA::CompletenessProof, + /// The blobs that are being processed + pub blobs: Vec<::BlobTransaction>, + /// The witness for the state transition + pub state_transition_witness: ST::Witness, +} diff --git a/full-node/sov-stf-runner/src/verifier.rs b/full-node/sov-stf-runner/src/verifier.rs new file mode 100644 index 000000000..899474bd4 --- /dev/null +++ b/full-node/sov-stf-runner/src/verifier.rs @@ -0,0 +1,56 @@ +use std::marker::PhantomData; + +use sov_modules_api::Zkvm; +use sov_rollup_interface::da::DaVerifier; +use sov_rollup_interface::stf::StateTransitionFunction; +use sov_rollup_interface::zk::ZkvmGuest; + +use crate::StateTransitionData; + +/// Verifies a state transition +pub struct StateTransitionVerifier +where + Da: DaVerifier, + Zk: Zkvm, + ST: StateTransitionFunction, +{ + app: ST, + da_verifier: Da, + phantom: PhantomData, +} +impl StateTransitionVerifier +where + Da: DaVerifier, + Zk: ZkvmGuest, + ST: StateTransitionFunction, +{ + /// Create a [`StateTransitionVerifier`] + pub fn new(app: ST, da_verifier: Da) -> Self { + Self { + app, + da_verifier, + phantom: Default::default(), + } + } + + /// Verify the next block + pub fn run_block(&mut self, zkvm: Zk) -> Result { + let mut data: StateTransitionData = zkvm.read_from_host(); + let validity_condition = self.da_verifier.verify_relevant_tx_list( + &data.da_block_header, + &data.blobs, + data.inclusion_proof, + data.completeness_proof, + )?; + + let result = self.app.apply_slot( + data.state_transition_witness, + &data.da_block_header, + &validity_condition, + &mut data.blobs, + ); + + zkvm.commit(&result.state_root); + Ok(result.state_root) + } +} diff --git a/module-system/sov-state/src/witness.rs b/module-system/sov-state/src/witness.rs index eaa202cda..4c8bf1492 100644 --- a/module-system/sov-state/src/witness.rs +++ b/module-system/sov-state/src/witness.rs @@ -3,11 +3,12 @@ use std::sync::Mutex; use borsh::{BorshDeserialize, BorshSerialize}; use jmt::storage::TreeReader; +use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; // TODO: Refactor witness trait so it only require Serialize / Deserialize // https://github.com/Sovereign-Labs/sovereign-sdk/issues/263 -pub trait Witness: Default + Serialize { +pub trait Witness: Default + Serialize + DeserializeOwned { fn add_hint(&self, hint: T); fn get_hint(&self) -> T; fn merge(&self, rhs: &Self); diff --git a/rollup-interface/src/state_machine/da.rs b/rollup-interface/src/state_machine/da.rs index 94b638fda..1b4a8cbbd 100644 --- a/rollup-interface/src/state_machine/da.rs +++ b/rollup-interface/src/state_machine/da.rs @@ -5,7 +5,6 @@ use std::cmp::min; use borsh::{BorshDeserialize, BorshSerialize}; use bytes::Buf; -use digest::Digest; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; @@ -61,7 +60,7 @@ pub trait DaVerifier { fn new(params: ::ChainParams) -> Self; /// Verify a claimed set of transactions against a block header. - fn verify_relevant_tx_list( + fn verify_relevant_tx_list( &self, block_header: &::BlockHeader, txs: &[::BlobTransaction], @@ -185,7 +184,7 @@ pub trait BlockHashTrait: } /// A block header, typically used in the context of an underlying DA blockchain. -pub trait BlockHeaderTrait: PartialEq + Debug + Clone { +pub trait BlockHeaderTrait: PartialEq + Debug + Clone + Serialize + DeserializeOwned { /// Each block header must have a unique canonical hash. type Hash: Clone; /// Each block header must contain the hash of the previous block. diff --git a/rollup-interface/src/state_machine/stf.rs b/rollup-interface/src/state_machine/stf.rs index 57855467a..e3d6ad776 100644 --- a/rollup-interface/src/state_machine/stf.rs +++ b/rollup-interface/src/state_machine/stf.rs @@ -95,7 +95,7 @@ pub struct SlotResult { /// - blob: Non serialised batch or anything else that can be posted on DA layer, like attestation or proof. pub trait StateTransitionFunction { /// Root hash of state merkle tree - type StateRoot; + type StateRoot: Serialize + DeserializeOwned + Clone; /// The initial state of the rollup. type InitialState; @@ -107,7 +107,7 @@ pub trait StateTransitionFunction { /// Witness is a data that is produced during actual batch execution /// or validated together with proof during verification - type Witness: Default + Serialize; + type Witness: Default + Serialize + DeserializeOwned; /// The validity condition that must be verified outside of the Vm type Condition: ValidityCondition; From 06d883105be025e73276689fb0585cf54354eb6f Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Mon, 11 Sep 2023 17:26:39 -0500 Subject: [PATCH 15/21] Got to a failing test --- Cargo.lock | 1 - adapters/celestia/src/da_service.rs | 4 +- adapters/risc0/src/guest.rs | 80 ++++++++++++++++++- adapters/risc0/src/host.rs | 56 +++++++------ examples/demo-rollup/Cargo.toml | 1 - examples/demo-rollup/benches/rng_xfers.rs | 24 +++++- examples/demo-rollup/src/main.rs | 6 +- examples/demo-rollup/src/rollup.rs | 69 ++++++++++++---- examples/demo-rollup/tests/all_tests.rs | 3 + examples/demo-rollup/tests/bank/mod.rs | 15 +++- examples/demo-rollup/tests/evm/mod.rs | 4 +- examples/demo-rollup/tests/test_helpers.rs | 9 ++- full-node/sov-stf-runner/src/runner.rs | 51 ++++++++++-- rollup-interface/src/node/services/da.rs | 5 +- .../src/state_machine/mocks/da.rs | 31 ++++++- .../src/state_machine/mocks/mod.rs | 2 +- rollup-interface/src/state_machine/zk/mod.rs | 16 +++- 17 files changed, 309 insertions(+), 68 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 804f0091a..45cce4b8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6696,7 +6696,6 @@ dependencies = [ "sov-celestia-adapter", "sov-cli", "sov-db", - "sov-demo-rollup", "sov-ethereum", "sov-evm", "sov-modules-api", diff --git a/adapters/celestia/src/da_service.rs b/adapters/celestia/src/da_service.rs index e319d2646..e1eeb9e28 100644 --- a/adapters/celestia/src/da_service.rs +++ b/adapters/celestia/src/da_service.rs @@ -18,7 +18,7 @@ use crate::types::{ExtendedDataSquare, FilteredCelestiaBlock, Row, RpcNamespaced use crate::utils::BoxError; use crate::verifier::address::CelestiaAddress; use crate::verifier::proofs::{CompletenessProof, CorrectnessProof}; -use crate::verifier::{CelestiaSpec, RollupParams, PFB_NAMESPACE}; +use crate::verifier::{CelestiaSpec, CelestiaVerifier, RollupParams, PFB_NAMESPACE}; use crate::{ parse_pfb_namespace, BlobWithSender, CelestiaHeader, CelestiaHeaderResponse, DataAvailabilityHeader, @@ -143,6 +143,8 @@ impl CelestiaService { impl DaService for CelestiaService { type Spec = CelestiaSpec; + type Verifier = CelestiaVerifier; + type FilteredBlock = FilteredCelestiaBlock; type Error = BoxError; diff --git a/adapters/risc0/src/guest.rs b/adapters/risc0/src/guest.rs index a68cf1714..335bd3022 100644 --- a/adapters/risc0/src/guest.rs +++ b/adapters/risc0/src/guest.rs @@ -1,11 +1,12 @@ +use std::ops::DerefMut; + #[cfg(target_os = "zkvm")] use risc0_zkvm::guest::env; +use risc0_zkvm::serde::{Deserializer, WordRead}; use sov_rollup_interface::zk::{Zkvm, ZkvmGuest}; use crate::Risc0MethodId; -pub struct Risc0Guest; - #[cfg(target_os = "zkvm")] impl ZkvmGuest for Risc0Guest { fn read_from_host(&self) -> T { @@ -17,14 +18,85 @@ impl ZkvmGuest for Risc0Guest { } } +#[cfg(not(target_os = "zkvm"))] +struct Hints { + values: Vec, + position: usize, +} + +#[cfg(not(target_os = "zkvm"))] +impl Hints { + pub fn new() -> Self { + Hints { + values: Vec::new(), + position: 0, + } + } + + pub fn with_hints(hints: Vec) -> Self { + Hints { + values: hints, + position: 0, + } + } + pub fn remaining(&self) -> usize { + self.values.len() - self.position + } +} + +#[cfg(not(target_os = "zkvm"))] +impl WordRead for Hints { + fn read_words(&mut self, words: &mut [u32]) -> risc0_zkvm::serde::Result<()> { + if self.remaining() < words.len() { + return Err(risc0_zkvm::serde::Error::DeserializeUnexpectedEnd); + } + words.copy_from_slice(&self.values[self.position..self.position + words.len()]); + self.position += words.len(); + Ok(()) + } + + fn read_padded_bytes(&mut self, bytes: &mut [u8]) -> risc0_zkvm::serde::Result<()> { + let remaining_bytes: &[u8] = bytemuck::cast_slice(&self.values[self.position..]); + if bytes.len() > remaining_bytes.len() { + return Err(risc0_zkvm::serde::Error::DeserializeUnexpectedEnd); + } + bytes.copy_from_slice(&remaining_bytes[..bytes.len()]); + self.position += bytes.len() / std::mem::size_of::(); + Ok(()) + } +} + +pub struct Risc0Guest { + #[cfg(not(target_os = "zkvm"))] + hints: std::sync::Mutex, +} + +impl Risc0Guest { + pub fn new() -> Self { + Self { + #[cfg(not(target_os = "zkvm"))] + hints: std::sync::Mutex::new(Hints::new()), + } + } + + #[cfg(not(target_os = "zkvm"))] + pub fn with_hints(hints: Vec) -> Self { + Self { + hints: std::sync::Mutex::new(Hints::with_hints(hints)), + } + } +} + #[cfg(not(target_os = "zkvm"))] impl ZkvmGuest for Risc0Guest { fn read_from_host(&self) -> T { - unimplemented!("This method should only be called in zkvm mode") + let mut hints = self.hints.lock().unwrap(); + let mut hints = hints.deref_mut(); + T::deserialize(&mut Deserializer::new(&mut hints)).unwrap() } fn commit(&self, _item: &T) { - unimplemented!("This method should only be called in zkvm mode") + todo!() } } diff --git a/adapters/risc0/src/host.rs b/adapters/risc0/src/host.rs index f208fa88b..58a8a881c 100644 --- a/adapters/risc0/src/host.rs +++ b/adapters/risc0/src/host.rs @@ -1,4 +1,4 @@ -use std::cell::RefCell; +use std::sync::Mutex; use risc0_zkvm::receipt::Receipt; use risc0_zkvm::serde::to_vec; @@ -9,38 +9,36 @@ use sov_rollup_interface::zk::{Zkvm, ZkvmHost}; #[cfg(feature = "bench")] use sov_zk_cycle_utils::{cycle_count_callback, get_syscall_name, get_syscall_name_cycles}; +use crate::guest::Risc0Guest; #[cfg(feature = "bench")] use crate::metrics::metrics_callback; use crate::Risc0MethodId; pub struct Risc0Host<'a> { - env: RefCell>, + env: Mutex>, elf: &'a [u8], } -impl<'a> Risc0Host<'a> { - #[cfg(not(feature = "bench"))] - pub fn new(elf: &'a [u8]) -> Self { - let default_env = ExecutorEnvBuilder::default(); - - Self { - env: RefCell::new(default_env), - elf, - } - } +#[cfg(not(feature = "bench"))] +fn add_benchmarking_callbacks(env: ExecutorEnvBuilder<'_>) -> ExecutorEnvBuilder<'_> { + env +} - #[cfg(feature = "bench")] - pub fn new(elf: &'a [u8]) -> Self { - let mut default_env = ExecutorEnvBuilder::default(); +#[cfg(feature = "bench")] +fn add_benchmarking_callbacks(mut env: ExecutorEnvBuilder<'_>) -> ExecutorEnvBuilder<'_> { + let metrics_syscall_name = get_syscall_name(); + env.io_callback(metrics_syscall_name, metrics_callback); - let metrics_syscall_name = get_syscall_name(); - default_env.io_callback(metrics_syscall_name, metrics_callback); + let cycles_syscall_name = get_syscall_name_cycles(); + env.io_callback(cycles_syscall_name, cycle_count_callback); - let cycles_syscall_name = get_syscall_name_cycles(); - default_env.io_callback(cycles_syscall_name, cycle_count_callback); + env +} +impl<'a> Risc0Host<'a> { + pub fn new(elf: &'a [u8]) -> Self { Self { - env: RefCell::new(default_env), + env: Default::default(), elf, } } @@ -48,11 +46,13 @@ impl<'a> Risc0Host<'a> { /// Run a computation in the zkvm without generating a receipt. /// This creates the "Session" trace without invoking the heavy cryptographic machinery. pub fn run_without_proving(&mut self) -> anyhow::Result { - let env = self.env.borrow_mut().build()?; + let env = add_benchmarking_callbacks(ExecutorEnvBuilder::default()) + .add_input(&self.env.lock().unwrap()) + .build() + .unwrap(); let mut executor = LocalExecutor::from_elf(env, self.elf)?; executor.run() } - /// Run a computation in the zkvm and generate a receipt. pub fn run(&mut self) -> anyhow::Result { let session = self.run_without_proving()?; @@ -61,13 +61,19 @@ impl<'a> Risc0Host<'a> { } impl<'a> ZkvmHost for Risc0Host<'a> { - fn write_to_guest(&self, item: T) { + fn add_hint(&self, item: T) { let serialized = to_vec(&item).expect("Serialization to vec is infallible"); - self.env.borrow_mut().add_input(&serialized); + self.env.lock().unwrap().extend_from_slice(&serialized[..]); + } + + type Guest = Risc0Guest; + + fn simulate_with_hints(&mut self) -> Self::Guest { + Risc0Guest::with_hints(std::mem::take(&mut self.env.lock().unwrap())) } } -impl<'prover> Zkvm for Risc0Host<'prover> { +impl<'host> Zkvm for Risc0Host<'host> { type CodeCommitment = Risc0MethodId; type Error = anyhow::Error; diff --git a/examples/demo-rollup/Cargo.toml b/examples/demo-rollup/Cargo.toml index c9f8d6b8c..6ce40f84a 100644 --- a/examples/demo-rollup/Cargo.toml +++ b/examples/demo-rollup/Cargo.toml @@ -65,7 +65,6 @@ ethers-signers = { workspace = true } ethers = { workspace = true } revm = { workspace = true } -sov-demo-rollup = { path = ".", features = ["experimental"] } [features] default = [] diff --git a/examples/demo-rollup/benches/rng_xfers.rs b/examples/demo-rollup/benches/rng_xfers.rs index 39ae23cf9..72c3e4c4b 100644 --- a/examples/demo-rollup/benches/rng_xfers.rs +++ b/examples/demo-rollup/benches/rng_xfers.rs @@ -8,7 +8,7 @@ use sov_modules_api::default_context::DefaultContext; use sov_modules_api::default_signature::private_key::DefaultPrivateKey; use sov_modules_api::transaction::Transaction; use sov_modules_api::{Address, AddressBech32, EncodeCall, PrivateKey, PublicKey, Spec}; -use sov_rollup_interface::da::DaSpec; +use sov_rollup_interface::da::{DaSpec, DaVerifier}; use sov_rollup_interface::mocks::{ MockAddress, MockBlob, MockBlock, MockBlockHeader, MockHash, MockValidityCond, }; @@ -109,6 +109,7 @@ impl DaSpec for RngDaSpec { #[async_trait] impl DaService for RngDaService { type Spec = RngDaSpec; + type Verifier = RngDaVerifier; type FilteredBlock = MockBlock; type Error = anyhow::Error; @@ -174,3 +175,24 @@ impl DaService for RngDaService { unimplemented!() } } + +pub struct RngDaVerifier; +impl DaVerifier for RngDaVerifier { + type Spec = RngDaSpec; + + type Error = anyhow::Error; + + fn new(_params: ::ChainParams) -> Self { + Self + } + + fn verify_relevant_tx_list( + &self, + _block_header: &::BlockHeader, + _txs: &[::BlobTransaction], + _inclusion_proof: ::InclusionMultiProof, + _completeness_proof: ::CompletenessProof, + ) -> Result<::ValidityCondition, Self::Error> { + Ok(MockValidityCond { is_valid: true }) + } +} diff --git a/examples/demo-rollup/src/main.rs b/examples/demo-rollup/src/main.rs index 44d33497f..cfccceff3 100644 --- a/examples/demo-rollup/src/main.rs +++ b/examples/demo-rollup/src/main.rs @@ -2,6 +2,7 @@ use std::str::FromStr; use clap::Parser; use sov_demo_rollup::{new_rollup_with_celestia_da, new_rollup_with_mock_da}; +use sov_risc0_adapter::host::Risc0Host; use tracing_subscriber::prelude::*; use tracing_subscriber::{fmt, EnvFilter}; @@ -37,11 +38,12 @@ async fn main() -> Result<(), anyhow::Error> { match args.da_layer.as_str() { "mock" => { - let rollup = new_rollup_with_mock_da(rollup_config_path)?; + let rollup = new_rollup_with_mock_da::>(rollup_config_path, None)?; rollup.run().await } "celestia" => { - let rollup = new_rollup_with_celestia_da(rollup_config_path).await?; + let rollup = + new_rollup_with_celestia_da::>(rollup_config_path, None).await?; rollup.run().await } da => panic!("DA Layer not supported: {}", da), diff --git a/examples/demo-rollup/src/rollup.rs b/examples/demo-rollup/src/rollup.rs index 23595eb15..1fdfb5743 100644 --- a/examples/demo-rollup/src/rollup.rs +++ b/examples/demo-rollup/src/rollup.rs @@ -5,21 +5,24 @@ use anyhow::Context; use const_rollup_config::SEQUENCER_DA_ADDRESS; #[cfg(feature = "experimental")] use demo_stf::app::DefaultPrivateKey; -use demo_stf::app::{App, DefaultContext}; -use demo_stf::runtime::{get_rpc_methods, GenesisConfig}; +use demo_stf::app::{create_zk_app_template, App, DefaultContext}; +use demo_stf::runtime::{get_rpc_methods, GenesisConfig, Runtime}; use sov_celestia_adapter::verifier::address::CelestiaAddress; -use sov_celestia_adapter::verifier::RollupParams; +use sov_celestia_adapter::verifier::{CelestiaVerifier, RollupParams}; use sov_celestia_adapter::CelestiaService; #[cfg(feature = "experimental")] use sov_cli::wallet_state::PrivateKeyAndAddress; use sov_db::ledger_db::LedgerDB; #[cfg(feature = "experimental")] use sov_ethereum::experimental::EthRpcConfig; -use sov_risc0_adapter::host::Risc0Verifier; +use sov_modules_api::default_context::ZkDefaultContext; +use sov_modules_stf_template::AppTemplate; +use sov_rollup_interface::da::DaVerifier; use sov_rollup_interface::mocks::{MockAddress, MockDaConfig, MockDaService}; use sov_rollup_interface::services::da::DaService; -use sov_rollup_interface::zk::Zkvm; +use sov_rollup_interface::zk::ZkvmHost; use sov_state::storage::Storage; +use sov_stf_runner::verifier::StateTransitionVerifier; use sov_stf_runner::{from_toml_path, RollupConfig, RunnerConfig, StateTransitionRunner}; use tokio::sync::oneshot; use tracing::debug; @@ -33,7 +36,7 @@ use crate::{get_genesis_config, initialize_ledger, ROLLUP_NAMESPACE}; const TX_SIGNER_PRIV_KEY_PATH: &str = "../test-data/keys/tx_signer_private_key.json"; /// Dependencies needed to run the rollup. -pub struct Rollup { +pub struct Rollup { /// Implementation of the STF. pub app: App, /// Data availability service. @@ -47,12 +50,27 @@ pub struct Rollup { #[cfg(feature = "experimental")] /// Configuration for the Ethereum RPC. pub eth_rpc_config: EthRpcConfig, + /// Verifier for the rollup. + pub verifier: Option<(Vm, AppVerifier)>, } +/// A verifier for the demo rollup +pub type AppVerifier = StateTransitionVerifier< + AppTemplate< + ZkDefaultContext, + ::Spec, + Zk, + Runtime::Spec>, + >, + DA, + Zk, +>; + /// Creates celestia based rollup. -pub async fn new_rollup_with_celestia_da( +pub async fn new_rollup_with_celestia_da( rollup_config_path: &str, -) -> Result, anyhow::Error> { + prover: Option, +) -> Result, anyhow::Error> { debug!( "Starting demo celestia rollup with config {}", rollup_config_path @@ -73,6 +91,17 @@ pub async fn new_rollup_with_celestia_da( let app = App::new(rollup_config.storage); let sequencer_da_address = CelestiaAddress::from_str(SEQUENCER_DA_ADDRESS)?; let genesis_config = get_genesis_config(sequencer_da_address); + let verifier = prover.map(|p| { + ( + p, + AppVerifier::new( + create_zk_app_template([0u8; 32]), + CelestiaVerifier { + rollup_namespace: ROLLUP_NAMESPACE, + }, + ), + ) + }); Ok(Rollup { app, @@ -85,25 +114,28 @@ pub async fn new_rollup_with_celestia_da( min_blob_size: Some(1), tx_signer_priv_key: read_tx_signer_priv_key()?, }, + verifier, }) } /// Creates MockDa based rollup. -pub fn new_rollup_with_mock_da( +pub fn new_rollup_with_mock_da( rollup_config_path: &str, -) -> Result, anyhow::Error> { + prover: Option, +) -> Result, anyhow::Error> { debug!("Starting mock rollup with config {}", rollup_config_path); let rollup_config: RollupConfig = from_toml_path(rollup_config_path).context("Failed to read rollup configuration")?; - new_rollup_with_mock_da_from_config(rollup_config) + new_rollup_with_mock_da_from_config(rollup_config, prover) } /// Creates MockDa based rollup. -pub fn new_rollup_with_mock_da_from_config( +pub fn new_rollup_with_mock_da_from_config( rollup_config: RollupConfig, -) -> Result, anyhow::Error> { + prover: Option, +) -> Result, anyhow::Error> { let ledger_db = initialize_ledger(&rollup_config.storage.path); let sequencer_da_address = MockAddress::from([0u8; 32]); let da_service = MockDaService::new(sequencer_da_address); @@ -111,6 +143,12 @@ pub fn new_rollup_with_mock_da_from_config( let app = App::new(rollup_config.storage); let genesis_config = get_genesis_config(sequencer_da_address); + let verifier = prover.map(|p| { + ( + p, + AppVerifier::new(create_zk_app_template([0u8; 32]), Default::default()), + ) + }); Ok(Rollup { app, da_service, @@ -122,6 +160,8 @@ pub fn new_rollup_with_mock_da_from_config( min_blob_size: Some(1), tx_signer_priv_key: read_tx_signer_priv_key()?, }, + // TODO: add verifier + verifier, }) } @@ -137,7 +177,7 @@ pub fn read_tx_signer_priv_key() -> Result { Ok(key_and_address.private_key) } -impl + Clone> Rollup { +impl + Clone> Rollup { /// Runs the rollup. pub async fn run(self) -> Result<(), anyhow::Error> { self.run_and_report_rpc_port(None).await @@ -168,6 +208,7 @@ impl + Clone> Rollup { self.app.stf, storage.is_empty(), self.genesis_config, + self.verifier, )?; runner.start_rpc_server(methods, channel).await; diff --git a/examples/demo-rollup/tests/all_tests.rs b/examples/demo-rollup/tests/all_tests.rs index ab4829fa8..fb5916cf5 100644 --- a/examples/demo-rollup/tests/all_tests.rs +++ b/examples/demo-rollup/tests/all_tests.rs @@ -1,3 +1,6 @@ +// For now, exclude the evm from the bank tests +#[cfg(not(feature = "experimental"))] mod bank; +#[cfg(feature = "experimental")] mod evm; mod test_helpers; diff --git a/examples/demo-rollup/tests/bank/mod.rs b/examples/demo-rollup/tests/bank/mod.rs index c2c5cb42a..a60fed7f5 100644 --- a/examples/demo-rollup/tests/bank/mod.rs +++ b/examples/demo-rollup/tests/bank/mod.rs @@ -8,6 +8,7 @@ use jsonrpsee::rpc_params; use sov_modules_api::default_context::DefaultContext; use sov_modules_api::transaction::Transaction; use sov_modules_api::{PrivateKey, Spec}; +use sov_risc0_adapter::host::Risc0Host; use sov_rollup_interface::mocks::MockDaSpec; use sov_sequencer::utils::SimpleClient; @@ -67,14 +68,22 @@ async fn send_test_create_token_tx(rpc_address: SocketAddr) -> Result<(), anyhow async fn bank_tx_tests() -> Result<(), anyhow::Error> { let (port_tx, port_rx) = tokio::sync::oneshot::channel(); + // Use a dummy `elf` file, since the prover doesn't currently use it in native execution + let prover = Risc0Host::new(&[]); + let rollup_task = tokio::spawn(async { - start_rollup(port_tx).await; + start_rollup(port_tx, Some(prover)).await; }); // Wait for rollup task to start: let port = port_rx.await.unwrap(); - send_test_create_token_tx(port).await?; - rollup_task.abort(); + // If the rollup throws an error, stop trying to send the transaction and return it + tokio::select! { + err = rollup_task => { + err?; + }, + res = send_test_create_token_tx(port) =>{res?}, + }; Ok(()) } diff --git a/examples/demo-rollup/tests/evm/mod.rs b/examples/demo-rollup/tests/evm/mod.rs index b4c99fc5b..825538651 100644 --- a/examples/demo-rollup/tests/evm/mod.rs +++ b/examples/demo-rollup/tests/evm/mod.rs @@ -13,6 +13,7 @@ use jsonrpsee::core::client::ClientT; use jsonrpsee::http_client::{HttpClient, HttpClientBuilder}; use jsonrpsee::rpc_params; use sov_evm::smart_contracts::SimpleStorageContract; +use sov_risc0_adapter::host::Risc0Host; use super::test_helpers::start_rollup; @@ -195,7 +196,8 @@ async fn evm_tx_tests() -> Result<(), anyhow::Error> { let (port_tx, port_rx) = tokio::sync::oneshot::channel(); let rollup_task = tokio::spawn(async { - start_rollup(port_tx).await; + // Don't provide a prover since the EVM is not currently provable + start_rollup::>(port_tx, None).await; }); // Wait for rollup task to start: diff --git a/examples/demo-rollup/tests/test_helpers.rs b/examples/demo-rollup/tests/test_helpers.rs index 121363fef..d340efd77 100644 --- a/examples/demo-rollup/tests/test_helpers.rs +++ b/examples/demo-rollup/tests/test_helpers.rs @@ -1,12 +1,15 @@ use std::net::SocketAddr; use sov_demo_rollup::new_rollup_with_mock_da_from_config; -#[cfg(feature = "experimental")] use sov_rollup_interface::mocks::MockDaConfig; +use sov_rollup_interface::zk::ZkvmHost; use sov_stf_runner::{RollupConfig, RpcConfig, RunnerConfig, StorageConfig}; use tokio::sync::oneshot; -pub async fn start_rollup(rpc_reporting_channel: oneshot::Sender) { +pub async fn start_rollup( + rpc_reporting_channel: oneshot::Sender, + prover: Option, +) { let temp_dir = tempfile::tempdir().unwrap(); let temp_path = temp_dir.path(); @@ -24,7 +27,7 @@ pub async fn start_rollup(rpc_reporting_channel: oneshot::Sender) { da: MockDaConfig {}, }; let rollup = - new_rollup_with_mock_da_from_config(rollup_config).expect("Rollup config is valid"); + new_rollup_with_mock_da_from_config(rollup_config, prover).expect("Rollup config is valid"); rollup .run_and_report_rpc_port(Some(rpc_reporting_channel)) .await diff --git a/full-node/sov-stf-runner/src/runner.rs b/full-node/sov-stf-runner/src/runner.rs index 178ed5c6c..01927e4b8 100644 --- a/full-node/sov-stf-runner/src/runner.rs +++ b/full-node/sov-stf-runner/src/runner.rs @@ -6,22 +6,24 @@ use sov_modules_api::SlotData; use sov_rollup_interface::da::{BlobReaderTrait, DaSpec}; use sov_rollup_interface::services::da::DaService; use sov_rollup_interface::stf::StateTransitionFunction; -use sov_rollup_interface::zk::Zkvm; +use sov_rollup_interface::zk::ZkvmHost; use tokio::sync::oneshot; use tracing::{debug, info}; -use crate::RunnerConfig; +use crate::verifier::StateTransitionVerifier; +use crate::{RunnerConfig, StateTransitionData}; type StateRoot = >::StateRoot; type InitialState = >::InitialState; /// Combines `DaService` with `StateTransitionFunction` and "runs" the rollup. -pub struct StateTransitionRunner +pub struct StateTransitionRunner where Da: DaService, - Vm: Zkvm, + Vm: ZkvmHost, ST: StateTransitionFunction::ValidityCondition>, + V: StateTransitionFunction, { start_height: u64, da_service: Da, @@ -29,13 +31,23 @@ where ledger_db: LedgerDB, state_root: StateRoot, listen_address: SocketAddr, + verifier: Option<(Vm, StateTransitionVerifier)>, } -impl StateTransitionRunner +impl StateTransitionRunner where Da: DaService + Clone + Send + Sync + 'static, - Vm: Zkvm, - ST: StateTransitionFunction::ValidityCondition>, + Vm: ZkvmHost, + V: StateTransitionFunction, + ST: StateTransitionFunction< + Vm, + Da::Spec, + StateRoot = Root, + Condition = ::ValidityCondition, + Witness = Witness, + >, + Witness: Default, + Root: Clone, { /// Creates a new `StateTransitionRunner` runner. pub fn new( @@ -45,6 +57,7 @@ where mut app: ST, should_init_chain: bool, genesis_config: InitialState, + verifier: Option<(Vm, StateTransitionVerifier)>, ) -> Result { let rpc_config = runner_config.rpc_config; @@ -75,6 +88,7 @@ where ledger_db, state_root: prev_state_root, listen_address, + verifier, }) } @@ -135,6 +149,29 @@ where for receipt in slot_result.batch_receipts { data_to_commit.add_batch(receipt); } + if let Some((host, verifier)) = self.verifier.as_mut() { + let (inclusion_proof, completeness_proof) = self + .da_service + .get_extraction_proof(&filtered_block, &blobs) + .await; + + let transition_data: StateTransitionData = + StateTransitionData { + pre_state_root: self.state_root.clone(), + da_block_header: filtered_block.header().clone(), + inclusion_proof, + completeness_proof, + blobs, + state_transition_witness: slot_result.witness, + }; + host.add_hint(transition_data); + + verifier + .run_block(host.simulate_with_hints()) + .map_err(|e| { + anyhow::anyhow!("Guest execution must succeed but failed with {:?}", e) + })?; + } let next_state_root = slot_result.state_root; self.ledger_db.commit_slot(data_to_commit)?; diff --git a/rollup-interface/src/node/services/da.rs b/rollup-interface/src/node/services/da.rs index 267d1411f..1b530c182 100644 --- a/rollup-interface/src/node/services/da.rs +++ b/rollup-interface/src/node/services/da.rs @@ -5,7 +5,7 @@ use async_trait::async_trait; use serde::de::DeserializeOwned; use serde::Serialize; -use crate::da::{BlockHeaderTrait, DaSpec}; +use crate::da::{BlockHeaderTrait, DaSpec, DaVerifier}; use crate::zk::ValidityCondition; /// A DaService is the local side of an RPC connection talking to a node of the DA layer @@ -18,6 +18,9 @@ pub trait DaService: Send + Sync + 'static { /// A handle to the types used by the DA layer. type Spec: DaSpec; + /// The verifier for this DA layer. + type Verifier: DaVerifier; + /// A DA layer block, possibly excluding some irrelevant information. type FilteredBlock: SlotData< BlockHeader = ::BlockHeader, diff --git a/rollup-interface/src/state_machine/mocks/da.rs b/rollup-interface/src/state_machine/mocks/da.rs index a37041cf6..09569085f 100644 --- a/rollup-interface/src/state_machine/mocks/da.rs +++ b/rollup-interface/src/state_machine/mocks/da.rs @@ -6,7 +6,9 @@ use borsh::{BorshDeserialize, BorshSerialize}; use bytes::Bytes; use serde::{Deserialize, Serialize}; -use crate::da::{BlobReaderTrait, BlockHashTrait, BlockHeaderTrait, CountedBufReader, DaSpec}; +use crate::da::{ + BlobReaderTrait, BlockHashTrait, BlockHeaderTrait, CountedBufReader, DaSpec, DaVerifier, +}; use crate::mocks::MockValidityCond; use crate::services::da::{DaService, SlotData}; use crate::{BasicAddress, RollupAddress}; @@ -281,6 +283,7 @@ impl MockDaService { #[async_trait] impl DaService for MockDaService { + type Verifier = MockDaVerifier; type Spec = MockDaSpec; type FilteredBlock = MockBlock; type Error = anyhow::Error; @@ -317,7 +320,7 @@ impl DaService for MockDaService { ::InclusionMultiProof, ::CompletenessProof, ) { - todo!() + ([0u8; 32], ()) } async fn send_transaction(&self, blob: &[u8]) -> Result<(), Self::Error> { @@ -329,3 +332,27 @@ impl DaService for MockDaService { /// The configuration for mock da #[derive(Debug, Clone, PartialEq, serde::Deserialize, serde::Serialize)] pub struct MockDaConfig {} + +#[derive(Clone, Default)] +/// DaVerifier used in tests. +pub struct MockDaVerifier {} + +impl DaVerifier for MockDaVerifier { + type Spec = MockDaSpec; + + type Error = anyhow::Error; + + fn new(_params: ::ChainParams) -> Self { + Self {} + } + + fn verify_relevant_tx_list( + &self, + _block_header: &::BlockHeader, + _txs: &[::BlobTransaction], + _inclusion_proof: ::InclusionMultiProof, + _completeness_proof: ::CompletenessProof, + ) -> Result<::ValidityCondition, Self::Error> { + Ok(MockValidityCond { is_valid: true }) + } +} diff --git a/rollup-interface/src/state_machine/mocks/mod.rs b/rollup-interface/src/state_machine/mocks/mod.rs index 8f07dd832..232a5626f 100644 --- a/rollup-interface/src/state_machine/mocks/mod.rs +++ b/rollup-interface/src/state_machine/mocks/mod.rs @@ -6,7 +6,7 @@ mod validity_condition; mod zk_vm; pub use da::{ MockAddress, MockBlob, MockBlock, MockBlockHeader, MockDaConfig, MockDaService, MockDaSpec, - MockHash, + MockDaVerifier, MockHash, }; pub use validity_condition::{MockValidityCond, MockValidityCondChecker}; pub use zk_vm::{MockCodeCommitment, MockProof, MockZkvm}; diff --git a/rollup-interface/src/state_machine/zk/mod.rs b/rollup-interface/src/state_machine/zk/mod.rs index 41483dba2..1591ba2f4 100644 --- a/rollup-interface/src/state_machine/zk/mod.rs +++ b/rollup-interface/src/state_machine/zk/mod.rs @@ -18,8 +18,13 @@ use crate::RollupAddress; /// A trait implemented by the prover ("host") of a zkVM program. pub trait ZkvmHost: Zkvm { + /// The associated guest type + type Guest: ZkvmGuest; /// Give the guest a piece of advice non-deterministically - fn write_to_guest(&self, item: T); + fn add_hint(&self, item: T); + + /// Simulate running the guest using the provided hints + fn simulate_with_hints(&mut self) -> Self::Guest; } /// A Zk proof system capable of proving and verifying arbitrary Rust code @@ -51,6 +56,15 @@ pub trait Zkvm { ) -> Result, Self::Error>; } +// /// A trait which is implemented by the proof system itself. +// #[cfg(feature = "native")] +// pub trait ProofSystem { +// /// The host type which is used by this proof system +// type Host: ZkvmHost; +// /// The guest type +// type Guest: ZkvmGuest; +// } + /// A trait which is accessible from within a zkVM program. pub trait ZkvmGuest: Zkvm { /// Obtain "advice" non-deterministically from the host From 27f5cd230f310d1a81d00e3dceb542aad04d896f Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Tue, 12 Sep 2023 08:00:23 -0500 Subject: [PATCH 16/21] Tests pass --- adapters/risc0/src/guest.rs | 11 +++++++++-- examples/demo-rollup/src/rollup.rs | 4 ++-- examples/demo-stf/src/app.rs | 3 +-- .../examples/sov-value-setter/src/tests.rs | 4 ++-- .../src/nested_modules/tests.rs | 2 +- .../module-template/tests/value_setter.rs | 2 +- module-system/sov-state/src/prover_storage.rs | 7 +++++-- module-system/sov-state/src/zk_storage.rs | 16 +++++++--------- module-system/sov-state/tests/state_tests.rs | 4 +--- 9 files changed, 29 insertions(+), 24 deletions(-) diff --git a/adapters/risc0/src/guest.rs b/adapters/risc0/src/guest.rs index 335bd3022..817ddedfc 100644 --- a/adapters/risc0/src/guest.rs +++ b/adapters/risc0/src/guest.rs @@ -69,6 +69,8 @@ impl WordRead for Hints { pub struct Risc0Guest { #[cfg(not(target_os = "zkvm"))] hints: std::sync::Mutex, + #[cfg(not(target_os = "zkvm"))] + commits: std::sync::Mutex>, } impl Risc0Guest { @@ -76,6 +78,8 @@ impl Risc0Guest { Self { #[cfg(not(target_os = "zkvm"))] hints: std::sync::Mutex::new(Hints::new()), + #[cfg(not(target_os = "zkvm"))] + commits: Default::default(), } } @@ -83,6 +87,7 @@ impl Risc0Guest { pub fn with_hints(hints: Vec) -> Self { Self { hints: std::sync::Mutex::new(Hints::with_hints(hints)), + commits: Default::default(), } } } @@ -95,8 +100,10 @@ impl ZkvmGuest for Risc0Guest { T::deserialize(&mut Deserializer::new(&mut hints)).unwrap() } - fn commit(&self, _item: &T) { - todo!() + fn commit(&self, item: &T) { + self.commits.lock().unwrap().extend_from_slice( + &risc0_zkvm::serde::to_vec(item).expect("Serialization to vec is infallible"), + ); } } diff --git a/examples/demo-rollup/src/rollup.rs b/examples/demo-rollup/src/rollup.rs index 1fdfb5743..cfa356c4d 100644 --- a/examples/demo-rollup/src/rollup.rs +++ b/examples/demo-rollup/src/rollup.rs @@ -95,7 +95,7 @@ pub async fn new_rollup_with_celestia_da( ( p, AppVerifier::new( - create_zk_app_template([0u8; 32]), + create_zk_app_template(), CelestiaVerifier { rollup_namespace: ROLLUP_NAMESPACE, }, @@ -146,7 +146,7 @@ pub fn new_rollup_with_mock_da_from_config( let verifier = prover.map(|p| { ( p, - AppVerifier::new(create_zk_app_template([0u8; 32]), Default::default()), + AppVerifier::new(create_zk_app_template(), Default::default()), ) }); Ok(Rollup { diff --git a/examples/demo-stf/src/app.rs b/examples/demo-stf/src/app.rs index c326f2a9f..95a5896e7 100644 --- a/examples/demo-stf/src/app.rs +++ b/examples/demo-stf/src/app.rs @@ -50,8 +50,7 @@ impl App { } pub fn create_zk_app_template( - runtime_config: [u8; 32], ) -> AppTemplate> { - let storage = ZkStorage::with_config(runtime_config).expect("Failed to open zk storage"); + let storage = ZkStorage::new(); AppTemplate::new(storage, Runtime::default()) } diff --git a/module-system/module-implementations/examples/sov-value-setter/src/tests.rs b/module-system/module-implementations/examples/sov-value-setter/src/tests.rs index 5c3747479..03cbafcfb 100644 --- a/module-system/module-implementations/examples/sov-value-setter/src/tests.rs +++ b/module-system/module-implementations/examples/sov-value-setter/src/tests.rs @@ -24,7 +24,7 @@ fn test_value_setter() { { let config = ValueSetterConfig { admin }; let zk_context = ZkDefaultContext::new(admin); - let mut zk_working_set = WorkingSet::with_witness(ZkStorage::new([0u8; 32]), witness); + let mut zk_working_set = WorkingSet::with_witness(ZkStorage::new(), witness); test_value_setter_helper(zk_context, &config, &mut zk_working_set); } } @@ -85,7 +85,7 @@ fn test_err_on_sender_is_not_admin() { let config = ValueSetterConfig { admin: sender_not_admin, }; - let zk_backing_store = ZkStorage::new([0u8; 32]); + let zk_backing_store = ZkStorage::new(); let zk_context = ZkDefaultContext::new(sender); let zk_working_set = &mut WorkingSet::with_witness(zk_backing_store, witness); test_err_on_sender_is_not_admin_helper(zk_context, &config, zk_working_set); diff --git a/module-system/module-implementations/integration-tests/src/nested_modules/tests.rs b/module-system/module-implementations/integration-tests/src/nested_modules/tests.rs index aac0cfd7a..294afb047 100644 --- a/module-system/module-implementations/integration-tests/src/nested_modules/tests.rs +++ b/module-system/module-implementations/integration-tests/src/nested_modules/tests.rs @@ -33,7 +33,7 @@ fn nested_module_call_test() { // Test the `zk` execution. { - let zk_storage = ZkStorage::new([0u8; 32]); + let zk_storage = ZkStorage::new(); let working_set = &mut WorkingSet::with_witness(zk_storage, witness); execute_module_logic::(working_set); test_state_update::(working_set); diff --git a/module-system/module-implementations/module-template/tests/value_setter.rs b/module-system/module-implementations/module-template/tests/value_setter.rs index b8ad67bb3..e000747ba 100644 --- a/module-system/module-implementations/module-template/tests/value_setter.rs +++ b/module-system/module-implementations/module-template/tests/value_setter.rs @@ -28,7 +28,7 @@ fn test_value_setter() { { let config = ExampleModuleConfig {}; let zk_context = ZkDefaultContext::new(admin); - let mut zk_working_set = WorkingSet::with_witness(ZkStorage::new([0u8; 32]), witness); + let mut zk_working_set = WorkingSet::with_witness(ZkStorage::new(), witness); test_value_setter_helper(zk_context, &config, &mut zk_working_set); } } diff --git a/module-system/sov-state/src/prover_storage.rs b/module-system/sov-state/src/prover_storage.rs index 70061749c..bed8157cc 100644 --- a/module-system/sov-state/src/prover_storage.rs +++ b/module-system/sov-state/src/prover_storage.rs @@ -96,8 +96,6 @@ impl Storage for ProverStorage { witness: &Self::Witness, ) -> Result<([u8; 32], Self::StateUpdate), anyhow::Error> { let latest_version = self.db.get_next_version() - 1; - witness.add_hint(latest_version); - let read_logger = TreeReadLogger::with_db_and_witness(self.db.clone(), witness); let untracked_jmt = JellyfishMerkleTree::<_, S::Hasher>::new(&self.db); @@ -116,6 +114,11 @@ impl Storage for ProverStorage { .write_node_batch(&tree_update.node_batch) .expect("db write must succeed"); } + let prev_root = untracked_jmt + .get_root_hash(latest_version) + .expect("Previous root hash was just populated"); + witness.add_hint(prev_root.0); + witness.add_hint(latest_version); // For each value that's been read from the tree, read it from the logged JMT to populate hints for (key, read_value) in state_accesses.ordered_reads { diff --git a/module-system/sov-state/src/zk_storage.rs b/module-system/sov-state/src/zk_storage.rs index d8e6ce64b..63d847370 100644 --- a/module-system/sov-state/src/zk_storage.rs +++ b/module-system/sov-state/src/zk_storage.rs @@ -15,23 +15,20 @@ use crate::{MerkleProofSpec, Storage}; extern crate risc0_zkvm; pub struct ZkStorage { - prev_state_root: [u8; 32], _phantom_hasher: PhantomData, } impl Clone for ZkStorage { fn clone(&self) -> Self { Self { - prev_state_root: self.prev_state_root, _phantom_hasher: Default::default(), } } } impl ZkStorage { - pub fn new(prev_state_root: [u8; 32]) -> Self { + pub fn new() -> Self { Self { - prev_state_root, _phantom_hasher: Default::default(), } } @@ -39,12 +36,12 @@ impl ZkStorage { impl Storage for ZkStorage { type Witness = S::Witness; - type RuntimeConfig = [u8; 32]; + type RuntimeConfig = (); type Proof = jmt::proof::SparseMerkleProof; type StateUpdate = NodeBatch; - fn with_config(config: Self::RuntimeConfig) -> Result { - Ok(Self::new(config)) + fn with_config(_config: Self::RuntimeConfig) -> Result { + Ok(Self::new()) } fn get(&self, _key: &StorageKey, witness: &Self::Witness) -> Option { @@ -61,6 +58,7 @@ impl Storage for ZkStorage { state_accesses: OrderedReadsAndWrites, witness: &Self::Witness, ) -> Result<([u8; 32], Self::StateUpdate), anyhow::Error> { + let prev_state_root = witness.get_hint(); let latest_version: Version = witness.get_hint(); let reader = TreeWitnessReader::new(witness); @@ -71,11 +69,11 @@ impl Storage for ZkStorage { let proof: jmt::proof::SparseMerkleProof = witness.get_hint(); match read_value { Some(val) => proof.verify_existence( - jmt::RootHash(self.prev_state_root), + jmt::RootHash(prev_state_root), key_hash, val.value.as_ref(), )?, - None => proof.verify_nonexistence(jmt::RootHash(self.prev_state_root), key_hash)?, + None => proof.verify_nonexistence(jmt::RootHash(prev_state_root), key_hash)?, } } diff --git a/module-system/sov-state/tests/state_tests.rs b/module-system/sov-state/tests/state_tests.rs index d4692fd2f..63de3ef99 100644 --- a/module-system/sov-state/tests/state_tests.rs +++ b/module-system/sov-state/tests/state_tests.rs @@ -8,8 +8,6 @@ enum Operation { Finalize, } -const EMPTY_ROOT: [u8; 32] = *b"SPARSE_MERKLE_PLACEHOLDER_HASH__"; - impl Operation { fn execute(&self, working_set: WorkingSet) -> StateCheckpoint { match self { @@ -193,7 +191,7 @@ fn test_witness_roundtrip() { }; { - let storage = ZkStorage::::new(EMPTY_ROOT); + let storage = ZkStorage::::new(); let mut working_set = WorkingSet::with_witness(storage.clone(), witness); state_value.set(&11, &mut working_set); let _ = state_value.get(&mut working_set); From c5e323cd7ba044ea149dc61bece440d6a3e2dae2 Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Tue, 12 Sep 2023 08:07:15 -0500 Subject: [PATCH 17/21] lint --- adapters/risc0/src/guest.rs | 16 +++------------- examples/demo-rollup/src/rollup.rs | 1 + full-node/sov-stf-runner/src/runner.rs | 3 ++- module-system/sov-state/src/zk_storage.rs | 1 + 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/adapters/risc0/src/guest.rs b/adapters/risc0/src/guest.rs index 817ddedfc..44a304460 100644 --- a/adapters/risc0/src/guest.rs +++ b/adapters/risc0/src/guest.rs @@ -19,6 +19,7 @@ impl ZkvmGuest for Risc0Guest { } #[cfg(not(target_os = "zkvm"))] +#[derive(Default)] struct Hints { values: Vec, position: usize, @@ -26,13 +27,6 @@ struct Hints { #[cfg(not(target_os = "zkvm"))] impl Hints { - pub fn new() -> Self { - Hints { - values: Vec::new(), - position: 0, - } - } - pub fn with_hints(hints: Vec) -> Self { Hints { values: hints, @@ -66,6 +60,7 @@ impl WordRead for Hints { } } +#[derive(Default)] pub struct Risc0Guest { #[cfg(not(target_os = "zkvm"))] hints: std::sync::Mutex, @@ -75,12 +70,7 @@ pub struct Risc0Guest { impl Risc0Guest { pub fn new() -> Self { - Self { - #[cfg(not(target_os = "zkvm"))] - hints: std::sync::Mutex::new(Hints::new()), - #[cfg(not(target_os = "zkvm"))] - commits: Default::default(), - } + Self::default() } #[cfg(not(target_os = "zkvm"))] diff --git a/examples/demo-rollup/src/rollup.rs b/examples/demo-rollup/src/rollup.rs index cfa356c4d..4a7ee92dd 100644 --- a/examples/demo-rollup/src/rollup.rs +++ b/examples/demo-rollup/src/rollup.rs @@ -51,6 +51,7 @@ pub struct Rollup { /// Configuration for the Ethereum RPC. pub eth_rpc_config: EthRpcConfig, /// Verifier for the rollup. + #[allow(clippy::type_complexity)] pub verifier: Option<(Vm, AppVerifier)>, } diff --git a/full-node/sov-stf-runner/src/runner.rs b/full-node/sov-stf-runner/src/runner.rs index 01927e4b8..92eaba967 100644 --- a/full-node/sov-stf-runner/src/runner.rs +++ b/full-node/sov-stf-runner/src/runner.rs @@ -31,6 +31,7 @@ where ledger_db: LedgerDB, state_root: StateRoot, listen_address: SocketAddr, + #[allow(clippy::type_complexity)] verifier: Option<(Vm, StateTransitionVerifier)>, } @@ -56,7 +57,7 @@ where ledger_db: LedgerDB, mut app: ST, should_init_chain: bool, - genesis_config: InitialState, + #[allow(clippy::type_complexity)] genesis_config: InitialState, verifier: Option<(Vm, StateTransitionVerifier)>, ) -> Result { let rpc_config = runner_config.rpc_config; diff --git a/module-system/sov-state/src/zk_storage.rs b/module-system/sov-state/src/zk_storage.rs index 63d847370..abc0aeaa6 100644 --- a/module-system/sov-state/src/zk_storage.rs +++ b/module-system/sov-state/src/zk_storage.rs @@ -14,6 +14,7 @@ use crate::{MerkleProofSpec, Storage}; #[cfg(all(target_os = "zkvm", feature = "bench"))] extern crate risc0_zkvm; +#[derive(Default)] pub struct ZkStorage { _phantom_hasher: PhantomData, } From 65c88af7f38ac8bc1953c73a4599fcd805501560 Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Tue, 12 Sep 2023 08:16:38 -0500 Subject: [PATCH 18/21] lint --- full-node/sov-stf-runner/src/runner.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/full-node/sov-stf-runner/src/runner.rs b/full-node/sov-stf-runner/src/runner.rs index 2b0db3cb7..c722bd5e3 100644 --- a/full-node/sov-stf-runner/src/runner.rs +++ b/full-node/sov-stf-runner/src/runner.rs @@ -51,6 +51,7 @@ where Root: Clone, { /// Creates a new `StateTransitionRunner` runner. + #[allow(clippy::type_complexity)] pub fn new( runner_config: RunnerConfig, da_service: Da, @@ -58,10 +59,7 @@ where mut app: ST, should_init_chain: bool, genesis_config: InitialState, - #[allow(clippy::type_complexity)] verifier: Option<( - Vm, - StateTransitionVerifier, - )>, + verifier: Option<(Vm, StateTransitionVerifier)>, ) -> Result { let rpc_config = runner_config.rpc_config; From 67b53179ef4a9e1fa30e697a04a32d515ad0d3e4 Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Tue, 12 Sep 2023 09:53:38 -0500 Subject: [PATCH 19/21] fix tests/features --- examples/demo-stf/src/app.rs | 4 ++-- .../sov-modules-macros/tests/dispatch/derive_dispatch.rs | 2 +- .../sov-modules-macros/tests/dispatch/derive_genesis.rs | 2 +- module-system/sov-modules-macros/tests/rpc/derive_rpc.rs | 2 +- .../sov-modules-macros/tests/rpc/derive_rpc_with_where.rs | 2 +- .../tests/rpc/expose_rpc_associated_type_not_static.rs | 2 +- .../tests/rpc/expose_rpc_associated_types.rs | 2 +- .../tests/rpc/expose_rpc_associated_types_nested.rs | 2 +- .../tests/rpc/expose_rpc_first_generic_not_context.rs | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/demo-stf/src/app.rs b/examples/demo-stf/src/app.rs index 95a5896e7..b88f39c5f 100644 --- a/examples/demo-stf/src/app.rs +++ b/examples/demo-stf/src/app.rs @@ -10,8 +10,8 @@ pub use sov_modules_stf_template::Batch; use sov_rollup_interface::da::DaSpec; use sov_rollup_interface::zk::Zkvm; #[cfg(feature = "native")] -use sov_state::ProverStorage; -use sov_state::{Storage, ZkStorage}; +use sov_state::{ProverStorage, Storage}; +use sov_state::{ZkStorage}; #[cfg(feature = "native")] use sov_stf_runner::FiFoStrictBatchBuilder; #[cfg(feature = "native")] diff --git a/module-system/sov-modules-macros/tests/dispatch/derive_dispatch.rs b/module-system/sov-modules-macros/tests/dispatch/derive_dispatch.rs index 38952914d..77d94d268 100644 --- a/module-system/sov-modules-macros/tests/dispatch/derive_dispatch.rs +++ b/module-system/sov-modules-macros/tests/dispatch/derive_dispatch.rs @@ -24,7 +24,7 @@ fn main() { type RT = Runtime; let runtime = &mut RT::default(); - let storage = ZkStorage::new([1u8; 32]); + let storage = ZkStorage::new(); let mut working_set = &mut sov_state::WorkingSet::new(storage); let config = GenesisConfig::new((), (), ()); runtime.genesis(&config, working_set).unwrap(); diff --git a/module-system/sov-modules-macros/tests/dispatch/derive_genesis.rs b/module-system/sov-modules-macros/tests/dispatch/derive_genesis.rs index 580a564c9..809d9d2fd 100644 --- a/module-system/sov-modules-macros/tests/dispatch/derive_genesis.rs +++ b/module-system/sov-modules-macros/tests/dispatch/derive_genesis.rs @@ -22,7 +22,7 @@ where fn main() { type C = ZkDefaultContext; - let storage = ZkStorage::new([1u8; 32]); + let storage = ZkStorage::new(); let mut working_set = &mut sov_state::WorkingSet::new(storage); let runtime = &mut Runtime::::default(); let config = GenesisConfig::new((), (), ()); diff --git a/module-system/sov-modules-macros/tests/rpc/derive_rpc.rs b/module-system/sov-modules-macros/tests/rpc/derive_rpc.rs index 0177fc500..7e4a6c4e1 100644 --- a/module-system/sov-modules-macros/tests/rpc/derive_rpc.rs +++ b/module-system/sov-modules-macros/tests/rpc/derive_rpc.rs @@ -60,7 +60,7 @@ impl TestStructRpcImpl for RpcStorage { } fn main() { - let storage = ZkStorage::new([1u8; 32]); + let storage = ZkStorage::new(); let r: RpcStorage = RpcStorage { storage: storage.clone(), }; diff --git a/module-system/sov-modules-macros/tests/rpc/derive_rpc_with_where.rs b/module-system/sov-modules-macros/tests/rpc/derive_rpc_with_where.rs index 716d8f0e6..8e944f8be 100644 --- a/module-system/sov-modules-macros/tests/rpc/derive_rpc_with_where.rs +++ b/module-system/sov-modules-macros/tests/rpc/derive_rpc_with_where.rs @@ -73,7 +73,7 @@ impl TestStructRpcImpl for RpcStorage { } fn main() { - let storage = ZkStorage::new([1u8; 32]); + let storage = ZkStorage::new(); let r: RpcStorage = RpcStorage { storage: storage.clone(), }; diff --git a/module-system/sov-modules-macros/tests/rpc/expose_rpc_associated_type_not_static.rs b/module-system/sov-modules-macros/tests/rpc/expose_rpc_associated_type_not_static.rs index b71e8a18e..e92f7c0c3 100644 --- a/module-system/sov-modules-macros/tests/rpc/expose_rpc_associated_type_not_static.rs +++ b/module-system/sov-modules-macros/tests/rpc/expose_rpc_associated_type_not_static.rs @@ -111,7 +111,7 @@ impl TestSpec for ActualSpec { fn main() { type C = ZkDefaultContext; type RT = Runtime; - let storage = ZkStorage::new([1u8; 32]); + let storage = ZkStorage::new(); let working_set = &mut WorkingSet::new(storage); let runtime = &mut Runtime::::default(); let config = GenesisConfig::new(22); diff --git a/module-system/sov-modules-macros/tests/rpc/expose_rpc_associated_types.rs b/module-system/sov-modules-macros/tests/rpc/expose_rpc_associated_types.rs index 352553613..4316511c5 100644 --- a/module-system/sov-modules-macros/tests/rpc/expose_rpc_associated_types.rs +++ b/module-system/sov-modules-macros/tests/rpc/expose_rpc_associated_types.rs @@ -111,7 +111,7 @@ impl TestSpec for ActualSpec { fn main() { type C = ZkDefaultContext; type RT = Runtime; - let storage = ZkStorage::new([1u8; 32]); + let storage = ZkStorage::new(); let working_set = &mut WorkingSet::new(storage); let runtime = &mut Runtime::::default(); let config = GenesisConfig::new(22); diff --git a/module-system/sov-modules-macros/tests/rpc/expose_rpc_associated_types_nested.rs b/module-system/sov-modules-macros/tests/rpc/expose_rpc_associated_types_nested.rs index 87242a9ea..b056cd885 100644 --- a/module-system/sov-modules-macros/tests/rpc/expose_rpc_associated_types_nested.rs +++ b/module-system/sov-modules-macros/tests/rpc/expose_rpc_associated_types_nested.rs @@ -122,7 +122,7 @@ impl TestSpec for ActualSpec { fn main() { type C = ZkDefaultContext; type RT = Runtime; - let storage = ZkStorage::new([1u8; 32]); + let storage = ZkStorage::new(); let working_set = &mut WorkingSet::new(storage); let runtime = &mut Runtime::::default(); let config = GenesisConfig::new(22); diff --git a/module-system/sov-modules-macros/tests/rpc/expose_rpc_first_generic_not_context.rs b/module-system/sov-modules-macros/tests/rpc/expose_rpc_first_generic_not_context.rs index 70af8d1aa..71c1a9384 100644 --- a/module-system/sov-modules-macros/tests/rpc/expose_rpc_first_generic_not_context.rs +++ b/module-system/sov-modules-macros/tests/rpc/expose_rpc_first_generic_not_context.rs @@ -111,7 +111,7 @@ impl TestSpec for ActualSpec { fn main() { type C = ZkDefaultContext; type RT = Runtime; - let storage = ZkStorage::new([1u8; 32]); + let storage = ZkStorage::new(); let working_set = &mut WorkingSet::new(storage); let runtime = &mut Runtime::::default(); let config = GenesisConfig::new(22); From 888d42ccec0e0018b7ab4f1d0cd30102bb41ad64 Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Tue, 12 Sep 2023 09:57:40 -0500 Subject: [PATCH 20/21] fix prover --- adapters/risc0/src/guest.rs | 2 ++ examples/demo-prover/host/benches/prover_bench.rs | 12 ++++++------ examples/demo-prover/host/src/main.rs | 12 ++++++------ examples/demo-prover/methods/guest/src/bin/rollup.rs | 5 ++--- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/adapters/risc0/src/guest.rs b/adapters/risc0/src/guest.rs index 44a304460..2198c578f 100644 --- a/adapters/risc0/src/guest.rs +++ b/adapters/risc0/src/guest.rs @@ -1,7 +1,9 @@ +#[cfg(not(target_os = "zkvm"))] use std::ops::DerefMut; #[cfg(target_os = "zkvm")] use risc0_zkvm::guest::env; +#[cfg(not(target_os = "zkvm"))] use risc0_zkvm::serde::{Deserializer, WordRead}; use sov_rollup_interface::zk::{Zkvm, ZkvmGuest}; diff --git a/examples/demo-prover/host/benches/prover_bench.rs b/examples/demo-prover/host/benches/prover_bench.rs index d25ed1efb..ffb388d4a 100644 --- a/examples/demo-prover/host/benches/prover_bench.rs +++ b/examples/demo-prover/host/benches/prover_bench.rs @@ -201,7 +201,7 @@ async fn main() -> Result<(), anyhow::Error> { for height in 2..(bincoded_blocks.len() as u64) { num_blocks += 1; let mut host = Risc0Host::new(ROLLUP_ELF); - host.write_to_guest(prev_state_root); + host.add_hint(prev_state_root); println!( "Requesting data for height {} and prev_state_root 0x{}", height, @@ -209,14 +209,14 @@ async fn main() -> Result<(), anyhow::Error> { ); let filtered_block = &bincoded_blocks[height as usize]; let _header_hash = hex::encode(filtered_block.header.header.hash()); - host.write_to_guest(&filtered_block.header); + host.add_hint(&filtered_block.header); let (mut blob_txs, inclusion_proof, completeness_proof) = da_service .extract_relevant_txs_with_proof(&filtered_block) .await; - host.write_to_guest(&inclusion_proof); - host.write_to_guest(&completeness_proof); - host.write_to_guest(&blob_txs); + host.add_hint(&inclusion_proof); + host.add_hint(&completeness_proof); + host.add_hint(&blob_txs); if !blob_txs.is_empty() { num_blobs += blob_txs.len(); @@ -232,7 +232,7 @@ async fn main() -> Result<(), anyhow::Error> { } // println!("{:?}",result.batch_receipts); - host.write_to_guest(&result.witness); + host.add_hint(&result.witness); println!("Skipping prover at block {height} to capture cycle counts\n"); let _receipt = host diff --git a/examples/demo-prover/host/src/main.rs b/examples/demo-prover/host/src/main.rs index d2885e068..8ef7bb9fd 100644 --- a/examples/demo-prover/host/src/main.rs +++ b/examples/demo-prover/host/src/main.rs @@ -92,7 +92,7 @@ async fn main() -> Result<(), anyhow::Error> { // prev_state_root is the root after applying the block at height-1 // This is necessary since we're proving that the current state root for the current height is // result of applying the block against state with root prev_state_root - host.write_to_guest(prev_state_root); + host.add_hint(prev_state_root); info!( "Requesting data for height {} and prev_state_root 0x{}", height, @@ -100,7 +100,7 @@ async fn main() -> Result<(), anyhow::Error> { ); let filtered_block = da_service.get_finalized_at(height).await?; let header_hash = hex::encode(filtered_block.header.header.hash()); - host.write_to_guest(&filtered_block.header); + host.add_hint(&filtered_block.header); // When we get a block from DA, we also need to provide proofs of completeness and correctness // https://github.com/Sovereign-Labs/sovereign-sdk/blob/nightly/rollup-interface/specs/interfaces/da.md#type-inclusionmultiproof let (mut blobs, inclusion_proof, completeness_proof) = da_service @@ -115,8 +115,8 @@ async fn main() -> Result<(), anyhow::Error> { ); // The above proofs of correctness and completeness need to passed to the prover - host.write_to_guest(&inclusion_proof); - host.write_to_guest(&completeness_proof); + host.add_hint(&inclusion_proof); + host.add_hint(&completeness_proof); let result = app.stf.apply_slot( Default::default(), @@ -127,11 +127,11 @@ async fn main() -> Result<(), anyhow::Error> { // The extracted blobs need to be passed to the prover after execution. // (Without executing, the host couldn't prune any data that turned out to be irrelevant to the guest) - host.write_to_guest(&blobs); + host.add_hint(&blobs); // Witness contains the merkle paths to the state root so that the code inside the VM // can access state values (Witness can also contain other hints and proofs) - host.write_to_guest(&result.witness); + host.add_hint(&result.witness); // Run the actual prover to generate a receipt that can then be verified if !skip_prover { diff --git a/examples/demo-prover/methods/guest/src/bin/rollup.rs b/examples/demo-prover/methods/guest/src/bin/rollup.rs index c04036a09..b15351f3c 100644 --- a/examples/demo-prover/methods/guest/src/bin/rollup.rs +++ b/examples/demo-prover/methods/guest/src/bin/rollup.rs @@ -13,7 +13,6 @@ use sov_celestia_adapter::verifier::address::CelestiaAddress; use sov_celestia_adapter::verifier::{CelestiaSpec, CelestiaVerifier}; use sov_celestia_adapter::{BlobWithSender, CelestiaHeader}; use sov_risc0_adapter::guest::Risc0Guest; -use sov_rollup_interface::crypto::NoOpHasher; use sov_rollup_interface::da::{BlockHeaderTrait, DaSpec, DaVerifier}; use sov_rollup_interface::stf::StateTransitionFunction; use sov_rollup_interface::zk::{StateTransition, ZkvmGuest}; @@ -32,7 +31,7 @@ risc0_zkvm::guest::entry!(main); // 6. Output (Da hash, start_root, end_root, event_root) pub fn main() { env::write(&"Start guest\n"); - let guest = Risc0Guest; + let guest = Risc0Guest{}; #[cfg(feature = "bench")] let start_cycles = env::get_cycle_count(); @@ -59,7 +58,7 @@ pub fn main() { env::write(&"Relevant txs verified\n"); // Step 3: Apply blobs - let mut app = create_zk_app_template::(prev_state_root_hash); + let mut app = create_zk_app_template::(); let witness: ArrayWitness = guest.read_from_host(); env::write(&"Witness have been read\n"); From 59c510db08dd470259c7c629abd3d7d65a5754cf Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Tue, 12 Sep 2023 10:00:53 -0500 Subject: [PATCH 21/21] lint --- examples/demo-stf/src/app.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/demo-stf/src/app.rs b/examples/demo-stf/src/app.rs index b88f39c5f..27970c9ae 100644 --- a/examples/demo-stf/src/app.rs +++ b/examples/demo-stf/src/app.rs @@ -9,9 +9,9 @@ use sov_modules_stf_template::AppTemplate; pub use sov_modules_stf_template::Batch; use sov_rollup_interface::da::DaSpec; use sov_rollup_interface::zk::Zkvm; +use sov_state::ZkStorage; #[cfg(feature = "native")] use sov_state::{ProverStorage, Storage}; -use sov_state::{ZkStorage}; #[cfg(feature = "native")] use sov_stf_runner::FiFoStrictBatchBuilder; #[cfg(feature = "native")]