From 35379abfaad8b30d1dba99b59b26e900e5431dad Mon Sep 17 00:00:00 2001 From: Blazej Kolad Date: Fri, 20 Oct 2023 15:44:49 +0200 Subject: [PATCH] Update `sov-rollup-starter` with `RollupTemplate` (#1082) * fix * Update sov-rollup-starter with RollupTemplate * make create_native_storage fallible * change logging level * change logging level * cleanup * Fix lint --- Cargo.lock | 2 + examples/demo-rollup/src/celestia_rollup.rs | 5 +- examples/demo-rollup/src/main.rs | 10 +- examples/demo-rollup/src/mock_rollup.rs | 17 +- examples/demo-rollup/tests/bank/mod.rs | 46 ++--- .../sov-modules-rollup-template/src/lib.rs | 7 +- sov-rollup-starter/.gitignore | 1 + sov-rollup-starter/Cargo.toml | 2 + .../provers/risc0/guest-mock/Cargo.lock | 3 + .../provers/risc0/guest-mock/Cargo.toml | 7 +- .../risc0/guest-mock/src/bin/mock_da.rs | 21 ++- sov-rollup-starter/rollup_config.toml | 2 +- sov-rollup-starter/src/bin/node.rs | 85 +++++---- sov-rollup-starter/src/da.rs | 11 -- sov-rollup-starter/src/lib.rs | 3 +- sov-rollup-starter/src/register_rpc.rs | 22 --- sov-rollup-starter/src/register_sequencer.rs | 37 ++++ sov-rollup-starter/src/rollup.rs | 163 ++++++++---------- sov-rollup-starter/stf/src/builder.rs | 48 ------ sov-rollup-starter/stf/src/lib.rs | 18 +- sov-rollup-starter/tests/bank/mod.rs | 51 +++--- sov-rollup-starter/tests/test_helpers.rs | 36 ++-- 22 files changed, 288 insertions(+), 309 deletions(-) create mode 100644 sov-rollup-starter/.gitignore delete mode 100644 sov-rollup-starter/src/da.rs delete mode 100644 sov-rollup-starter/src/register_rpc.rs create mode 100644 sov-rollup-starter/src/register_sequencer.rs delete mode 100644 sov-rollup-starter/stf/src/builder.rs diff --git a/Cargo.lock b/Cargo.lock index a24fcaf74..01a7a9d12 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8839,6 +8839,7 @@ name = "sov-rollup-starter" version = "0.2.0" dependencies = [ "anyhow", + "async-trait", "borsh", "clap 4.4.6", "jsonrpsee 0.20.2", @@ -8850,6 +8851,7 @@ dependencies = [ "sov-db", "sov-ledger-rpc", "sov-modules-api", + "sov-modules-rollup-template", "sov-modules-stf-template", "sov-risc0-adapter", "sov-rollup-interface", diff --git a/examples/demo-rollup/src/celestia_rollup.rs b/examples/demo-rollup/src/celestia_rollup.rs index 2352f1a0b..557dc4c2a 100644 --- a/examples/demo-rollup/src/celestia_rollup.rs +++ b/examples/demo-rollup/src/celestia_rollup.rs @@ -42,6 +42,7 @@ impl RollupTemplate for CelestiaDemoRollup { fn create_genesis_config( &self, genesis_paths: &Self::GenesisPaths, + _rollup_config: &RollupConfig, ) -> , - ) -> ::Storage { + ) -> Result<::Storage, anyhow::Error> { let storage_config = StorageConfig { path: rollup_config.storage.path.clone(), }; - ProverStorage::with_config(storage_config).expect("Failed to open prover storage") + ProverStorage::with_config(storage_config) } fn create_rpc_methods( diff --git a/examples/demo-rollup/src/main.rs b/examples/demo-rollup/src/main.rs index 25268c806..e0b76c9d8 100644 --- a/examples/demo-rollup/src/main.rs +++ b/examples/demo-rollup/src/main.rs @@ -6,9 +6,7 @@ use clap::Parser; use demo_stf::genesis_config::GenesisPaths; use sov_demo_rollup::{CelestiaDemoRollup, MockDemoRollup}; use sov_modules_rollup_template::{Rollup, RollupProverConfig, RollupTemplate}; -use sov_risc0_adapter::host::Risc0Host; use sov_rollup_interface::mocks::MockDaConfig; -use sov_rollup_interface::zk::ZkvmHost; use sov_stf_runner::{from_toml_path, RollupConfig}; use tracing::log::debug; use tracing_subscriber::prelude::*; @@ -46,7 +44,7 @@ async fn main() -> Result<(), anyhow::Error> { match args.da_layer.as_str() { "mock" => { - let rollup = new_rollup_with_mock_da::>( + let rollup = new_rollup_with_mock_da( &GenesisPaths::from_dir("../test-data/genesis/integration-tests"), rollup_config_path, Some(RollupProverConfig::Execute), @@ -55,7 +53,7 @@ async fn main() -> Result<(), anyhow::Error> { rollup.run().await } "celestia" => { - let rollup = new_rollup_with_celestia_da::>( + let rollup = new_rollup_with_celestia_da( &GenesisPaths::from_dir("../test-data/genesis/demo-tests"), rollup_config_path, Some(RollupProverConfig::Execute), @@ -67,7 +65,7 @@ async fn main() -> Result<(), anyhow::Error> { } } -pub async fn new_rollup_with_celestia_da( +async fn new_rollup_with_celestia_da( genesis_paths: &GenesisPaths, rollup_config_path: &str, prover_config: Option, @@ -86,7 +84,7 @@ pub async fn new_rollup_with_celestia_da( .await } -pub async fn new_rollup_with_mock_da( +async fn new_rollup_with_mock_da( genesis_paths: &GenesisPaths, rollup_config_path: &str, prover_config: Option, diff --git a/examples/demo-rollup/src/mock_rollup.rs b/examples/demo-rollup/src/mock_rollup.rs index 58ef6d137..85f2d6349 100644 --- a/examples/demo-rollup/src/mock_rollup.rs +++ b/examples/demo-rollup/src/mock_rollup.rs @@ -9,9 +9,7 @@ use sov_modules_api::Spec; use sov_modules_rollup_template::RollupTemplate; use sov_modules_stf_template::Runtime as RuntimeTrait; use sov_risc0_adapter::host::Risc0Host; -use sov_rollup_interface::mocks::{ - MockAddress, MockDaConfig, MockDaService, MockDaSpec, MOCK_SEQUENCER_DA_ADDRESS, -}; +use sov_rollup_interface::mocks::{MockDaConfig, MockDaService, MockDaSpec}; use sov_rollup_interface::services::da::DaService; use sov_state::{ProverStorage, Storage, ZkStorage}; use sov_stf_runner::RollupConfig; @@ -41,15 +39,14 @@ impl RollupTemplate for MockDemoRollup { fn create_genesis_config( &self, genesis_paths: &Self::GenesisPaths, + rollup_config: &RollupConfig, ) -> >::GenesisConfig { - let sequencer_da_address = MockAddress::from(MOCK_SEQUENCER_DA_ADDRESS); - #[cfg(feature = "experimental")] let eth_signer = read_eth_tx_signers(); get_genesis_config( - sequencer_da_address, + rollup_config.da.sender_address, genesis_paths, #[cfg(feature = "experimental")] eth_signer.signers(), @@ -58,9 +55,9 @@ impl RollupTemplate for MockDemoRollup { async fn create_da_service( &self, - _rollup_config: &RollupConfig, + rollup_config: &RollupConfig, ) -> Self::DaService { - MockDaService::new(MockAddress::from(MOCK_SEQUENCER_DA_ADDRESS)) + MockDaService::new(rollup_config.da.sender_address) } fn create_vm(&self) -> Self::Vm { @@ -81,11 +78,11 @@ impl RollupTemplate for MockDemoRollup { fn create_native_storage( &self, rollup_config: &RollupConfig, - ) -> ::Storage { + ) -> Result<::Storage, anyhow::Error> { let storage_config = StorageConfig { path: rollup_config.storage.path.clone(), }; - ProverStorage::with_config(storage_config).expect("Failed to open prover storage") + ProverStorage::with_config(storage_config) } fn create_rpc_methods( diff --git a/examples/demo-rollup/tests/bank/mod.rs b/examples/demo-rollup/tests/bank/mod.rs index 7f5de302f..454518c0b 100644 --- a/examples/demo-rollup/tests/bank/mod.rs +++ b/examples/demo-rollup/tests/bank/mod.rs @@ -18,6 +18,29 @@ use crate::test_helpers::start_rollup; const TOKEN_SALT: u64 = 0; const TOKEN_NAME: &str = "test_token"; +#[tokio::test] +async fn bank_tx_tests() -> Result<(), anyhow::Error> { + let (port_tx, port_rx) = tokio::sync::oneshot::channel(); + + let rollup_task = tokio::spawn(async { + start_rollup( + port_tx, + GenesisPaths::from_dir("../test-data/genesis/integration-tests"), + Some(RollupProverConfig::Execute), + ) + .await; + }); + + let port = port_rx.await.unwrap(); + + // If the rollup throws an error, return it and stop trying to send the transaction + tokio::select! { + err = rollup_task => err?, + res = send_test_create_token_tx(port) => res?, + }; + Ok(()) +} + async fn send_test_create_token_tx(rpc_address: SocketAddr) -> Result<(), anyhow::Error> { let key = DefaultPrivateKey::generate(); let user_address: ::Address = key.to_address(); @@ -65,26 +88,3 @@ async fn send_test_create_token_tx(rpc_address: SocketAddr) -> Result<(), anyhow assert_eq!(balance_response.amount.unwrap_or_default(), 1000); Ok(()) } - -#[tokio::test] -async fn bank_tx_tests() -> Result<(), anyhow::Error> { - let (port_tx, port_rx) = tokio::sync::oneshot::channel(); - - let rollup_task = tokio::spawn(async { - start_rollup( - port_tx, - GenesisPaths::from_dir("../test-data/genesis/integration-tests"), - Some(RollupProverConfig::Execute), - ) - .await; - }); - - let port = port_rx.await.unwrap(); - - // If the rollup throws an error, return it and stop trying to send the transaction - tokio::select! { - err = rollup_task => err?, - res = send_test_create_token_tx(port) => res?, - }; - Ok(()) -} diff --git a/module-system/sov-modules-rollup-template/src/lib.rs b/module-system/sov-modules-rollup-template/src/lib.rs index 3eeef534d..0ad4eff7b 100644 --- a/module-system/sov-modules-rollup-template/src/lib.rs +++ b/module-system/sov-modules-rollup-template/src/lib.rs @@ -52,6 +52,7 @@ pub trait RollupTemplate: Sized + Send + Sync { fn create_genesis_config( &self, genesis_paths: &Self::GenesisPaths, + rollup_config: &RollupConfig, ) -> >::GenesisConfig; /// Creates instance of DA Service. @@ -70,7 +71,7 @@ pub trait RollupTemplate: Sized + Send + Sync { fn create_native_storage( &self, rollup_config: &RollupConfig, - ) -> ::Storage; + ) -> Result<::Storage, anyhow::Error>; /// Creates instance of ZkVm. fn create_vm(&self) -> Self::Vm; @@ -95,7 +96,7 @@ pub trait RollupTemplate: Sized + Send + Sync { { let da_service = self.create_da_service(&rollup_config).await; let ledger_db = self.create_ledger_db(&rollup_config); - let genesis_config = self.create_genesis_config(genesis_paths); + let genesis_config = self.create_genesis_config(genesis_paths, &rollup_config); let prover = prover_config.map(|pc| { configure_prover( @@ -106,7 +107,7 @@ pub trait RollupTemplate: Sized + Send + Sync { ) }); - let storage = self.create_native_storage(&rollup_config); + let storage = self.create_native_storage(&rollup_config)?; let prev_root = ledger_db .get_head_slot()? diff --git a/sov-rollup-starter/.gitignore b/sov-rollup-starter/.gitignore new file mode 100644 index 000000000..e6031cf8f --- /dev/null +++ b/sov-rollup-starter/.gitignore @@ -0,0 +1 @@ +rollup-starter-data \ No newline at end of file diff --git a/sov-rollup-starter/Cargo.toml b/sov-rollup-starter/Cargo.toml index 51d6214b6..9fb7923df 100644 --- a/sov-rollup-starter/Cargo.toml +++ b/sov-rollup-starter/Cargo.toml @@ -18,8 +18,10 @@ sov-accounts = { path = "../module-system/module-implementations/sov-accounts", sov-bank = { path = "../module-system/module-implementations/sov-bank", features = ["native"] } sov-ledger-rpc = { path = "../full-node/sov-ledger-rpc", features = ["server"] } sov-sequencer-registry = { path = "../module-system/module-implementations/sov-sequencer-registry", features = ["native"] } +sov-modules-rollup-template = { path = "../module-system/sov-modules-rollup-template" } sov-modules-stf-template = { path = "../module-system/sov-modules-stf-template/", features = ["native"] } sov-stf-runner = { path = "../full-node/sov-stf-runner", features = ["native"] } +async-trait = { workspace = true } borsh = { workspace = true } clap = { workspace = true } serde = { workspace = true } diff --git a/sov-rollup-starter/provers/risc0/guest-mock/Cargo.lock b/sov-rollup-starter/provers/risc0/guest-mock/Cargo.lock index 2d87daccd..323955818 100644 --- a/sov-rollup-starter/provers/risc0/guest-mock/Cargo.lock +++ b/sov-rollup-starter/provers/risc0/guest-mock/Cargo.lock @@ -371,8 +371,11 @@ dependencies = [ "anyhow", "risc0-zkvm", "risc0-zkvm-platform", + "sov-modules-api", + "sov-modules-stf-template", "sov-risc0-adapter", "sov-rollup-interface", + "sov-state", "stf-starter", ] diff --git a/sov-rollup-starter/provers/risc0/guest-mock/Cargo.toml b/sov-rollup-starter/provers/risc0/guest-mock/Cargo.toml index 00a11dbdb..847bba3a8 100644 --- a/sov-rollup-starter/provers/risc0/guest-mock/Cargo.toml +++ b/sov-rollup-starter/provers/risc0/guest-mock/Cargo.toml @@ -10,10 +10,15 @@ resolver = "2" anyhow = "1.0.68" risc0-zkvm = { version = "0.18", default-features = false, features = ["std"] } risc0-zkvm-platform = "0.18" -stf-starter = { path = "../../../stf" } sov-risc0-adapter = { path = "../../../../adapters/risc0" } sov-rollup-interface = { path = "../../../../rollup-interface", features = ["mocks"] } +stf-starter = { path = "../../../stf" } + +sov-modules-api = { path = "../../../../module-system/sov-modules-api" } +sov-state = { path = "../../../../module-system/sov-state" } +sov-modules-stf-template = { path = "../../../../module-system/sov-modules-stf-template" } + [patch.crates-io] sha2 = { git = "https://github.com/risc0/RustCrypto-hashes", tag = "sha2/v0.10.6-risc0" } diff --git a/sov-rollup-starter/provers/risc0/guest-mock/src/bin/mock_da.rs b/sov-rollup-starter/provers/risc0/guest-mock/src/bin/mock_da.rs index 3ac2bcbc9..2ecd70cbc 100644 --- a/sov-rollup-starter/provers/risc0/guest-mock/src/bin/mock_da.rs +++ b/sov-rollup-starter/provers/risc0/guest-mock/src/bin/mock_da.rs @@ -1,6 +1,25 @@ #![no_main] //! This binary implements the verification logic for the rollup. This is the code that runs inside //! of the zkvm in order to generate proofs for the rollup. + +use sov_modules_api::default_context::ZkDefaultContext; +use sov_modules_stf_template::AppTemplate; +use sov_risc0_adapter::guest::Risc0Guest; +use sov_rollup_interface::mocks::MockDaVerifier; +use sov_state::ZkStorage; +use stf_starter::runtime::Runtime; +use stf_starter::AppVerifier; + risc0_zkvm::guest::entry!(main); -pub fn main() {} +pub fn main() { + let guest = Risc0Guest::new(); + let storage = ZkStorage::new(); + let app: AppTemplate> = AppTemplate::new(storage); + + let mut stf_verifier = AppVerifier::new(app, MockDaVerifier {}); + + stf_verifier + .run_block(guest) + .expect("Prover must be honest"); +} diff --git a/sov-rollup-starter/rollup_config.toml b/sov-rollup-starter/rollup_config.toml index 94fe44868..2e7ac5701 100644 --- a/sov-rollup-starter/rollup_config.toml +++ b/sov-rollup-starter/rollup_config.toml @@ -3,7 +3,7 @@ sender_address = "01010101010101010101010101010101010101010101010101010101010101 [storage] # The path to the rollup's data directory. Paths that do not begin with `/` are interpreted as relative paths. -path = "demo_data" +path = "rollup-starter-data" # We define the rollup's genesis to occur at block number `start_height`. The rollup will ignore # any blocks before this height diff --git a/sov-rollup-starter/src/bin/node.rs b/sov-rollup-starter/src/bin/node.rs index 5e5d6f159..e8d7d6e15 100644 --- a/sov-rollup-starter/src/bin/node.rs +++ b/sov-rollup-starter/src/bin/node.rs @@ -1,53 +1,64 @@ //! This binary runs the rollup full node. -use std::env; use std::path::PathBuf; use anyhow::Context; -use sov_risc0_adapter::host::Risc0Host; -use sov_rollup_interface::mocks::{MockAddress, MOCK_SEQUENCER_DA_ADDRESS}; -use sov_rollup_starter::da::{start_da_service, DaConfig}; -use sov_rollup_starter::rollup::Rollup; +use clap::Parser; +use sov_modules_rollup_template::{Rollup, RollupProverConfig, RollupTemplate}; +use sov_rollup_interface::mocks::MockDaConfig; +use sov_rollup_starter::rollup::StarterRollup; use sov_stf_runner::{from_toml_path, RollupConfig}; -use stf_starter::{get_genesis_config, GenesisPaths}; +use stf_starter::genesis_config::GenesisPaths; use tracing::info; -use tracing_subscriber::filter::LevelFilter; -use tracing_subscriber::EnvFilter; +use tracing_subscriber::prelude::*; +use tracing_subscriber::{fmt, EnvFilter}; + +#[derive(Parser, Debug)] +#[command(author, version, about, long_about = None)] +struct Args { + /// The path to the rollup config. + #[arg(long, default_value = "rollup_config.toml")] + rollup_config_path: String, + + /// The path to the genesis config. + #[arg(long, default_value = "test-data/genesis/")] + genesis_paths: String, +} #[tokio::main] async fn main() -> Result<(), anyhow::Error> { - // Initialize a logger for the demo - let subscriber = tracing_subscriber::fmt() - .with_env_filter( - EnvFilter::builder() - .with_default_directive(LevelFilter::INFO.into()) // If no logging config is set. default to `info` level logs - .from_env_lossy(), // Parse the log level from the RUST_LOG env var if set - ) // Try to override logging config from RUST_LOG env var - .finish(); - tracing::subscriber::set_global_default(subscriber) - .context("Unable to set global default subscriber")?; - - // Read the rollup config from a file - let rollup_config_path = env::args() - .nth(1) - .map(PathBuf::from) - .unwrap_or_else(|| PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("rollup_config.toml")); - info!("Reading rollup config from {rollup_config_path:?}"); + // Initializing logging + tracing_subscriber::registry() + .with(fmt::layer()) + .with(EnvFilter::from_default_env()) + .init(); - let rollup_config: RollupConfig = - from_toml_path(rollup_config_path).context("Failed to read rollup configuration")?; - info!("Initializing DA service"); - let da_service = start_da_service(&rollup_config).await; + let args = Args::parse(); + let rollup_config_path = args.rollup_config_path.as_str(); - let sequencer_da_address = MockAddress::from(MOCK_SEQUENCER_DA_ADDRESS); - let genesis_paths = GenesisPaths::from_dir("../../test-data/genesis/"); - let genesis_config = get_genesis_config(sequencer_da_address, &genesis_paths); + let genesis_paths = args.genesis_paths.as_str(); - // Start rollup - let rollup: Rollup = - Rollup::new(da_service, genesis_config, rollup_config, None)?; + let rollup = new_rollup_with_mock_da( + &GenesisPaths::from_dir(genesis_paths), + rollup_config_path, + Some(RollupProverConfig::Execute), + ) + .await?; + rollup.run().await +} + +async fn new_rollup_with_mock_da( + genesis_paths: &GenesisPaths, + rollup_config_path: &str, + prover_config: Option, +) -> Result, anyhow::Error> { + info!("Reading rollup config from {rollup_config_path:?}"); - rollup.run().await?; + let rollup_config: RollupConfig = + from_toml_path(rollup_config_path).context("Failed to read rollup configuration")?; - Ok(()) + let starter_rollup = StarterRollup {}; + starter_rollup + .create_new_rollup(genesis_paths, rollup_config, prover_config) + .await } diff --git a/sov-rollup-starter/src/da.rs b/sov-rollup-starter/src/da.rs deleted file mode 100644 index 0bea35f23..000000000 --- a/sov-rollup-starter/src/da.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! This crate configures the da layer used by the rollup. -use sov_stf_runner::RollupConfig; -/// The type alias for the DA layer configuration. Change the contents of this alias if you change DA layers. -pub type DaConfig = sov_rollup_interface::mocks::MockDaConfig; -/// The type alias for the DA service. Change the contents of this alias if you change DA layers. -pub type DaService = sov_rollup_interface::mocks::MockDaService; - -/// Creates a new instance of the DA Service -pub async fn start_da_service(rollup_config: &RollupConfig) -> DaService { - DaService::new(rollup_config.da.sender_address) -} diff --git a/sov-rollup-starter/src/lib.rs b/sov-rollup-starter/src/lib.rs index 839788293..3b3bc2154 100644 --- a/sov-rollup-starter/src/lib.rs +++ b/sov-rollup-starter/src/lib.rs @@ -1,5 +1,4 @@ #![deny(missing_docs)] #![doc = include_str!("../README.md")] -pub mod da; -mod register_rpc; +mod register_sequencer; pub mod rollup; diff --git a/sov-rollup-starter/src/register_rpc.rs b/sov-rollup-starter/src/register_rpc.rs deleted file mode 100644 index c8a07e165..000000000 --- a/sov-rollup-starter/src/register_rpc.rs +++ /dev/null @@ -1,22 +0,0 @@ -use anyhow::Context; -use sov_modules_api::Zkvm; -use sov_rollup_interface::services::da::DaService; -use sov_sequencer::get_sequencer_rpc; -use stf_starter::StfWithBuilder; - -/// register sequencer rpc methods. -pub(crate) fn register_sequencer( - da_service: Da, - app: &mut StfWithBuilder, - methods: &mut jsonrpsee::RpcModule<()>, -) -> Result<(), anyhow::Error> -where - Da: DaService, - Vm: Zkvm, -{ - let batch_builder = app.batch_builder.take().unwrap(); - let sequencer_rpc = get_sequencer_rpc(batch_builder, da_service); - methods - .merge(sequencer_rpc) - .context("Failed to merge Txs RPC modules") -} diff --git a/sov-rollup-starter/src/register_sequencer.rs b/sov-rollup-starter/src/register_sequencer.rs new file mode 100644 index 000000000..99e8da07b --- /dev/null +++ b/sov-rollup-starter/src/register_sequencer.rs @@ -0,0 +1,37 @@ +use anyhow::Context; +use sov_modules_api::default_context::DefaultContext; +use sov_modules_api::Spec; +use sov_rollup_interface::da::DaSpec; +use sov_rollup_interface::services::da::DaService; +use sov_sequencer::batch_builder::FiFoStrictBatchBuilder; +use sov_sequencer::get_sequencer_rpc; +use sov_state::ProverStorage; +use stf_starter::Runtime; + +/// register sequencer rpc methods. +pub(crate) fn register_sequencer( + storage: &::Storage, + da_service: Da, + methods: &mut jsonrpsee::RpcModule<()>, +) -> Result<(), anyhow::Error> +where + Da: DaService, +{ + let batch_builder = create_batch_builder::<::Spec>(storage.clone()); + let sequencer_rpc = get_sequencer_rpc(batch_builder, da_service); + methods + .merge(sequencer_rpc) + .context("Failed to merge Txs RPC modules") +} + +fn create_batch_builder( + storage: ProverStorage, +) -> FiFoStrictBatchBuilder, DefaultContext> { + let batch_size_bytes = 1024 * 100; // max allowed batch size = 100 KB + FiFoStrictBatchBuilder::new( + batch_size_bytes, + u32::MAX as usize, + Runtime::default(), + storage, + ) +} diff --git a/sov-rollup-starter/src/rollup.rs b/sov-rollup-starter/src/rollup.rs index 0ef7db2e2..4990f9645 100644 --- a/sov-rollup-starter/src/rollup.rs +++ b/sov-rollup-starter/src/rollup.rs @@ -1,110 +1,99 @@ //! Defines the rollup full node implementation, including logic for configuring //! and starting the rollup node. -use jsonrpsee::RpcModule; -use serde::de::DeserializeOwned; +use std::path::PathBuf; + +use async_trait::async_trait; use sov_db::ledger_db::LedgerDB; use sov_modules_api::default_context::{DefaultContext, ZkDefaultContext}; use sov_modules_api::Spec; -use sov_modules_stf_template::{AppTemplate, SequencerOutcome, TxEffect}; +use sov_modules_rollup_template::RollupTemplate; +use sov_modules_stf_template::{Runtime as RuntimeTrait, SequencerOutcome, TxEffect}; +use sov_risc0_adapter::host::Risc0Host; +use sov_rollup_interface::mocks::{MockDaConfig, MockDaService, MockDaSpec}; use sov_rollup_interface::services::da::DaService; -use sov_rollup_interface::zk::ZkvmHost; -use sov_state::storage::NativeStorage; -use sov_stf_runner::{Prover, RollupConfig, RunnerConfig, StateTransitionRunner}; -use stf_starter::{get_rpc_methods, GenesisConfig, Runtime, StfWithBuilder}; -use tokio::sync::oneshot; - -use crate::register_rpc::register_sequencer; -type ZkStf = AppTemplate>; - -/// Dependencies needed to run the rollup. -/// This is duplicated exactly from demo-rollup. Should go to stf-runner crate? -pub struct Rollup { - // Implementation of the STF. - pub(crate) app: StfWithBuilder, - // Data availability service. - pub(crate) da_service: Da, - // Ledger db. - pub(crate) ledger_db: LedgerDB, - // Runner configuration. - pub(crate) runner_config: RunnerConfig, - // Initial rollup configuration. - pub(crate) genesis_config: GenesisConfig, - // Prover for the rollup. - #[allow(clippy::type_complexity)] - pub(crate) prover: Option, Da, Vm>>, -} +use sov_state::config::Config as StorageConfig; +use sov_state::{ProverStorage, Storage, ZkStorage}; +use sov_stf_runner::RollupConfig; +use stf_starter::genesis_config::{get_genesis_config, GenesisPaths}; +use stf_starter::{get_rpc_methods, Runtime}; + +use crate::register_sequencer::register_sequencer; + +/// Rollup with MockDa. +pub struct StarterRollup {} + +#[async_trait] +impl RollupTemplate for StarterRollup { + type DaService = MockDaService; + type GenesisPaths = GenesisPaths; + type Vm = Risc0Host<'static>; + + type ZkContext = ZkDefaultContext; + type NativeContext = DefaultContext; + + type ZkRuntime = Runtime; + type NativeRuntime = Runtime; + + type DaSpec = MockDaSpec; + type DaConfig = MockDaConfig; + + fn create_genesis_config( + &self, + genesis_paths: &Self::GenesisPaths, + rollup_config: &RollupConfig, + ) -> >::GenesisConfig + { + get_genesis_config(rollup_config.da.sender_address, genesis_paths) + } + + async fn create_da_service( + &self, + rollup_config: &RollupConfig, + ) -> Self::DaService { + MockDaService::new(rollup_config.da.sender_address) + } + + fn create_vm(&self) -> Self::Vm { + Risc0Host::new(risc0_starter::MOCK_DA_ELF) + } -impl + Clone> Rollup { - /// Creates a new rollup instance - #[allow(clippy::type_complexity)] - pub fn new( - da_service: Da, - genesis_config: GenesisConfig, - config: RollupConfig, - prover: Option, Da, Vm>>, - ) -> Result { - let ledger_db = LedgerDB::with_path(&config.storage.path)?; - let app = StfWithBuilder::new(config.storage.clone()); - Ok(Self { - app, - da_service, - ledger_db, - runner_config: config.runner, - genesis_config, - prover, - }) + fn create_zk_storage( + &self, + _rollup_config: &RollupConfig, + ) -> ::Storage { + ZkStorage::new() } - /// Runs the rollup. - pub async fn run(self) -> Result<(), anyhow::Error> { - self.run_and_report_rpc_port(None).await + fn create_verifier(&self) -> ::Verifier { + Default::default() } - /// Runs the rollup. Reports rpc port to the caller using the provided channel. - pub async fn run_and_report_rpc_port( - mut self, - channel: Option>, - ) -> Result<(), anyhow::Error> { - let storage = self.app.get_storage(); - let last_slot_opt = self.ledger_db.get_head_slot()?; - let prev_root = last_slot_opt - .map(|(number, _)| storage.get_root_hash(number.0)) - .transpose()?; - - let rpc_module = self.rpc_module(storage)?; - - let mut runner = StateTransitionRunner::new( - self.runner_config, - self.da_service, - self.ledger_db, - self.app.stf, - prev_root, - self.genesis_config, - self.prover, - )?; - - runner.start_rpc_server(rpc_module, channel).await; - runner.run_in_process().await?; - - Ok(()) + fn create_native_storage( + &self, + rollup_config: &RollupConfig, + ) -> Result<::Storage, anyhow::Error> { + let storage_config = StorageConfig { + path: rollup_config.storage.path.clone(), + }; + ProverStorage::with_config(storage_config) } - /// Creates a new [`jsonrpsee::RpcModule`] and registers all RPC methods - /// exposed by the node. - fn rpc_module( - &mut self, - storage: ::Storage, - ) -> anyhow::Result> { - let mut module = get_rpc_methods::(storage.clone()); + fn create_rpc_methods( + &self, + storage: &::Storage, + ledger_db: &LedgerDB, + da_service: &Self::DaService, + ) -> Result, anyhow::Error> { + let mut module = get_rpc_methods::(storage.clone()); module.merge(sov_ledger_rpc::server::rpc_module::< LedgerDB, SequencerOutcome<::Address>, TxEffect, - >(self.ledger_db.clone())?)?; - register_sequencer(self.da_service.clone(), &mut self.app, &mut module)?; + >(ledger_db.clone())?)?; + register_sequencer::(storage, da_service.clone(), &mut module)?; Ok(module) } } diff --git a/sov-rollup-starter/stf/src/builder.rs b/sov-rollup-starter/stf/src/builder.rs deleted file mode 100644 index 87470d9fe..000000000 --- a/sov-rollup-starter/stf/src/builder.rs +++ /dev/null @@ -1,48 +0,0 @@ -//! This module implements the batch builder for the rollup. -//! To swap out the batch builder, simply replace the -//! FiFoStrictBatchBuilder in `StfWithBuilder` with a type of your choosing. -use sov_modules_api::default_context::DefaultContext; -#[cfg(feature = "native")] -use sov_modules_api::Spec; -use sov_modules_api::{DaSpec, Zkvm}; -use sov_modules_stf_template::AppTemplate; -#[cfg(feature = "native")] -use sov_sequencer::batch_builder::FiFoStrictBatchBuilder; -#[cfg(feature = "native")] -use sov_state::{ProverStorage, Storage}; - -use super::runtime::Runtime; - -/// The "native" version of the STF and a batch builder -pub struct StfWithBuilder { - pub stf: AppTemplate>, - pub batch_builder: Option, DefaultContext>>, -} - -#[cfg(feature = "native")] -impl StfWithBuilder { - /// Create a new rollup instance - pub fn new(storage_config: sov_stf_runner::StorageConfig) -> Self { - let config = sov_state::config::Config { - path: storage_config.path, - }; - - let storage = ProverStorage::with_config(config).expect("Failed to open prover storage"); - let app = AppTemplate::new(storage.clone()); - let batch_size_bytes = 1024 * 100; // 100 KB - let batch_builder = FiFoStrictBatchBuilder::new( - batch_size_bytes, - u32::MAX as usize, - Runtime::default(), - storage, - ); - Self { - stf: app, - batch_builder: Some(batch_builder), - } - } - - pub fn get_storage(&self) -> ::Storage { - self.stf.current_storage.clone() - } -} diff --git a/sov-rollup-starter/stf/src/lib.rs b/sov-rollup-starter/stf/src/lib.rs index 0e88e28a9..155d8c492 100644 --- a/sov-rollup-starter/stf/src/lib.rs +++ b/sov-rollup-starter/stf/src/lib.rs @@ -1,13 +1,13 @@ //! The rollup State Transition Function. #[cfg(feature = "native")] -mod builder; -#[cfg(feature = "native")] -mod genesis_config; +pub mod genesis_config; mod hooks; -mod runtime; - -#[cfg(feature = "native")] -pub use builder::*; -#[cfg(feature = "native")] -pub use genesis_config::*; +pub mod runtime; pub use runtime::*; +use sov_modules_stf_template::AppTemplate; +use sov_rollup_interface::da::DaVerifier; +use sov_stf_runner::verifier::StateTransitionVerifier; + +/// Alias for StateTransitionVerifier. +pub type AppVerifier = + StateTransitionVerifier::Spec, Vm, RT>, DA, Vm>; diff --git a/sov-rollup-starter/tests/bank/mod.rs b/sov-rollup-starter/tests/bank/mod.rs index b6aabd9d0..1b3b38bf5 100644 --- a/sov-rollup-starter/tests/bank/mod.rs +++ b/sov-rollup-starter/tests/bank/mod.rs @@ -7,16 +7,40 @@ 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::{PrivateKey, Spec}; -use sov_risc0_adapter::host::Risc0Host; +use sov_modules_rollup_template::RollupProverConfig; use sov_rollup_interface::mocks::MockDaSpec; use sov_sequencer::utils::SimpleClient; -use stf_starter::{GenesisPaths, RuntimeCall}; +use stf_starter::genesis_config::GenesisPaths; +use stf_starter::RuntimeCall; use super::test_helpers::start_rollup; const TOKEN_SALT: u64 = 0; const TOKEN_NAME: &str = "test_token"; +#[tokio::test] +async fn bank_tx_tests() -> Result<(), anyhow::Error> { + let (port_tx, port_rx) = tokio::sync::oneshot::channel(); + + let rollup_task = tokio::spawn(async { + start_rollup( + port_tx, + GenesisPaths::from_dir("test-data/genesis/"), + Some(RollupProverConfig::Execute), + ) + .await; + }); + + let port = port_rx.await.unwrap(); + + // If the rollup throws an error, return it and stop trying to send the transaction + tokio::select! { + err = rollup_task => err?, + res = send_test_create_token_tx(port) => res?, + }; + Ok(()) +} + async fn send_test_create_token_tx(rpc_address: SocketAddr) -> Result<(), anyhow::Error> { let key = DefaultPrivateKey::generate(); let user_address: ::Address = key.to_address(); @@ -64,26 +88,3 @@ async fn send_test_create_token_tx(rpc_address: SocketAddr) -> Result<(), anyhow assert_eq!(balance_response.amount.unwrap_or_default(), 1000); Ok(()) } - -#[tokio::test] -async fn bank_tx_tests() -> Result<(), anyhow::Error> { - let (port_tx, port_rx) = tokio::sync::oneshot::channel(); - - let rollup_task = tokio::spawn(async { - start_rollup::, _>( - port_tx, - &GenesisPaths::from_dir("test-data/genesis/"), - ) - .await; - }); - - // Wait for rollup task to start: - let port = port_rx.await.unwrap(); - - // If the rollup throws an error, return it and stop trying to send the transaction - tokio::select! { - err = rollup_task => err?, - res = send_test_create_token_tx(port) => res?, - }; - Ok(()) -} diff --git a/sov-rollup-starter/tests/test_helpers.rs b/sov-rollup-starter/tests/test_helpers.rs index f92f6da18..cade8b16b 100644 --- a/sov-rollup-starter/tests/test_helpers.rs +++ b/sov-rollup-starter/tests/test_helpers.rs @@ -1,26 +1,21 @@ use std::net::SocketAddr; -use std::path::Path; +use std::path::PathBuf; -use sov_rollup_interface::mocks::{ - MockAddress, MockDaConfig, MockDaService, MOCK_SEQUENCER_DA_ADDRESS, -}; -use sov_rollup_interface::zk::ZkvmHost; -use sov_rollup_starter::rollup::Rollup; +use sov_modules_rollup_template::{RollupProverConfig, RollupTemplate}; +use sov_rollup_interface::mocks::{MockAddress, MockDaConfig}; +use sov_rollup_starter::rollup::StarterRollup; use sov_stf_runner::{RollupConfig, RpcConfig, RunnerConfig, StorageConfig}; -use stf_starter::{get_genesis_config, GenesisPaths}; +use stf_starter::genesis_config::GenesisPaths; use tokio::sync::oneshot; -pub async fn start_rollup>( +pub async fn start_rollup( rpc_reporting_channel: oneshot::Sender, - genesis_paths: &GenesisPaths

, + genesis_paths: GenesisPaths, + rollup_prover_config: Option, ) { let temp_dir = tempfile::tempdir().unwrap(); let temp_path = temp_dir.path(); - let sequencer_da_address = MockAddress::from(MOCK_SEQUENCER_DA_ADDRESS); - - let genesis_config = get_genesis_config(sequencer_da_address, genesis_paths); - let rollup_config = RollupConfig { storage: StorageConfig { path: temp_path.to_path_buf(), @@ -33,17 +28,16 @@ pub async fn start_rollup>( }, }, da: MockDaConfig { - sender_address: genesis_config.sequencer_registry.seq_da_address, + sender_address: MockAddress { addr: [0; 32] }, }, }; - let rollup = Rollup::::new( - MockDaService::new(genesis_config.sequencer_registry.seq_da_address), - genesis_config, - rollup_config, - None, - ) - .unwrap(); + let starter_rollup = StarterRollup {}; + + let rollup = starter_rollup + .create_new_rollup(&genesis_paths, rollup_config, rollup_prover_config) + .await + .unwrap(); rollup .run_and_report_rpc_port(Some(rpc_reporting_channel))