diff --git a/Cargo.lock b/Cargo.lock index dc0e4c410..1ae71d6cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1106,16 +1106,6 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" -[[package]] -name = "bashtestmd" -version = "0.5.0-rc.1" -dependencies = [ - "clap", - "indoc", - "markdown", - "shell-escape", -] - [[package]] name = "bcs" version = "0.1.6" @@ -2161,10 +2151,6 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" -[[package]] -name = "const-rollup-config" -version = "0.5.0-rc.1" - [[package]] name = "constant_time_eq" version = "0.3.0" @@ -2479,50 +2465,6 @@ dependencies = [ "parking_lot_core", ] -[[package]] -name = "demo-simple-stf" -version = "0.5.0-rc.1" -dependencies = [ - "anyhow", - "hex", - "serde", - "sha2", - "sov-mock-da", - "sov-mock-zkvm", - "sov-rollup-interface 0.5.0-rc.1", -] - -[[package]] -name = "demo-stf" -version = "0.5.0-rc.1" -dependencies = [ - "anyhow", - "borsh", - "citrea-evm", - "clap", - "hex", - "jsonrpsee", - "rand 0.8.5", - "reth-primitives", - "secp256k1", - "serde", - "serde_json", - "soft-confirmation-rule-enforcer", - "sov-accounts", - "sov-bank", - "sov-modules-api", - "sov-modules-stf-blueprint", - "sov-prover-storage-manager", - "sov-rollup-interface 0.5.0-rc.1", - "sov-sequencer-registry", - "sov-state", - "sov-stf-runner", - "sov-value-setter", - "tempfile", - "tokio", - "tracing", -] - [[package]] name = "der" version = "0.7.9" @@ -3829,12 +3771,6 @@ dependencies = [ "serde", ] -[[package]] -name = "indoc" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" - [[package]] name = "informalsystems-pbjson" version = "0.7.0" @@ -4432,15 +4368,6 @@ dependencies = [ "libc", ] -[[package]] -name = "markdown" -version = "1.0.0-alpha.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e27d6220ce21f80ce5c4201f23a37c6f1ad037c72c9d1ff215c2919605a5d6" -dependencies = [ - "unicode-id", -] - [[package]] name = "matchers" version = "0.1.0" @@ -4581,27 +4508,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "module-template" -version = "0.5.0-rc.1" -dependencies = [ - "anyhow", - "arbitrary", - "borsh", - "module-template", - "proptest", - "proptest-derive", - "schemars", - "serde", - "serde_json", - "sov-bank", - "sov-modules-api", - "sov-prover-storage-manager", - "sov-state", - "tempfile", - "thiserror", -] - [[package]] name = "ndarray" version = "0.16.1" @@ -7444,12 +7350,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "shell-escape" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f" - [[package]] name = "shlex" version = "1.3.0" @@ -7556,19 +7456,6 @@ dependencies = [ "sha1", ] -[[package]] -name = "sov-accessory-state" -version = "0.5.0-rc.1" -dependencies = [ - "borsh", - "jsonrpsee", - "serde", - "sov-modules-api", - "sov-prover-storage-manager", - "sov-state", - "tempfile", -] - [[package]] name = "sov-accounts" version = "0.5.0-rc.1" @@ -7609,39 +7496,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "sov-cli" -version = "0.5.0-rc.1" -dependencies = [ - "anyhow", - "borsh", - "demo-stf", - "directories", - "hex", - "jsonrpsee", - "serde", - "serde_json", - "sov-accounts", - "sov-bank", - "sov-mock-da", - "sov-modules-api", - "tempfile", -] - -[[package]] -name = "sov-data-generators" -version = "0.5.0-rc.1" -dependencies = [ - "borsh", - "proptest", - "sov-bank", - "sov-mock-da", - "sov-modules-api", - "sov-modules-stf-blueprint", - "sov-state", - "sov-value-setter", -] - [[package]] name = "sov-db" version = "0.5.0-rc.1" @@ -7729,20 +7583,6 @@ dependencies = [ "sov-rollup-interface 0.5.0-rc.1", ] -[[package]] -name = "sov-module-schemas" -version = "0.5.0-rc.1" -dependencies = [ - "sov-accounts", - "sov-bank", - "sov-mock-da", - "sov-mock-zkvm", - "sov-modules-api", - "sov-prover-incentives", - "sov-sequencer-registry", - "sov-value-setter", -] - [[package]] name = "sov-modules-api" version = "0.5.0-rc.1" @@ -7831,19 +7671,13 @@ version = "0.5.0-rc.1" dependencies = [ "anyhow", "async-trait", - "borsh", "citrea-common", - "hex", "jsonrpsee", - "serde", - "serde_json", - "sov-cli", "sov-db", "sov-ledger-rpc 0.5.0-rc.1", "sov-modules-api", "sov-modules-stf-blueprint", "sov-rollup-interface 0.5.0-rc.1", - "sov-state", "sov-stf-runner", "tokio", "tracing", @@ -7859,38 +7693,14 @@ dependencies = [ "itertools 0.13.0", "jmt", "jsonrpsee", - "risc0-zkvm", - "risc0-zkvm-platform", "rs_merkle", "serde", "sov-modules-api", "sov-rollup-interface 0.5.0-rc.1", "sov-state", - "sov-zk-cycle-macros", - "sov-zk-cycle-utils", - "thiserror", "tracing", ] -[[package]] -name = "sov-prover-incentives" -version = "0.5.0-rc.1" -dependencies = [ - "anyhow", - "bincode", - "borsh", - "schemars", - "serde", - "serde_json", - "sov-bank", - "sov-mock-da", - "sov-mock-zkvm", - "sov-modules-api", - "sov-prover-storage-manager", - "sov-state", - "tempfile", -] - [[package]] name = "sov-prover-storage-manager" version = "0.5.0-rc.1" @@ -7987,33 +7797,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "sov-sequencer-registry" -version = "0.5.0-rc.1" -dependencies = [ - "anyhow", - "arbitrary", - "borsh", - "clap", - "jsonrpsee", - "proptest", - "proptest-derive", - "risc0-zkvm", - "risc0-zkvm-platform", - "schemars", - "serde", - "serde_json", - "sov-bank", - "sov-mock-da", - "sov-modules-api", - "sov-prover-storage-manager", - "sov-sequencer-registry", - "sov-state", - "sov-zk-cycle-macros", - "sov-zk-cycle-utils", - "tempfile", -] - [[package]] name = "sov-state" version = "0.5.0-rc.1" @@ -8022,21 +7805,15 @@ dependencies = [ "arbitrary", "bcs", "borsh", - "hex", "jmt", "proptest", "proptest-derive", - "risc0-zkvm", - "risc0-zkvm-platform", "serde", - "serde_json", "sha2", "sov-db", "sov-modules-core", "sov-rollup-interface 0.5.0-rc.1", - "sov-zk-cycle-macros", "tempfile", - "thiserror", ] [[package]] @@ -8066,42 +7843,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "sov-value-setter" -version = "0.5.0-rc.1" -dependencies = [ - "anyhow", - "borsh", - "clap", - "jsonrpsee", - "schemars", - "serde", - "serde_json", - "sov-modules-api", - "sov-prover-storage-manager", - "sov-state", - "tempfile", - "thiserror", -] - -[[package]] -name = "sov-vec-setter" -version = "0.5.0-rc.1" -dependencies = [ - "anyhow", - "borsh", - "clap", - "jsonrpsee", - "schemars", - "serde", - "serde_json", - "sov-modules-api", - "sov-prover-storage-manager", - "sov-state", - "tempfile", - "thiserror", -] - [[package]] name = "sov-zk-cycle-macros" version = "0.5.0-rc.1" @@ -8111,7 +7852,7 @@ dependencies = [ "risc0-zkvm", "risc0-zkvm-platform", "sov-zk-cycle-macros", - "syn 1.0.109", + "syn 2.0.72", "trybuild", ] @@ -8119,7 +7860,6 @@ dependencies = [ name = "sov-zk-cycle-utils" version = "0.5.0-rc.1" dependencies = [ - "bytes", "risc0-zkvm", "risc0-zkvm-platform", ] @@ -8900,12 +8640,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "unicode-id" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1b6def86329695390197b82c1e244a54a131ceb66c996f2088a3876e2ae083f" - [[package]] name = "unicode-ident" version = "1.0.12" diff --git a/Cargo.toml b/Cargo.toml index 2bba62015..70733fb30 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,10 +23,6 @@ members = [ "crates/sovereign-sdk/adapters/risc0", "crates/sovereign-sdk/adapters/mock-da", "crates/sovereign-sdk/adapters/mock-zkvm", - # Examples - "crates/sovereign-sdk/examples/const-rollup-config", - "crates/sovereign-sdk/examples/demo-simple-stf", - "crates/sovereign-sdk/examples/demo-stf", # Full Node "crates/sovereign-sdk/full-node/db/sov-db", "crates/sovereign-sdk/full-node/sov-ledger-rpc", @@ -35,25 +31,15 @@ members = [ # Utils "crates/sovereign-sdk/utils/zk-cycle-macros", "crates/sovereign-sdk/utils/zk-cycle-utils", - "crates/sovereign-sdk/utils/bashtestmd", # Module System - "crates/sovereign-sdk/module-system/sov-cli", "crates/sovereign-sdk/module-system/sov-modules-stf-blueprint", "crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint", "crates/sovereign-sdk/module-system/sov-modules-macros", "crates/sovereign-sdk/module-system/sov-modules-core", "crates/sovereign-sdk/module-system/sov-state", "crates/sovereign-sdk/module-system/sov-modules-api", - "crates/sovereign-sdk/module-system/module-schemas", - "crates/sovereign-sdk/module-system/utils/sov-data-generators", "crates/sovereign-sdk/module-system/module-implementations/sov-accounts", "crates/sovereign-sdk/module-system/module-implementations/sov-bank", - "crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives", - "crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry", - "crates/sovereign-sdk/module-system/module-implementations/module-template", - "crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter", - "crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter", - "crates/sovereign-sdk/module-system/module-implementations/examples/sov-accessory-state", "crates/sovereign-sdk/module-system/module-implementations/integration-tests", ] @@ -169,17 +155,6 @@ tower-http = { version = "0.5.0", features = ["full"] } tower = { version = "0.4.13", features = ["full"] } hyper = { version = "1.4.0" } -[patch.'https://github.com/eigerco/celestia-node-rs.git'] -# Uncomment to apply local changes -# celestia-proto = { path = "../celestia-node-rs/proto" } -# celestia-rpc = { path = "../celestia-node-rs/rpc" } -# celestia-types = { path = "../celestia-node-rs/types" } - -[patch.'https://github.com/eigerco/celestia-tendermint-rs.git'] -# Uncomment to apply local changes -# tendermint = { path = "../celestia-tendermint-rs/tendermint" } -# tendermint-proto = { path = "../celestia-tendermint-rs/proto" } - # putting risc0 patches here as well #  surprisignly decreased cycle counts [patch.crates-io] diff --git a/bin/citrea/provers/risc0/batch-prover-bitcoin/Cargo.lock b/bin/citrea/provers/risc0/batch-prover-bitcoin/Cargo.lock index 072ff628a..65a4cf4ee 100644 --- a/bin/citrea/provers/risc0/batch-prover-bitcoin/Cargo.lock +++ b/bin/citrea/provers/risc0/batch-prover-bitcoin/Cargo.lock @@ -2986,15 +2986,11 @@ dependencies = [ "hex", "itertools 0.13.0", "jmt", - "risc0-zkvm", - "risc0-zkvm-platform", "rs_merkle", "serde", "sov-modules-api", "sov-rollup-interface", "sov-state", - "sov-zk-cycle-macros", - "thiserror", ] [[package]] @@ -3034,17 +3030,11 @@ dependencies = [ "anyhow", "bcs", "borsh", - "hex", "jmt", - "risc0-zkvm", - "risc0-zkvm-platform", "serde", - "serde_json", "sha2", "sov-modules-core", "sov-rollup-interface", - "sov-zk-cycle-macros", - "thiserror", ] [[package]] @@ -3060,15 +3050,6 @@ dependencies = [ "sov-rollup-interface", ] -[[package]] -name = "sov-zk-cycle-macros" -version = "0.5.0-rc.1" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "spin" version = "0.9.8" diff --git a/bin/citrea/provers/risc0/batch-prover-bitcoin/Cargo.toml b/bin/citrea/provers/risc0/batch-prover-bitcoin/Cargo.toml index 8d01a16d4..efe3eafab 100644 --- a/bin/citrea/provers/risc0/batch-prover-bitcoin/Cargo.toml +++ b/bin/citrea/provers/risc0/batch-prover-bitcoin/Cargo.toml @@ -32,10 +32,3 @@ debug = 0 lto = true opt-level = 3 codegen-units = 1 - -[features] -bench = [ - "sov-modules-api/bench", - "sov-state/bench", - "sov-modules-stf-blueprint/bench", -] diff --git a/bin/citrea/provers/risc0/batch-prover-bitcoin/src/bin/batch_prover_bitcoin.rs b/bin/citrea/provers/risc0/batch-prover-bitcoin/src/bin/batch_prover_bitcoin.rs index a1e9f27ac..14d77bfa9 100644 --- a/bin/citrea/provers/risc0/batch-prover-bitcoin/src/bin/batch_prover_bitcoin.rs +++ b/bin/citrea/provers/risc0/batch-prover-bitcoin/src/bin/batch_prover_bitcoin.rs @@ -4,38 +4,17 @@ use bitcoin_da::verifier::BitcoinVerifier; use citrea_primitives::{REVEAL_BATCH_PROOF_PREFIX, REVEAL_LIGHT_CLIENT_PREFIX}; use citrea_stf::runtime::Runtime; use citrea_stf::StfVerifier; -#[cfg(feature = "bench")] -use risc0_zkvm::guest::env; use sov_modules_api::default_context::ZkDefaultContext; use sov_modules_stf_blueprint::StfBlueprint; use sov_risc0_adapter::guest::Risc0Guest; use sov_rollup_interface::da::DaVerifier; use sov_state::ZkStorage; -#[cfg(feature = "bench")] -fn report_bench_metrics(start_cycles: u64, end_cycles: u64) { - let cycles_per_block = end_cycles - start_cycles; - let tuple = ("Cycles per block".to_string(), cycles_per_block); - let mut serialized = Vec::new(); - serialized.extend(tuple.0.as_bytes()); - serialized.push(0); - let size_bytes = tuple.1.to_ne_bytes(); - serialized.extend(&size_bytes); - - // calculate the syscall name. - let name = c"cycle_metrics"; - let metrics_syscall_name = risc0_zkvm_platform::syscall::SyscallName::from_c_str(name).unwrap(); - - risc0_zkvm::guest::env::send_recv_slice::(metrics_syscall_name, &serialized); -} - risc0_zkvm::guest::entry!(main); pub fn main() { let guest = Risc0Guest::new(); let storage = ZkStorage::new(); - #[cfg(feature = "bench")] - let start_cycles = env::cycle_count(); let stf: StfBlueprint> = StfBlueprint::new(); @@ -50,10 +29,4 @@ pub fn main() { stf_verifier .run_sequencer_commitments_in_da_slot(guest, storage) .expect("Prover must be honest"); - - #[cfg(feature = "bench")] - { - let end_cycles = env::cycle_count(); - report_bench_metrics(start_cycles, end_cycles); - } } diff --git a/bin/citrea/provers/risc0/batch-prover-mock/Cargo.lock b/bin/citrea/provers/risc0/batch-prover-mock/Cargo.lock index 9df1e7c5a..c93fa7e5a 100644 --- a/bin/citrea/provers/risc0/batch-prover-mock/Cargo.lock +++ b/bin/citrea/provers/risc0/batch-prover-mock/Cargo.lock @@ -2789,15 +2789,11 @@ dependencies = [ "hex", "itertools 0.13.0", "jmt", - "risc0-zkvm", - "risc0-zkvm-platform", "rs_merkle", "serde", "sov-modules-api", "sov-rollup-interface", "sov-state", - "sov-zk-cycle-macros", - "thiserror", ] [[package]] @@ -2837,17 +2833,11 @@ dependencies = [ "anyhow", "bcs", "borsh", - "hex", "jmt", - "risc0-zkvm", - "risc0-zkvm-platform", "serde", - "serde_json", "sha2", "sov-modules-core", "sov-rollup-interface", - "sov-zk-cycle-macros", - "thiserror", ] [[package]] @@ -2863,15 +2853,6 @@ dependencies = [ "sov-rollup-interface", ] -[[package]] -name = "sov-zk-cycle-macros" -version = "0.5.0-rc.1" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "spin" version = "0.9.8" diff --git a/bin/citrea/provers/risc0/batch-prover-mock/Cargo.toml b/bin/citrea/provers/risc0/batch-prover-mock/Cargo.toml index 1e68f0476..f8bf43468 100644 --- a/bin/citrea/provers/risc0/batch-prover-mock/Cargo.toml +++ b/bin/citrea/provers/risc0/batch-prover-mock/Cargo.toml @@ -30,10 +30,3 @@ debug = 0 lto = true opt-level = 3 codegen-units = 1 - -[features] -bench = [ - "sov-modules-api/bench", - "sov-state/bench", - "sov-modules-stf-blueprint/bench", -] diff --git a/bin/citrea/provers/risc0/batch-prover-mock/src/bin/batch_prover_mock.rs b/bin/citrea/provers/risc0/batch-prover-mock/src/bin/batch_prover_mock.rs index 40d0115f3..27a04c479 100644 --- a/bin/citrea/provers/risc0/batch-prover-mock/src/bin/batch_prover_mock.rs +++ b/bin/citrea/provers/risc0/batch-prover-mock/src/bin/batch_prover_mock.rs @@ -1,38 +1,17 @@ #![no_main] use citrea_stf::runtime::Runtime; use citrea_stf::StfVerifier; -#[cfg(feature = "bench")] -use risc0_zkvm::guest::env; use sov_mock_da::MockDaVerifier; use sov_modules_api::default_context::ZkDefaultContext; use sov_modules_stf_blueprint::StfBlueprint; use sov_risc0_adapter::guest::Risc0Guest; use sov_state::ZkStorage; -#[cfg(feature = "bench")] -fn report_bench_metrics(start_cycles: u64, end_cycles: u64) { - let cycles_per_block = end_cycles - start_cycles; - let tuple = ("Cycles per block".to_string(), cycles_per_block); - let mut serialized = Vec::new(); - serialized.extend(tuple.0.as_bytes()); - serialized.push(0); - let size_bytes = tuple.1.to_ne_bytes(); - serialized.extend(&size_bytes); - - // calculate the syscall name. - let name = c"cycle_metrics"; - let metrics_syscall_name = risc0_zkvm_platform::syscall::SyscallName::from_c_str(name).unwrap(); - - risc0_zkvm::guest::env::send_recv_slice::(metrics_syscall_name, &serialized); -} - risc0_zkvm::guest::entry!(main); pub fn main() { let guest = Risc0Guest::new(); let storage = ZkStorage::new(); - #[cfg(feature = "bench")] - let start_cycles = env::cycle_count(); let stf: StfBlueprint> = StfBlueprint::new(); @@ -41,10 +20,4 @@ pub fn main() { stf_verifier .run_sequencer_commitments_in_da_slot(guest, storage) .expect("Prover must be honest"); - - #[cfg(feature = "bench")] - { - let end_cycles = env::cycle_count(); - report_bench_metrics(start_cycles, end_cycles); - } } diff --git a/bin/citrea/provers/risc0/build.rs b/bin/citrea/provers/risc0/build.rs index 822b1accf..4dc8fba8a 100644 --- a/bin/citrea/provers/risc0/build.rs +++ b/bin/citrea/provers/risc0/build.rs @@ -48,11 +48,8 @@ fn main() { fn get_guest_options() -> HashMap<&'static str, risc0_build::GuestOptions> { let mut guest_pkg_to_options = HashMap::new(); - let mut features = vec![]; + let features = vec![]; - if cfg!(feature = "bench") { - features.push("bench".to_string()); - } let use_docker = if std::env::var("REPR_GUEST_BUILD").is_ok() { let this_package_dir = std::env!("CARGO_MANIFEST_DIR"); let root_dir = format!("{this_package_dir}/../../../../"); diff --git a/bin/citrea/provers/risc0/light-client-prover-bitcoin/Cargo.lock b/bin/citrea/provers/risc0/light-client-prover-bitcoin/Cargo.lock index 0f80440ad..9e4834424 100644 --- a/bin/citrea/provers/risc0/light-client-prover-bitcoin/Cargo.lock +++ b/bin/citrea/provers/risc0/light-client-prover-bitcoin/Cargo.lock @@ -2750,15 +2750,11 @@ dependencies = [ "hex", "itertools 0.13.0", "jmt", - "risc0-zkvm", - "risc0-zkvm-platform", "rs_merkle", "serde", "sov-modules-api", "sov-rollup-interface", "sov-state", - "sov-zk-cycle-macros", - "thiserror", ] [[package]] @@ -2798,26 +2794,11 @@ dependencies = [ "anyhow", "bcs", "borsh", - "hex", "jmt", - "risc0-zkvm", - "risc0-zkvm-platform", "serde", - "serde_json", "sha2", "sov-modules-core", "sov-rollup-interface", - "sov-zk-cycle-macros", - "thiserror", -] - -[[package]] -name = "sov-zk-cycle-macros" -version = "0.5.0-rc.1" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", ] [[package]] diff --git a/bin/citrea/provers/risc0/light-client-prover-bitcoin/Cargo.toml b/bin/citrea/provers/risc0/light-client-prover-bitcoin/Cargo.toml index 041a7da0c..9214f11d7 100644 --- a/bin/citrea/provers/risc0/light-client-prover-bitcoin/Cargo.toml +++ b/bin/citrea/provers/risc0/light-client-prover-bitcoin/Cargo.toml @@ -32,10 +32,3 @@ debug = 0 lto = true opt-level = 3 codegen-units = 1 - -[features] -bench = [ - "sov-modules-api/bench", - "sov-state/bench", - "sov-modules-stf-blueprint/bench", -] diff --git a/bin/citrea/provers/risc0/light-client-prover-bitcoin/src/bin/light_client_prover_bitcoin.rs b/bin/citrea/provers/risc0/light-client-prover-bitcoin/src/bin/light_client_prover_bitcoin.rs index bb8d909cb..fbe5d5ea0 100644 --- a/bin/citrea/provers/risc0/light-client-prover-bitcoin/src/bin/light_client_prover_bitcoin.rs +++ b/bin/citrea/provers/risc0/light-client-prover-bitcoin/src/bin/light_client_prover_bitcoin.rs @@ -4,35 +4,14 @@ use bitcoin_da::verifier::BitcoinVerifier; use citrea_light_client_prover::circuit::run_circuit; use citrea_light_client_prover::input::LightClientCircuitInput; use citrea_primitives::{REVEAL_BATCH_PROOF_PREFIX, REVEAL_LIGHT_CLIENT_PREFIX}; -#[cfg(feature = "bench")] -use risc0_zkvm::guest::env; use sov_risc0_adapter::guest::Risc0Guest; use sov_rollup_interface::da::DaVerifier; use sov_rollup_interface::zk::ZkvmGuest; -#[cfg(feature = "bench")] -fn report_bench_metrics(start_cycles: u64, end_cycles: u64) { - let cycles_per_block = end_cycles - start_cycles; - let tuple = ("Cycles per block".to_string(), cycles_per_block); - let mut serialized = Vec::new(); - serialized.extend(tuple.0.as_bytes()); - serialized.push(0); - let size_bytes = tuple.1.to_ne_bytes(); - serialized.extend(&size_bytes); - - // calculate the syscall name. - let name = c"cycle_metrics"; - let metrics_syscall_name = risc0_zkvm_platform::syscall::SyscallName::from_c_str(name).unwrap(); - - risc0_zkvm::guest::env::send_recv_slice::(metrics_syscall_name, &serialized); -} - risc0_zkvm::guest::entry!(main); pub fn main() { let guest = Risc0Guest::new(); - #[cfg(feature = "bench")] - let start_cycles = env::cycle_count(); let input: LightClientCircuitInput = guest.read_from_host(); @@ -44,10 +23,4 @@ pub fn main() { let output = run_circuit::(input, da_verifier).unwrap(); guest.commit(&output); - - #[cfg(feature = "bench")] - { - let end_cycles = env::cycle_count(); - report_bench_metrics(start_cycles, end_cycles); - } } diff --git a/bin/citrea/provers/risc0/light-client-prover-mock/Cargo.lock b/bin/citrea/provers/risc0/light-client-prover-mock/Cargo.lock index 16f7efa80..ddb7d5ba3 100644 --- a/bin/citrea/provers/risc0/light-client-prover-mock/Cargo.lock +++ b/bin/citrea/provers/risc0/light-client-prover-mock/Cargo.lock @@ -2538,15 +2538,11 @@ dependencies = [ "hex", "itertools 0.13.0", "jmt", - "risc0-zkvm", - "risc0-zkvm-platform", "rs_merkle", "serde", "sov-modules-api", "sov-rollup-interface", "sov-state", - "sov-zk-cycle-macros", - "thiserror", ] [[package]] @@ -2586,26 +2582,11 @@ dependencies = [ "anyhow", "bcs", "borsh", - "hex", "jmt", - "risc0-zkvm", - "risc0-zkvm-platform", "serde", - "serde_json", "sha2", "sov-modules-core", "sov-rollup-interface", - "sov-zk-cycle-macros", - "thiserror", -] - -[[package]] -name = "sov-zk-cycle-macros" -version = "0.5.0-rc.1" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", ] [[package]] diff --git a/bin/citrea/provers/risc0/light-client-prover-mock/Cargo.toml b/bin/citrea/provers/risc0/light-client-prover-mock/Cargo.toml index dbb3f634e..f216360d0 100644 --- a/bin/citrea/provers/risc0/light-client-prover-mock/Cargo.toml +++ b/bin/citrea/provers/risc0/light-client-prover-mock/Cargo.toml @@ -32,10 +32,3 @@ debug = 0 lto = true opt-level = 3 codegen-units = 1 - -[features] -bench = [ - "sov-modules-api/bench", - "sov-state/bench", - "sov-modules-stf-blueprint/bench", -] diff --git a/bin/citrea/provers/risc0/light-client-prover-mock/src/bin/light_client_prover_mock.rs b/bin/citrea/provers/risc0/light-client-prover-mock/src/bin/light_client_prover_mock.rs index caa293f74..b551d6d34 100644 --- a/bin/citrea/provers/risc0/light-client-prover-mock/src/bin/light_client_prover_mock.rs +++ b/bin/citrea/provers/risc0/light-client-prover-mock/src/bin/light_client_prover_mock.rs @@ -1,35 +1,14 @@ #![no_main] use citrea_light_client_prover::circuit::run_circuit; use citrea_light_client_prover::input::LightClientCircuitInput; -#[cfg(feature = "bench")] -use risc0_zkvm::guest::env; use sov_mock_da::{MockDaSpec, MockDaVerifier}; use sov_risc0_adapter::guest::Risc0Guest; use sov_rollup_interface::zk::ZkvmGuest; -#[cfg(feature = "bench")] -fn report_bench_metrics(start_cycles: u64, end_cycles: u64) { - let cycles_per_block = end_cycles - start_cycles; - let tuple = ("Cycles per block".to_string(), cycles_per_block); - let mut serialized = Vec::new(); - serialized.extend(tuple.0.as_bytes()); - serialized.push(0); - let size_bytes = tuple.1.to_ne_bytes(); - serialized.extend(&size_bytes); - - // calculate the syscall name. - let name = c"cycle_metrics"; - let metrics_syscall_name = risc0_zkvm_platform::syscall::SyscallName::from_c_str(name).unwrap(); - - risc0_zkvm::guest::env::send_recv_slice::(metrics_syscall_name, &serialized); -} - risc0_zkvm::guest::entry!(main); pub fn main() { let guest = Risc0Guest::new(); - #[cfg(feature = "bench")] - let start_cycles = env::cycle_count(); let input: LightClientCircuitInput = guest.read_from_host(); @@ -38,10 +17,4 @@ pub fn main() { let output = run_circuit::(input, da_verifier).unwrap(); guest.commit(&output); - - #[cfg(feature = "bench")] - { - let end_cycles = env::cycle_count(); - report_bench_metrics(start_cycles, end_cycles); - } } diff --git a/crates/sovereign-sdk/docker/DEMO.md b/crates/sovereign-sdk/docker/DEMO.md deleted file mode 100644 index a7d52222c..000000000 --- a/crates/sovereign-sdk/docker/DEMO.md +++ /dev/null @@ -1,15 +0,0 @@ - - -```bash -# Sent to node 2, should fail -target/debug/sov-cli submit-transaction examples/test-data/keys/token_deployer_private_key.json Bank examples/test-data/requests/create_token.json 0 http://127.0.0.1:12346 -target/debug/sov-cli publish-batch http://127.0.0.1:12346 - -# Registering second sequencer -target/debug/sov-cli submit-transaction examples/test-data/keys/token_deployer_private_key.json SequencerRegistry examples/test-data/requests/register_sequencer.json 0 http://127.0.0.1:12345 -target/debug/sov-cli publish-batch http://127.0.0.1:12345 - -# Try on second sequencer again -target/debug/sov-cli submit-transaction examples/test-data/keys/token_deployer_private_key.json Bank examples/test-data/requests/transfer.json 1 http://127.0.0.1:12346 -target/debug/sov-cli publish-batch http://127.0.0.1:12346 -``` \ No newline at end of file diff --git a/crates/sovereign-sdk/docker/Dockerfile.bridge b/crates/sovereign-sdk/docker/Dockerfile.bridge deleted file mode 100644 index 463e0ab81..000000000 --- a/crates/sovereign-sdk/docker/Dockerfile.bridge +++ /dev/null @@ -1,18 +0,0 @@ -# A dockerfile for the celestia bridge node in DA layer -# Based on: -# https://github.com/celestiaorg/celestia-node/blob/main/Dockerfile -FROM docker.io/alpine:3.18.3 - -ENV CELESTIA_HOME=/root - -RUN apk update && apk add --no-cache bash jq - -# Copy in the binary -COPY --from=ghcr.io/celestiaorg/celestia-node:v0.12.0 /bin/celestia /bin/celestia -COPY --from=ghcr.io/celestiaorg/celestia-node:v0.12.0 /bin/cel-key /bin/cel-key - -COPY ./run-bridge.sh /opt/entrypoint.sh - -EXPOSE 2121 26658 - -CMD /opt/entrypoint.sh diff --git a/crates/sovereign-sdk/docker/Dockerfile.validator b/crates/sovereign-sdk/docker/Dockerfile.validator deleted file mode 100644 index 7ef44edd0..000000000 --- a/crates/sovereign-sdk/docker/Dockerfile.validator +++ /dev/null @@ -1,18 +0,0 @@ -# A dockerfile for the celestia validator in consensus layer -# Based on: -# https://github.com/celestiaorg/celestia-app/blob/main/Dockerfile -FROM docker.io/alpine:3.18.3 - -ENV CELESTIA_HOME=/root - -RUN apk update && apk add --no-cache bash jq - -# Copy in the binary -COPY --from=ghcr.io/celestiaorg/celestia-app:v1.3.0 /bin/celestia-appd /bin/celestia-appd - -COPY ./run-validator.sh /opt/entrypoint.sh - -# p2p, rpc and prometheus port -EXPOSE 26656 26657 1317 9090 - -CMD /opt/entrypoint.sh diff --git a/crates/sovereign-sdk/docker/Makefile b/crates/sovereign-sdk/docker/Makefile deleted file mode 100644 index 48dd59754..000000000 --- a/crates/sovereign-sdk/docker/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -PROJECT_ROOT := $(shell git rev-parse --show-toplevel) -DOCKER_COMPOSE_DIR := $(PROJECT_ROOT)/docker -DOCKER_COMPOSE_CFG := $(DOCKER_COMPOSE_DIR)/docker-compose.yml -CREDENTIALS_DIR := $(PROJECT_ROOT)/examples/celestia-docker/credentials - -docker_compose := docker compose -f $(DOCKER_COMPOSE_CFG) - -up: - @echo "Starting services" - @$(docker_compose) up -d --build --force-recreate - @echo "Waiting for services to finish setup" - @$(docker_compose) logs -f | awk '/Provisioning finished./ {print;exit}' # exit when encounter this log entry - -down: - @echo "Shutting down services" - @$(docker_compose) down - @echo "Removing generated configs" - @rm rollup_config_*.toml - -# wait for the celestia network to perform setup and coins transfers -wait-compose-ready: - @echo "Waiting for services to finish setup" - @$(compose_logs) | awk '/Provisioning finished./ {print;exit}' # exit when encounter this log entry - -restart: down up generate_configs - -generate_configs: wait-compose-ready - @$(DOCKER_COMPOSE_DIR)/generate_configs.sh - -logs: - @$(docker_compose) logs -f diff --git a/crates/sovereign-sdk/docker/README.md b/crates/sovereign-sdk/docker/README.md deleted file mode 100644 index 3c167caed..000000000 --- a/crates/sovereign-sdk/docker/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# Local celestia setup - -It consists of one validator (block maker) and arbitrary number of bridge nodes -for sequencers (1 by default). - -## Example - -```sh -# start the celestia network -docker compose -f docker/docker-compose.yml up --build --force-recreate -d - -# grab the jwt -CELESTIA_NODE_AUTH_TOKEN="$(cat docker/credentials/bridge-0.jwt)" - -# check the celestia rpc -curl -X POST \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer ${CELESTIA_NODE_AUTH_TOKEN}" \ - -d '{ - "id": 1, - "jsonrpc": "2.0", - "method": "header.GetByHeight", - "params": [2] - }' \ - localhost:26658 - -# stop the celestia network -docker compose -f docker/docker-compose.yml down -``` - -### Login to github registry - -You'll need to be logged in to the github's registry in order to pull celestia images. -Follow [this guide](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#authenticating-with-a-personal-access-token-classic) -to authorize yourself in github's container registry. (we use original celestia images which they publish in ghcr) - -```shell -# this has to be ran only once, unless your token expires -$ echo $MY_PERSONAL_GITHUB_TOKEN | docker login ghcr.io -u $MY_GITHUB_USERNAME --password-stdin -``` - -## Multiple sequencers - -To have multiple sequencers, a few conditions needs to be met: -- validator must know the number of sequencers to provision them with accounts and coins -- each sequencer must have a unique id and each id has to be a consecutive natural number - starting from 0. (eg. 0, 1, 2) -- each sequencer other than the first one has to have the ports remapped so they don't conflict - with other sequencers - -The `docker-compose.yml` has a commented out example setup for the second sequencer. It can -be copy-pasted and adjusted for an arbitrary number of sequencers. The amount of sequencers -needs to be provided by uncommenting and aligning the `services.validator.command` field. - -## Credentials - -Credentials for each new sequencer are created by validator on the first startup. The validator writes -the keys and address of each sequencer to the `docker/credentials` volume. Each consecutive -run will use the same credentials until the directory is manually cleaned up. - -In addition, each sequencer on startup will write it's `JWT` token to the same directory. The token is -updated during consecutive runs. diff --git a/crates/sovereign-sdk/docker/credentials/bridge-0.addr b/crates/sovereign-sdk/docker/credentials/bridge-0.addr deleted file mode 100644 index 251e6a8cf..000000000 --- a/crates/sovereign-sdk/docker/credentials/bridge-0.addr +++ /dev/null @@ -1 +0,0 @@ -celestia1a68m2l85zn5xh0l07clk4rfvnezhywc53g8x7s diff --git a/crates/sovereign-sdk/docker/credentials/bridge-0.key b/crates/sovereign-sdk/docker/credentials/bridge-0.key deleted file mode 100644 index fda19e624..000000000 --- a/crates/sovereign-sdk/docker/credentials/bridge-0.key +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN TENDERMINT PRIVATE KEY----- -kdf: bcrypt -salt: 68B0092F4FC5386C20DA96ECEE1BFE09 -type: secp256k1 - -JEOTdvPjs/4G+Jhz0hyNgdN5CgOCCcf5zvECY6zp+AN6IT6rTW0xbGqgFqbX6Yyi -NUV8e1fo9zhoytjrHjcCgHRnGiBGFQf1Ld4sBzE= -=TmEg ------END TENDERMINT PRIVATE KEY----- diff --git a/crates/sovereign-sdk/docker/docker-compose.yml b/crates/sovereign-sdk/docker/docker-compose.yml deleted file mode 100644 index b03da1809..000000000 --- a/crates/sovereign-sdk/docker/docker-compose.yml +++ /dev/null @@ -1,54 +0,0 @@ -services: - validator: - image: validator - build: - context: . - dockerfile: Dockerfile.validator - # uncomment to provide amount of sequencers to provision (default: 1) - # command: ["/opt/entrypoint.sh", "2"] - volumes: - - credentials:/credentials - - genesis:/genesis - - sequencer-0: - image: bridge - build: - context: . - dockerfile: Dockerfile.bridge - # uncomment to provide the id of the sequencer (default: 0) - # command: ["/opt/entrypoint.sh", "0"] - ports: - - 26658:26658 - volumes: - - credentials:/credentials - - genesis:/genesis - - # Uncomment for another sequencer - # remember to adjust services.validator.command - # sequencer-1: - # image: bridge - # build: - # context: . - # dockerfile: Dockerfile.bridge - # # uncomment to provide the id of the sequencer (default: 0) - # command: ["/opt/entrypoint.sh", "1"] - # ports: - # # remap the default port as it's already used - # - 36658:26658 - # volumes: - # - credentials:/credentials - # - genesis:/genesis - -volumes: - # local volume where sequencer's credentials can persist - credentials: - driver: local - driver_opts: - type: 'none' - o: 'bind' - device: './credentials' - # a temporary fs where the genesis hash is announced - genesis: - driver_opts: - type: tmpfs - device: tmpfs diff --git a/crates/sovereign-sdk/docker/generate_configs.sh b/crates/sovereign-sdk/docker/generate_configs.sh deleted file mode 100755 index 1f4944653..000000000 --- a/crates/sovereign-sdk/docker/generate_configs.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/bash - -# be strict -set -euo pipefail - -PROJECT_DIR="$(git rev-parse --show-toplevel)" -DOCKER_DIR="$PROJECT_DIR/docker" -CREDENTIALS_DIR="$DOCKER_DIR/credentials" -DOCKER_COMPOSE_CFG="$DOCKER_DIR/docker-compose.yml" -CONFIG_TEMPLATE="$DOCKER_DIR/template.toml" -CELESTIA_RPC_PORT=26658 - -# get amount of running sequencers -sequencers_running() { - docker compose -f "$DOCKER_COMPOSE_CFG" config --services | grep -c sequencer -} - -# get the jwt for given sequencer -sequencer_jwt() { - local sequencer_id="${1}" - - cat "$CREDENTIALS_DIR/bridge-${sequencer_id}.jwt" -} - -# get the rpc port the sequencer's celestia node listens on -sequencer_rpc_port() { - local sequencer_id="${1}" - - docker compose -f "$DOCKER_COMPOSE_CFG" port "sequencer-${sequencer_id}" "$CELESTIA_RPC_PORT" -} - -# create a new rollup config with given id -create_rollup_config() { - local id="${1}" - local address - local jwt - - jwt="$(sequencer_jwt "$id")" - address="http://127.0.0.1:$(sequencer_rpc_port "$id")" - storage_path="demo_data_$id" - bind_port="1234${id}" - target_file="rollup_config_${id}.toml" - - # use '|' in sed as the url has '/' - sed \ - -e "s||$jwt|" \ - -e "s|
|$address|" \ - -e "s||$storage_path|" \ - -e "s|12345|$bind_port|" \ - "$CONFIG_TEMPLATE" > "$target_file" -} - -main() { - local amount - local last_idx - - # get amount of running sequencers - amount="$(sequencers_running)" - last_idx=$((amount - 1)) - - # create the config for each rollup - for id in $(seq 0 $last_idx); do - create_rollup_config "$id" - done -} - -main diff --git a/crates/sovereign-sdk/docker/rollup_config_0.toml b/crates/sovereign-sdk/docker/rollup_config_0.toml deleted file mode 100644 index 33d79a284..000000000 --- a/crates/sovereign-sdk/docker/rollup_config_0.toml +++ /dev/null @@ -1,15 +0,0 @@ -[da] -celestia_rpc_auth_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJBbGxvdyI6WyJwdWJsaWMiLCJyZWFkIiwid3JpdGUiLCJhZG1pbiJdfQ.Ie5-ulwuVPjzs6ahngRXunEsU4oLV46-AYfbJLz94Pw" -celestia_rpc_address = "http://127.0.0.1:0.0.0.0:26658" -max_celestia_response_body_size = 104_857_600 -celestia_rpc_timeout_seconds = 60 - -[storage] -path = "demo_data_0" - -[runner] -start_height = 1 - -[runner.rpc_config] -bind_host = "127.0.0.1" -bind_port = 12340 diff --git a/crates/sovereign-sdk/docker/run-bridge.sh b/crates/sovereign-sdk/docker/run-bridge.sh deleted file mode 100755 index e493fe42c..000000000 --- a/crates/sovereign-sdk/docker/run-bridge.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash - -# be strict -set -euo pipefail - -# Name for this node, with suffix taken from the first argument -# or `bridge-0` if not provided -NODE_NAME="bridge-${1:-0}" -# a private local network -P2P_NETWORK="private" -# a bridge node configuration directory -CONFIG_DIR="$CELESTIA_HOME/.celestia-bridge-$P2P_NETWORK" -# directory and the files shared with the validator node -CREDENTIALS_DIR="/credentials" -# node credentials -NODE_KEY_FILE="$CREDENTIALS_DIR/$NODE_NAME.key" -NODE_JWT_FILE="$CREDENTIALS_DIR/$NODE_NAME.jwt" -# directory where validator will write the genesis hash -GENESIS_DIR="/genesis" -GENESIS_HASH_FILE="$GENESIS_DIR/genesis_hash" - -# Wait for the validator to set up and provision us via shared dirs -wait_for_provision() { - echo "Waiting for the validator node to start" - while [[ ! ( -e "$GENESIS_HASH_FILE" && -e "$NODE_KEY_FILE" ) ]]; do - sleep 0.5 - done - - sleep 1 # let the validator finish setup - echo "Validator is ready" -} - -# Import the test account key shared by the validator -import_shared_key() { - echo "password" | cel-key import "$NODE_NAME" "$NODE_KEY_FILE" \ - --keyring-backend="test" \ - --p2p.network "$P2P_NETWORK" \ - --node.type bridge -} - -add_trusted_genesis() { - local genesis_hash - - # Read the hash of the genesis block - genesis_hash="$(cat "$GENESIS_HASH_FILE")" - # and make it trusted in the node's config - echo "Trusting a genesis: $genesis_hash" - sed -i'.bak' "s/TrustedHash = .*/TrustedHash = $genesis_hash/" "$CONFIG_DIR/config.toml" -} - -write_jwt_token() { - echo "Saving jwt token to $NODE_JWT_FILE" - celestia bridge auth admin --p2p.network "$P2P_NETWORK" > "$NODE_JWT_FILE" -} - -main() { - # Wait for a validator - wait_for_provision - # Import the key with the coins - import_shared_key - # Initialize the bridge node - celestia bridge init --p2p.network "$P2P_NETWORK" - # Trust the private blockchain - add_trusted_genesis - # Update the JWT token - write_jwt_token - # Start the bridge node - echo "Configuration finished. Running a bridge node..." - celestia bridge start \ - --core.ip validator \ - --keyring.accname "$NODE_NAME" \ - --p2p.network "$P2P_NETWORK" -} - -main diff --git a/crates/sovereign-sdk/docker/run-validator.sh b/crates/sovereign-sdk/docker/run-validator.sh deleted file mode 100755 index ae789a0fc..000000000 --- a/crates/sovereign-sdk/docker/run-validator.sh +++ /dev/null @@ -1,165 +0,0 @@ -#!/bin/bash - -# be strict -set -euo pipefail - -# Amount of bridge nodes to setup, taken from the first argument -# or 1 if not provided -BRIDGE_COUNT="${1:-1}" -# a private local network -P2P_NETWORK="private" -# a validator node configuration directory -CONFIG_DIR="$CELESTIA_HOME/.celestia-app" -# the names of the keys -NODE_NAME=validator-0 -# amounts of the coins for the keys -BRIDGE_COINS="200000000000000utia" -VALIDATOR_COINS="1000000000000000utia" -# a directory and the files shared with the bridge nodes -CREDENTIALS_DIR="/credentials" -# directory where validator will write the genesis hash -GENESIS_DIR="/genesis" -GENESIS_HASH_FILE="$GENESIS_DIR/genesis_hash" - -# Get the address of the node of given name -node_address() { - local node_name="$1" - local node_address - - node_address=$(celestia-appd keys show "$node_name" -a --keyring-backend="test") - echo "$node_address" -} - -# Waits for the given block to be created and returns it's hash -wait_for_block() { - local block_num="$1" - local block_hash="" - - # Wait for the block to be created - while [[ -z "$block_hash" ]]; do - # `|| echo` fallbacks to an empty string in case it's not ready - block_hash="$(celestia-appd query block "$block_num" 2>/dev/null | jq '.block_id.hash' || echo)" - sleep 0.5 - done - - echo "$block_hash" -} - -# Saves the hash of the genesis node and the keys funded with the coins -# to the directory shared with the bridge node -provision_bridge_nodes() { - local genesis_hash - local last_node_idx=$((BRIDGE_COUNT - 1)) - - # Save the genesis hash for the bridge - genesis_hash=$(wait_for_block 1) - echo "Saving a genesis hash to $GENESIS_HASH_FILE" - echo "$genesis_hash" > "$GENESIS_HASH_FILE" - - # Get or create the keys for bridge nodes - for node_idx in $(seq 0 "$last_node_idx"); do - local bridge_name="bridge-$node_idx" - local key_file="$CREDENTIALS_DIR/$bridge_name.key" - local addr_file="$CREDENTIALS_DIR/$bridge_name.addr" - - if [ ! -e "$key_file" ]; then - # if key don't exist yet, then create and export it - # create a new key - echo "Creating a new keys for the $bridge_name" - celestia-appd keys add "$bridge_name" --keyring-backend "test" - # export it - echo "password" | celestia-appd keys export "$bridge_name" 2> "$key_file" - # export associated address - node_address "$bridge_name" > "$addr_file" - else - # otherwise, just import it - echo "password" | celestia-appd keys import "$bridge_name" "$key_file" \ - --keyring-backend="test" - fi - done - - # Transfer the coins to bridge nodes addresses - # Coins transfer need to be after validator registers EVM address, which happens in block 2. - # see `setup_private_validator` - local start_block=2 - - for node_idx in $(seq 0 "$last_node_idx"); do - # TODO: - # we need to transfer the coins for each node in separate - # block, or the signing of all but the first one will fail. - # Unfortunately multi-send only works with >= 2 bridge nodes, - # so we still rely on this hack. - wait_for_block $((start_block + node_idx)) - - local bridge_name="bridge-$node_idx" - local bridge_address - - bridge_address=$(node_address "$bridge_name") - - echo "Transferring $BRIDGE_COINS coins to the $bridge_name" - echo "y" | celestia-appd tx bank send \ - "$NODE_NAME" \ - "$bridge_address" \ - "$BRIDGE_COINS" \ - --fees 21000utia - done - - # !! This is the last log entry that indicates the setup has finished for all the nodes - echo "Provisioning finished." -} - -# Set up the validator for a private alone network. -# Based on -# https://github.com/celestiaorg/celestia-app/blob/main/scripts/single-node.sh -setup_private_validator() { - local validator_addr - - # Initialize the validator - celestia-appd init "$P2P_NETWORK" --chain-id "$P2P_NETWORK" - # Derive a new private key for the validator - celestia-appd keys add "$NODE_NAME" --keyring-backend="test" - validator_addr=$(node_address "$NODE_NAME") - # Create a validator's genesis account for the genesis.json with an initial bag of coins - celestia-appd add-genesis-account "$validator_addr" "$VALIDATOR_COINS" - # Generate a genesis transaction that creates a validator with a self-delegation - celestia-appd gentx "$NODE_NAME" 5000000000utia \ - --keyring-backend="test" \ - --chain-id "$P2P_NETWORK" - # Collect the genesis transactions and form a genesis.json - celestia-appd collect-gentxs - - # Set proper defaults and change ports - # If you encounter: `sed: -I or -i may not be used with stdin` on MacOS you can mitigate by installing gnu-sed - # https://gist.github.com/andre3k1/e3a1a7133fded5de5a9ee99c87c6fa0d?permalink_comment_id=3082272#gistcomment-3082272 - sed -i'.bak' 's|"tcp://127.0.0.1:26657"|"tcp://0.0.0.0:26657"|g' "$CONFIG_DIR/config/config.toml" - sed -i'.bak' 's|"null"|"kv"|g' "$CONFIG_DIR/config/config.toml" - - # Register the validator EVM address in background - { - # wait for the genesis - wait_for_block 1 - - # private key: da6ed55cb2894ac2c9c10209c09de8e8b9d109b910338d5bf3d747a7e1fc9eb9 - celestia-appd tx qgb register \ - "$(celestia-appd keys show "$NODE_NAME" --bech val -a)" \ - 0x966e6f22781EF6a6A82BBB4DB3df8E225DfD9488 \ - --from "$NODE_NAME" \ - --fees 30000utia \ - -b block \ - -y - - echo "Registered validator's EVM address" - } & -} - -main() { - # Configure stuff - setup_private_validator - # Spawn a job to provision a bridge node later - provision_bridge_nodes & - # Start the celestia-app - echo "Configuration finished. Running a validator node..." - celestia-appd start --api.enable --grpc.enable -} - -main diff --git a/crates/sovereign-sdk/docker/template.toml b/crates/sovereign-sdk/docker/template.toml deleted file mode 100644 index ed2b70ca9..000000000 --- a/crates/sovereign-sdk/docker/template.toml +++ /dev/null @@ -1,15 +0,0 @@ -[da] -celestia_rpc_auth_token = "" -celestia_rpc_address = "
" -max_celestia_response_body_size = 104_857_600 -celestia_rpc_timeout_seconds = 60 - -[storage] -path = "" - -[runner] -start_height = 3 - -[runner.rpc_config] -bind_host = "127.0.0.1" -bind_port = 12345 diff --git a/crates/sovereign-sdk/examples/const-rollup-config/Cargo.toml b/crates/sovereign-sdk/examples/const-rollup-config/Cargo.toml deleted file mode 100644 index 75e64e279..000000000 --- a/crates/sovereign-sdk/examples/const-rollup-config/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "const-rollup-config" -version = { workspace = true } -edition = { workspace = true } -authors = { workspace = true } -license = { workspace = true } -homepage = "sovereign.xyz" -publish = false diff --git a/crates/sovereign-sdk/examples/const-rollup-config/README.md b/crates/sovereign-sdk/examples/const-rollup-config/README.md deleted file mode 100644 index 5fe52531d..000000000 --- a/crates/sovereign-sdk/examples/const-rollup-config/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Const Rollup Config - -In Sovereign, many state transition functions require consensus critical configuration. For example, rollups on Celestia -need to configure a namespace which they check for data. This consensus critical configuration needs to be available -to packages at compile time, so that it is baked into the binary which is fed to the zkVM. Otherwise, a malicious -prover might be able to overwrite this configuration at runtime and create valid-looking proofs that were run -over the wrong namespace. - -This package demonstrates how you can accomplish such configuration. You can see its usage in the [`main` function of demo-rollup](../demo-rollup/src/main.rs). diff --git a/crates/sovereign-sdk/examples/const-rollup-config/src/lib.rs b/crates/sovereign-sdk/examples/const-rollup-config/src/lib.rs deleted file mode 100644 index 4b13774f2..000000000 --- a/crates/sovereign-sdk/examples/const-rollup-config/src/lib.rs +++ /dev/null @@ -1,19 +0,0 @@ -pub const ROLLUP_NAME: &str = "chainway"; -pub const TEST_PRIVATE_KEY: &str = - "1212121212121212121212121212121212121212121212121212121212121212"; - -pub const SEQUENCER_DA_ADDRESS: [u8; 33] = [ - 2, 88, 141, 32, 42, 252, 193, 238, 74, 181, 37, 76, 120, 71, 236, 37, 185, 161, 53, 187, 218, - 15, 43, 198, 158, 225, 167, 20, 116, 159, 215, 125, 201, -]; - -/// The namespace used by the rollup to store its data. This is a raw slice of 8 bytes. -/// The rollup stores its data in the namespace b"sov-test" on Celestia. Which in this case is encoded using the -/// ascii representation of each character. -pub const ROLLUP_BATCH_NAMESPACE_RAW: [u8; 10] = [0, 0, 115, 111, 118, 45, 116, 101, 115, 116]; - -/// The namespace used by the rollup to store aggregated ZK proofs. -pub const ROLLUP_PROOF_NAMESPACE_RAW: [u8; 10] = [115, 111, 118, 45, 116, 101, 115, 116, 45, 112]; - -/// Leading zeros prefix for the reveal transaction id. -pub const DA_TX_ID_LEADING_ZEROS: &[u8] = [0, 0].as_slice(); diff --git a/crates/sovereign-sdk/examples/demo-simple-stf/Cargo.toml b/crates/sovereign-sdk/examples/demo-simple-stf/Cargo.toml deleted file mode 100644 index 62c3a1bdf..000000000 --- a/crates/sovereign-sdk/examples/demo-simple-stf/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "demo-simple-stf" -version = { workspace = true } -edition = { workspace = true } -resolver = "2" -authors = { workspace = true } -license = { workspace = true } -homepage = "sovereign.xyz" -publish = false - -[dependencies] -anyhow = { workspace = true } -serde = { workspace = true } -sha2 = { workspace = true } -hex = { workspace = true } - -sov-rollup-interface = { path = "../../rollup-interface" } - -[dev-dependencies] -sov-mock-da = { path = "../../adapters/mock-da" } -sov-mock-zkvm = { path = "../../adapters/mock-zkvm" } diff --git a/crates/sovereign-sdk/examples/demo-simple-stf/README.md b/crates/sovereign-sdk/examples/demo-simple-stf/README.md deleted file mode 100644 index b43b26603..000000000 --- a/crates/sovereign-sdk/examples/demo-simple-stf/README.md +++ /dev/null @@ -1,199 +0,0 @@ -# How to Create a Rollup from Scratch - -Many rollups have concepts like `Account` or `Token` and access the state in a similar manner. This is where the [sov-modules-api](../../module-system/sov-modules-api/README.md) becomes useful. It offers a standardized approach to writing rollup business logic. However, there are cases where your rollup requirements may be so unique that the `module-system` could become a hindrance. In this tutorial, we will bypass the `module-system` and directly create a simple rollup by implementing a `StateTransitionFunction` "from scratch". - -In this tutorial, we’ll build an STF which checks if the input data (called a preimage) results in a specific output (called a digest) when fed through a hash function. It's important to note that our rollup is designed to be "stateless," meaning that implementing state access is not covered in this tutorial. However, if you're interested, you can refer to the [sov-state](../../module-system/sov-state/README.md) for an example of how it can be done. - -## Implementing the State Transition Function - -The [State Transition Function -interface](../../rollup-interface/specs/interfaces/stf.md) serves as the core component of our rollup, where the business logic will reside. -Implementations of this trait can be integrated with any zkVM and DA Layer resulting in a fully functional rollup. To begin, we will create a structure called `CheckHashPreimageStf`, and implement the `StateTransitionFunction` trait for it. You can find the complete code in the `lib.rs` file, but we will go over the most important parts here: - -```rust, ignore -pub struct CheckHashPreimageStf {} -``` - -The `ApplyBlobResult` represents the outcome of the state transition, and its specific usage will be explained later: - -```rust, ignore -#[derive(serde::Serialize, serde::Deserialize, Clone)] -pub enum ApplyBlobResult { - Failure, - Success, -} -``` - -Now let's discuss the implementation. First, we define some types that are relevant to our rollup: - -```rust, ignore -impl StateTransitionFunction for CheckHashPreimageStf { - // Since our rollup is stateless, we don't need to consider the StateRoot. - type StateRoot = (); - - // This represents the initial configuration of the rollup, but it is not supported in this tutorial. - type InitialState = (); - - // We could incorporate the concept of a transaction into the rollup, but we leave it as an - // exercise for the reader. - type TxReceiptContents = (); - - // This is the type that will be returned as a result of `apply_blob`. - type BatchReceiptContents = ApplyBlobResult; - - // This data is produced during actual batch execution or validated with proof during verification. - // However, in this tutorial, we won't use it. - type Witness = (); - - // This represents a proof of misbehavior by the sequencer, but we won't utilize it in this tutorial. - type MisbehaviorProof = (); -} -``` - -Now that we have defined the necessary types, we need to implement the following functions: - -```rust, ignore - // Perform one-time initialization for the genesis block. - fn init_chain(&mut self, _params: Self::InitialState) { - // Do nothing - } - - // Called at the beginning of each DA-layer block - whether or not that block contains any - // data relevant to the rollup. - fn begin_slot(&mut self, _witness: Self::Witness) { - // Do nothing - } -``` - -These functions handle the initialization and preparation stages of our rollup, but as we are not modifying the rollup state, their implementation is simply left empty. - -Next we need to write the core logic in `apply_slot`: - -```rust, ignore - // The core logic of our rollup. - fn apply_slot<'a, I>( - &mut self, - _witness: Self::Witness, - blobs: I, - ) -> SlotResult< - Self::StateRoot, - Self::BatchReceiptContents, - Self::TxReceiptContents, - Self::Witness, - > - where - I: IntoIterator, - { - let mut receipts = vec![]; - for blob in blobs { - let blob_data = blob.data_mut(); - - // Read the data from the blob as a byte vec. - let mut data = Vec::new(); - - // Panicking within the `StateTransitionFunction` is generally not recommended. - // But here, if we encounter an error while reading the bytes, - // it suggests a serious issue with the DA layer or our setup. - blob_data - .read_to_end(&mut data) - .unwrap_or_else(|e| panic!("Unable to read blob data {}", e)); - - // Check if the sender submitted the preimage of the hash. - let hash = sha2::Sha256::digest(&data).into(); - let desired_hash = [ - 102, 104, 122, 173, 248, 98, 189, 119, 108, 143, 193, 139, 142, 159, 142, 32, 8, - 151, 20, 133, 110, 226, 51, 179, 144, 42, 89, 29, 13, 95, 41, 37, - ]; - - let result = if hash == desired_hash { - ApplySlotResult::Success - } else { - ApplySlotResult::Failure - }; - - // Return the `BatchReceipt` - receipts.push(BatchReceipt { - batch_hash: hash, - tx_receipts: vec![], - inner: result, - }); - } - - SlotResult { - state_root: (), - batch_receipts: receipts, - witness: (), - } - } -``` - -The above function reads the data from the blob, computes the `hash`, compares it with the `desired_hash`, and returns a `BatchReceipt` indicating whether the preimage was successfully submitted or not. - -The last method is `end_slot`, like before the implementation is trivial: - -```rust, ignore - fn end_slot( - &mut self, - ) -> ( - Self::StateRoot, - Self::Witness, - Vec>, - ) { - ((), (), vec![]) - } -``` - -### Exercise - -In the current implementation, every blob contains the data we pass to the hash function. -As an exercise, you can introduce the concept of transactions. In this scenario, -the blob would contain multiple transactions (containing data) that we can loop over to check hash equality. -The first transaction that finds the correct hash would break the loop and return early. - -## Testing - -The `sov-mock-da` and `sov-mock-zkvm` crates provide two utilities that are useful for testing: - -1. The `sov_mock_zkvm::MockZkvm` is an implementation of the `Zkvm` trait that can be used in tests. -2. The `sov_mock_da::MockBlob` is an implementation of the `BlobTransactionTrait` trait that can be used in tests. It accepts an `A: BasicAddress` as a generic parameter. For testing purposes, we use `MockAddress` struct from the same module - -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. - -```no_run -use demo_simple_stf::{ApplySlotResult, CheckHashPreimageStf}; -use sov_mock_da::{MockAddress, MockBlob, MockBlock, MockValidityCond}; -use sov_mock_zkvm::MockZkvm; -use sov_rollup_interface::stf::StateTransitionFunction; - -fn test_stf() { - let address = MockAddress { addr: [1; 32] }; - let preimage = vec![0; 32]; - - let mut test_blob = MockBlob::new(preimage, address, [0; 32]); - // Work around for https://github.com/Sovereign-Labs/sovereign-sdk/issues/1129 - test_blob.data.advance(test_blob.data.total_len()); - let stf = &mut CheckHashPreimageStf::::default(); - StateTransitionFunction::::init_chain(stf, (), ()); - - let data = MockBlock::default(); - let mut blobs = [test_blob]; - - StateTransitionFunction::::init_chain(stf, ()); - - let result = StateTransitionFunction::::apply_slot( - stf, - &[], - (), - (), - &MockBlockHeader::default(), - &MockValidityCond::default(), - &mut blobs, - ); - - assert_eq!(1, result.batch_receipts.len()); - let receipt = result.batch_receipts[0].clone(); - assert_eq!(receipt.inner, ApplySlotResult::Success); -} -``` diff --git a/crates/sovereign-sdk/examples/demo-simple-stf/src/lib.rs b/crates/sovereign-sdk/examples/demo-simple-stf/src/lib.rs deleted file mode 100644 index d0da48466..000000000 --- a/crates/sovereign-sdk/examples/demo-simple-stf/src/lib.rs +++ /dev/null @@ -1,160 +0,0 @@ -#![deny(missing_docs)] -#![doc = include_str!("../README.md")] -use std::marker::PhantomData; - -use sha2::Digest; -use sov_rollup_interface::da::{BlobReaderTrait, DaSpec}; -use sov_rollup_interface::fork::Fork; -use sov_rollup_interface::soft_confirmation::SignedSoftConfirmation; -use sov_rollup_interface::spec::SpecId; -use sov_rollup_interface::stf::{ - BatchReceipt, SlotResult, SoftConfirmationError, SoftConfirmationResult, - StateTransitionFunction, -}; -use sov_rollup_interface::zk::{CumulativeStateDiff, ValidityCondition, Zkvm}; - -/// An implementation of the [`StateTransitionFunction`] -/// that is specifically designed to check if someone knows a preimage of a specific hash. -#[derive(PartialEq, Debug, Clone, Eq, serde::Serialize, serde::Deserialize, Default)] -pub struct CheckHashPreimageStf { - phantom_data: PhantomData, -} - -/// Outcome of the apply_slot method. -#[derive(serde::Serialize, serde::Deserialize, Clone, Debug, PartialEq, Eq)] -pub enum ApplySlotResult { - /// Incorrect hash preimage was posted on the DA. - Failure, - /// Correct hash preimage was posted on the DA. - Success, -} - -impl StateTransitionFunction - for CheckHashPreimageStf -{ - // Since our rollup is stateless, we don't need to consider the StateRoot. - type StateRoot = [u8; 0]; - - // This represents the initial configuration of the rollup, but it is not supported in this tutorial. - type GenesisParams = (); - type PreState = (); - type ChangeSet = (); - - // We could incorporate the concept of a transaction into the rollup, but we leave it as an exercise for the reader. - type TxReceiptContents = (); - - // This is the type that will be returned as a result of `apply_blob`. - type BatchReceiptContents = ApplySlotResult; - - // This data is produced during actual batch execution or validated with proof during verification. - // However, in this tutorial, we won't use it. - type Witness = (); - - type Condition = Cond; - - // Perform one-time initialization for the genesis block. - fn init_chain( - &self, - _base_state: Self::PreState, - _params: Self::GenesisParams, - ) -> ([u8; 0], ()) { - ([], ()) - } - - fn apply_slot<'a, I>( - &self, - _current_spec: SpecId, - _pre_state_root: &[u8; 0], - _base_state: Self::PreState, - _witness: Self::Witness, - _slot_header: &Da::BlockHeader, - _validity_condition: &Da::ValidityCondition, - blobs: I, - ) -> SlotResult< - Self::StateRoot, - Self::ChangeSet, - Self::BatchReceiptContents, - Self::TxReceiptContents, - Self::Witness, - > - where - I: IntoIterator, - { - let mut receipts = vec![]; - for blob in blobs { - let data = blob.verified_data(); - - // Check if the sender submitted the preimage of the hash. - let hash = sha2::Sha256::digest(data).into(); - let prev_hash = sha2::Sha256::digest(data).into(); - let desired_hash = [ - 102, 104, 122, 173, 248, 98, 189, 119, 108, 143, 193, 139, 142, 159, 142, 32, 8, - 151, 20, 133, 110, 226, 51, 179, 144, 42, 89, 29, 13, 95, 41, 37, - ]; - - let _result = if hash == desired_hash { - ApplySlotResult::Success - } else { - ApplySlotResult::Failure - }; - - // Return the `BatchReceipt` - receipts.push(BatchReceipt:: { - hash, - prev_hash, - tx_receipts: vec![], - phantom_data: PhantomData, - }); - } - - SlotResult { - state_root: [], - change_set: (), - batch_receipts: receipts, - witness: (), - state_diff: vec![], - } - } - - fn apply_soft_confirmation( - &mut self, - _current_spec: SpecId, - _sequencer_public_key: &[u8], - _pre_state_root: &Self::StateRoot, - _pre_state: Self::PreState, - _witness: Self::Witness, - _slot_header: &::BlockHeader, - _validity_condition: &::ValidityCondition, - _soft_confirmation: &mut SignedSoftConfirmation, - ) -> Result< - SoftConfirmationResult< - Self::StateRoot, - Self::ChangeSet, - Self::TxReceiptContents, - Self::Witness, - Da, - >, - SoftConfirmationError, - > { - todo!() - } - - fn apply_soft_confirmations_from_sequencer_commitments( - &mut self, - _sequencer_public_key: &[u8], - _sequencer_da_public_key: &[u8], - _initial_state_root: &Self::StateRoot, - _initial_batch_hash: [u8; 32], - _pre_state: Self::PreState, - _da_data: Vec<::BlobTransaction>, - _sequencer_commitments_range: (u32, u32), - _witnesses: std::collections::VecDeque>, - _slot_headers: std::collections::VecDeque::BlockHeader>>, - _validity_condition: &::ValidityCondition, - _soft_confirmation: std::collections::VecDeque>, - _preproven_commitment_indicies: Vec, - _forks: Vec, - ) -> (Self::StateRoot, CumulativeStateDiff, SpecId) { - todo!() - } -} diff --git a/crates/sovereign-sdk/examples/demo-simple-stf/tests/stf_test.rs b/crates/sovereign-sdk/examples/demo-simple-stf/tests/stf_test.rs deleted file mode 100644 index 2930a42a3..000000000 --- a/crates/sovereign-sdk/examples/demo-simple-stf/tests/stf_test.rs +++ /dev/null @@ -1,42 +0,0 @@ -use demo_simple_stf::CheckHashPreimageStf; -use sov_mock_da::verifier::MockDaSpec; -use sov_mock_da::{MockAddress, MockBlob, MockBlockHeader, MockValidityCond}; -use sov_mock_zkvm::MockZkvm; -use sov_rollup_interface::spec::SpecId; -use sov_rollup_interface::stf::StateTransitionFunction; - -#[test] -fn test_stf_success() { - let address = MockAddress::from([1; 32]); - - let stf = &mut CheckHashPreimageStf::::default(); - StateTransitionFunction::, MockDaSpec>::init_chain(stf, (), ()); - - let mut blobs = { - let incorrect_preimage = vec![1; 32]; - let correct_preimage = vec![0; 32]; - - [ - MockBlob::new(incorrect_preimage, address, [0; 32]), - MockBlob::new(correct_preimage, address, [0; 32]), - ] - }; - - // Pretend we are in native code and progress the blobs to the verified state. - for blob in &mut blobs { - blob.data.advance(blob.data.total_len()); - } - - let result = StateTransitionFunction::, MockDaSpec>::apply_slot( - stf, - SpecId::Genesis, - &[], - (), - (), - &MockBlockHeader::default(), - &MockValidityCond::default(), - &mut blobs, - ); - - assert_eq!(2, result.batch_receipts.len()); -} diff --git a/crates/sovereign-sdk/examples/demo-stf/Cargo.toml b/crates/sovereign-sdk/examples/demo-stf/Cargo.toml deleted file mode 100644 index 1c88b6fa0..000000000 --- a/crates/sovereign-sdk/examples/demo-stf/Cargo.toml +++ /dev/null @@ -1,77 +0,0 @@ -[package] -name = "demo-stf" -version = { workspace = true } -edition = { workspace = true } -resolver = "2" -authors = { workspace = true } -license = { workspace = true } -homepage = "sovereign.xyz" -publish = false - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -anyhow = { workspace = true } -borsh = { workspace = true } -serde = { workspace = true } -serde_json = { workspace = true, optional = true } -clap = { workspace = true, optional = true } -jsonrpsee = { workspace = true, features = [ - "http-client", - "server", -], optional = true } -tokio = { workspace = true, optional = true } -hex = { workspace = true } -tracing = { workspace = true } -reth-primitives = { workspace = true } -secp256k1 = { workspace = true } - -sov-stf-runner = { path = "../../../sovereign-sdk/full-node/sov-stf-runner" } -sov-rollup-interface = { path = "../../../sovereign-sdk/rollup-interface" } -sov-sequencer-registry = { path = "../../../sovereign-sdk/module-system/module-implementations/sov-sequencer-registry" } -sov-bank = { path = "../../../sovereign-sdk/module-system/module-implementations/sov-bank" } - -sov-modules-stf-blueprint = { path = "../../../sovereign-sdk/module-system/sov-modules-stf-blueprint" } -sov-value-setter = { path = "../../../sovereign-sdk/module-system/module-implementations/examples/sov-value-setter", default-features = false } -sov-accounts = { path = "../../../sovereign-sdk/module-system/module-implementations/sov-accounts", default-features = false } -sov-state = { path = "../../../sovereign-sdk/module-system/sov-state" } -sov-modules-api = { path = "../../../sovereign-sdk/module-system/sov-modules-api", default-features = false } -citrea-evm = { path = "../../../evm" } -soft-confirmation-rule-enforcer = { path = "../../../soft-confirmation-rule-enforcer" } - - -[dev-dependencies] -tempfile = { workspace = true } -rand = { workspace = true } -sov-prover-storage-manager = { path = "../../../sovereign-sdk/full-node/sov-prover-storage-manager", features = [ - "test-utils", -] } - - -[features] -default = ["native"] -native = [ - "sov-stf-runner/native", - "sov-bank/native", - "sov-accounts/native", - "sov-sequencer-registry/native", - "sov-value-setter/native", - "sov-modules-api/native", - "sov-rollup-interface/native", - "sov-modules-stf-blueprint/native", - "citrea-evm/native", - "clap", - "serde", - "serde_json", - "soft-confirmation-rule-enforcer/native", - "jsonrpsee", - "tokio", -] -serde = [ - "sov-bank/serde", - "sov-sequencer-registry/serde", - "sov-value-setter/serde", - "sov-accounts/serde", - "citrea-evm/serde", - "soft-confirmation-rule-enforcer/serde", -] diff --git a/crates/sovereign-sdk/examples/demo-stf/README.md b/crates/sovereign-sdk/examples/demo-stf/README.md deleted file mode 100644 index 46f191c80..000000000 --- a/crates/sovereign-sdk/examples/demo-stf/README.md +++ /dev/null @@ -1,193 +0,0 @@ - - - -- [Demo State Transition Function](#demo-state-transition-function) - - [Overview](#overview) - - [Implementing State Transition _Function_](#implementing-state-transition-_function_) - - [Implementing Runtime: Pick Your Modules](#implementing-runtime-pick-your-modules) - - [Implementing Hooks for the Runtime:](#implementing-hooks-for-the-runtime) - - [Exposing RPC](#exposing-rpc) - - [Make Full Node Itegrations Simpler with the State Transition Runner:](#make-full-node-itegrations-simpler-with-the-state-transition-runner) - - [Using State Transition Runner](#using-state-transition-runner) - - [Wrapping Up](#wrapping-up) - - - -# Demo State Transition Function - -This package shows how you can combine modules to build a custom state transition function. We provide several module implementations -for you, and if you want additional functionality you can find a tutorial on writing custom modules [here](../simple-nft-module/README.md). - -For purposes of this tutorial, the exact choices of modules don't matter at all - the steps to combine modules are identical -no matter which ones you pick. - -## Overview - -To get a fully functional rollup, we recommend implementing the [State Transition Function -interface](../../rollup-interface/specs/interfaces/stf.md) ("STF") trait, which specifies your rollup's abstract logic. Second, there's -a related struct called `State Transition Runner` ("STR") which tells a full node how to run your abstract STF on a concrete machine. - -## Implementing State Transition _Function_ - -As you recall, the Module System is primarily designed to help you implement the [State Transition Function -interface](../../rollup-interface/specs/interfaces/stf.md). - -That interface is quite high-level - the only notion -that it surfaces is that of a `blob` of rollup data. In the Module System, we work at a much lower level - with -transactions signed by particular private keys. To fill the gap, there's a system called an `StfBlueprint`, which -bridges between the two layers of abstraction. - -The reason the `StfBlueprint` is called a "blueprint" is that it's generic. It allows you, the developer, to pass in -several parameters that specify its exact behavior. In order, these generics are: - -1. `Context`: a per-transaction struct containing the message's sender. This also provides specs for storage access, so we use different `Context` - implementations for Native and ZK execution. In ZK, we read values non-deterministically from hints and check them against a merkle tree, while in - native mode we just read values straight from disk. -2. `Runtime`: a collection of modules which make up the rollup's public interface - -To implement your state transition function, you simply need to specify values for each of these fields. - -In the remainder of this section, we'll walk you through implementing each of the remaining generics. - -## Implementing Runtime: Pick Your Modules - -The final piece of the puzzle is your app's runtime. A runtime is just a list of modules - really, that's it! To add a new -module to your app, just add an additional field to the runtime. - -```rust -use sov_modules_api::{Genesis, DispatchCall, MessageCodec, Context}; -use sov_modules_api::macros::expose_rpc; -use sov_rollup_interface::da::DaSpec; -#[cfg(feature = "native")] -use sov_accounts::{AccountsRpcImpl, AccountsRpcServer}; -#[cfg(feature = "native")] -use sov_bank::{BankRpcImpl, BankRpcServer}; -#[cfg(feature = "native")] -use sov_sequencer_registry::{SequencerRegistryRpcImpl, SequencerRegistryRpcServer}; - - -#[cfg_attr( - feature = "native", - expose_rpc(DefaultContext) -)] -#[derive(Genesis, DispatchCall, MessageCodec)] -#[serialization(borsh::BorshDeserialize, borsh::BorshSerialize)] -pub struct MyRuntime { - #[allow(unused)] - sequencer: sov_sequencer_registry::SequencerRegistry, - - #[allow(unused)] - bank: sov_bank::Bank, - - #[allow(unused)] - accounts: sov_accounts::Accounts, -} -``` - -As you can see in the above snippet, we derive four macros on the runtime. The `Genesis` macro generates -initialization code for each module which will get run at your rollup's genesis. The other three macros -allow your runtime to dispatch transactions and queries, and tell it which serialization scheme to use. -We recommend borsh, since it's both fast and safe for hashing. - -### Implementing Hooks for the Runtime: - -The next step is to implement `Hooks` for `MyRuntime`. Hooks are abstractions that allow for the injection of custom logic into the transaction processing pipeline. - -There are two kind of hooks: - -`TxHooks`, which has the following methods: - -1. `pre_dispatch_tx_hook`: Invoked immediately before each transaction is processed. This is a good time to apply stateful transaction verification, like checking the nonce. -2. `post_dispatch_tx_hook`: Invoked immediately after each transaction is executed. This is a good place to perform any post-execution operations, like incrementing the nonce. - -`ApplyBlobHooks`, which has the following methods: - -1. `begin_blob_hook `Invoked at the beginning of the `apply_blob` function, before the blob is deserialized into a group of transactions. This is a good time to ensure that the sequencer is properly bonded. -2. `end_blob_hook` invoked at the end of the `apply_blob` function. This is a good place to reward sequencers. - -To use the `StfBlueprint`, the runtime needs to provide implementation of these hooks which specifies what needs to happen at each of these four stages. - -In this demo, we only rely on two modules which need access to the hooks - `sov-accounts` and `sequencer-registry`. - -The `sov-accounts` module implements `TxHooks` because it needs to check and increment the sender nonce for every transaction. -The `sequencer-registry` implements `ApplyBlobHooks` since it is responsible for managing the sequencer bond. - -The implementation for `MyRuntime` is straightforward because we can leverage the existing hooks provided by `sov-accounts` and `sequencer-registry` and reuse them in our implementation. - -```Rust -impl TxHooks for Runtime { - type Context = C; - - fn pre_dispatch_tx_hook( - &self, - tx: Transaction, - working_set: &mut WorkingSet, - ) -> anyhow::Result<::Address> { - self.accounts.pre_dispatch_tx_hook(tx, working_set) - } - - fn post_dispatch_tx_hook( - &self, - tx: &Transaction, - working_set: &mut WorkingSet, - ) -> anyhow::Result<()> { - self.accounts.post_dispatch_tx_hook(tx, working_set) - } -} -``` - -```Rust -impl ApplyBlobHooks for Runtime { - type Context = C; - - fn lock_sequencer_bond( - &self, - sequencer: &[u8], - working_set: &mut WorkingSet, - ) -> anyhow::Result<()> { - self.sequencer.lock_sequencer_bond(sequencer, working_set) - } - - fn reward_sequencer( - &self, - amount: u64, - working_set: &mut WorkingSet, - ) -> anyhow::Result<()> { - self.sequencer.reward_sequencer(amount, working_set) - } -} -``` - -That's it - with those three structs implemented, you can plug them into your `StfBlueprint` and get a -complete State Transition Function! - -### Exposing RPC - -Your modules implement rpc methods via the `rpc_gen` macro, in order to enable the full-node to expose them, annotate the `Runtime` with `expose_rpc`. -In the example above, you can see how to use the `expose_rpc` macro on the `native` `Runtime`. - -## Make Full Node Integrations Simpler with the State Transition Runner: - -Now that we have an app, we want to be able to run it. For any custom state transition, your full node implementation is going to need a little -customization. At the very least, you'll have to modify our `demo-rollup` example code -to import your custom STF! But, when you're building an STF it's useful to stick as closely as possible to some standard interfaces. -That way, you can minimize the changeset for your custom node implementation, which reduces the risk of bugs. - -To help you integrate with full node implementations, we provide standard tools for initializing an app (`StateTransitionRunner`). In this section, we'll briefly show how to use them. Again it is not strictly -required - just by implementing STF, you get the capability to integrate with DA layers and zkVMs. But, using these structures -makes you more compatible with full node implementations out of the box. - -### Using State Transition Runner - -The State Transition Runner struct contains logic related to initialization and running the rollup. It has just three methods: - -1. `new` - which consumes all the dependencies need for running the rollup. -2. `run` - which runs the rollup. -3. `start_rpc_server` - which exposes an RPC server. - - -## Wrapping Up - -Whew, that was a lot of information. To recap, implementing your own state transition function is as simple as plugging -a Runtime, a Transaction Verifier, and some Transaction Hooks into the pre-built app blueprint. Once you've done that, -you can integrate with any DA layer and zkVM to create a Sovereign Rollup. diff --git a/crates/sovereign-sdk/examples/demo-stf/src/genesis_config.rs b/crates/sovereign-sdk/examples/demo-stf/src/genesis_config.rs deleted file mode 100644 index 62abeb918..000000000 --- a/crates/sovereign-sdk/examples/demo-stf/src/genesis_config.rs +++ /dev/null @@ -1,121 +0,0 @@ -//! While the `GenesisConfig` type for `Rollup` is generated from the underlying runtime through a macro, -//! specific module configurations are obtained from files. This code is responsible for the logic -//! that transforms module genesis data into Rollup genesis data. - -use std::convert::AsRef; -use std::path::{Path, PathBuf}; - -use anyhow::{bail, Context as _}; -use citrea_evm::EvmConfig; -use soft_confirmation_rule_enforcer::SoftConfirmationRuleEnforcerConfig; -use sov_accounts::AccountConfig; -use sov_bank::BankConfig; -pub use sov_modules_api::default_context::DefaultContext; -use sov_modules_api::Context; -use sov_modules_stf_blueprint::Runtime as RuntimeTrait; -use sov_rollup_interface::da::DaSpec; -use sov_sequencer_registry::SequencerConfig; -pub use sov_state::config::Config as StorageConfig; -use sov_stf_runner::read_json_file; -use sov_value_setter::ValueSetterConfig; - -/// Creates config for a rollup with some default settings, the config is used in demos and tests. -use crate::runtime::GenesisConfig; -use crate::runtime::Runtime; - -/// Paths pointing to genesis files. -pub struct GenesisPaths { - /// Bank genesis path. - pub bank_genesis_path: PathBuf, - /// Sequencer Registry genesis path. - pub sequencer_genesis_path: PathBuf, - /// Value Setter genesis path. - pub value_setter_genesis_path: PathBuf, - /// Accounts genesis path. - pub accounts_genesis_path: PathBuf, - /// EVM genesis path. - pub evm_genesis_path: PathBuf, - /// Soft Confirmation Rule Enforcer genesis path. - pub soft_confirmation_rule_enforcer_genesis_path: PathBuf, -} - -impl GenesisPaths { - /// Creates a new [`GenesisPaths`] from the files contained in the given - /// directory. - /// - /// Take a look at the contents of the `test_data` directory to see the - /// expected files. - pub fn from_dir(dir: impl AsRef) -> Self { - Self { - bank_genesis_path: dir.as_ref().join("bank.json"), - sequencer_genesis_path: dir.as_ref().join("sequencer_registry.json"), - value_setter_genesis_path: dir.as_ref().join("value_setter.json"), - accounts_genesis_path: dir.as_ref().join("accounts.json"), - evm_genesis_path: dir.as_ref().join("evm.json"), - soft_confirmation_rule_enforcer_genesis_path: dir - .as_ref() - .join("soft_confirmation_rule_enforcer.json"), - } - } -} - -/// Creates genesis configuration. -pub fn get_genesis_config( - genesis_paths: &GenesisPaths, -) -> Result< as RuntimeTrait>::GenesisConfig, anyhow::Error> { - let genesis_config = - create_genesis_config(genesis_paths).context("Unable to read genesis configuration")?; - validate_config(genesis_config) -} - -pub(crate) fn validate_config( - genesis_config: as RuntimeTrait>::GenesisConfig, -) -> Result< as RuntimeTrait>::GenesisConfig, anyhow::Error> { - let token_address = &sov_bank::get_genesis_token_address::( - &genesis_config.bank.tokens[0].token_name, - genesis_config.bank.tokens[0].salt, - ); - - let coins_token_addr = &genesis_config - .sequencer_registry - .coins_to_lock - .token_address; - - if coins_token_addr != token_address { - bail!( - "Wrong token address in `sequencer_registry_config` expected {} but found {}", - token_address, - coins_token_addr - ) - } - - Ok(genesis_config) -} - -fn create_genesis_config( - genesis_paths: &GenesisPaths, -) -> anyhow::Result< as RuntimeTrait>::GenesisConfig> { - let bank_config: BankConfig = read_json_file(&genesis_paths.bank_genesis_path)?; - - let sequencer_registry_config: SequencerConfig = - read_json_file(&genesis_paths.sequencer_genesis_path)?; - - let value_setter_config: ValueSetterConfig = - read_json_file(&genesis_paths.value_setter_genesis_path)?; - - let accounts_config: AccountConfig = read_json_file(&genesis_paths.accounts_genesis_path)?; - - let evm_config: EvmConfig = read_json_file(&genesis_paths.evm_genesis_path)?; - - let soft_confirmation_rule_enforcer_config: SoftConfirmationRuleEnforcerConfig = - read_json_file(&genesis_paths.soft_confirmation_rule_enforcer_genesis_path)?; - - Ok(GenesisConfig::new( - bank_config, - sequencer_registry_config, - value_setter_config, - accounts_config, - evm_config, - soft_confirmation_rule_enforcer_config, - )) -} diff --git a/crates/sovereign-sdk/examples/demo-stf/src/hooks_impl.rs b/crates/sovereign-sdk/examples/demo-stf/src/hooks_impl.rs deleted file mode 100644 index f21779139..000000000 --- a/crates/sovereign-sdk/examples/demo-stf/src/hooks_impl.rs +++ /dev/null @@ -1,126 +0,0 @@ -use sov_accounts::AccountsTxHook; -use sov_bank::BankTxHook; -use sov_modules_api::hooks::{ - ApplyBlobHooks, ApplySoftConfirmationHooks, FinalizeHook, HookSoftConfirmationInfo, SlotHooks, - SoftConfirmationError, TxHooks, -}; -use sov_modules_api::transaction::Transaction; -use sov_modules_api::{AccessoryWorkingSet, Context, Spec, WorkingSet}; -use sov_modules_stf_blueprint::{RuntimeTxHook, SequencerOutcome}; -use sov_rollup_interface::da::{BlobReaderTrait, DaSpec}; -use sov_state::Storage; - -use crate::runtime::Runtime; - -impl TxHooks for Runtime { - type Context = C; - type PreArg = RuntimeTxHook; - type PreResult = C; - - fn pre_dispatch_tx_hook( - &self, - tx: &Transaction, - working_set: &mut WorkingSet, - arg: &RuntimeTxHook, - ) -> anyhow::Result { - let RuntimeTxHook { - height, - sequencer, - current_spec, - l1_fee_rate, - } = arg; - let AccountsTxHook { sender, sequencer } = - self.accounts - .pre_dispatch_tx_hook(tx, working_set, sequencer)?; - - let hook = BankTxHook { sender, sequencer }; - self.bank.pre_dispatch_tx_hook(tx, working_set, &hook)?; - - Ok(C::new( - hook.sender, - hook.sequencer, - *height, - *current_spec, - *l1_fee_rate, - )) - } - - fn post_dispatch_tx_hook( - &self, - tx: &Transaction, - ctx: &C, - working_set: &mut WorkingSet, - ) -> anyhow::Result<()> { - self.accounts.post_dispatch_tx_hook(tx, ctx, working_set)?; - self.bank.post_dispatch_tx_hook(tx, ctx, working_set)?; - Ok(()) - } -} - -impl ApplyBlobHooks for Runtime { - type Context = C; - type BlobResult = - SequencerOutcome<<::BlobTransaction as BlobReaderTrait>::Address>; - - fn begin_blob_hook( - &self, - blob: &mut Da::BlobTransaction, - working_set: &mut WorkingSet, - ) -> anyhow::Result<()> { - // Before executing each batch, check that the sender is registered as a sequencer - self.sequencer_registry.begin_blob_hook(blob, working_set) - } - - fn end_blob_hook(&self, _working_set: &mut WorkingSet) -> anyhow::Result<()> { - Ok(()) - } -} - -impl ApplySoftConfirmationHooks for Runtime { - type Context = C; - type SoftConfirmationResult = - SequencerOutcome<<::BlobTransaction as BlobReaderTrait>::Address>; - - fn begin_soft_confirmation_hook( - &mut self, - _soft_confirmation: &HookSoftConfirmationInfo, - _working_set: &mut WorkingSet, - ) -> Result<(), SoftConfirmationError> { - // Before executing each batch, check that the sender is registered as a sequencer - Ok(()) - } - - fn end_soft_confirmation_hook( - &mut self, - _soft_confirmation: HookSoftConfirmationInfo, - _working_set: &mut WorkingSet, - ) -> Result<(), SoftConfirmationError> { - Ok(()) - } -} - -impl SlotHooks for Runtime { - type Context = C; - - fn begin_slot_hook( - &self, - _slot_header: &Da::BlockHeader, - _validity_condition: &Da::ValidityCondition, - _pre_state_root: &<::Storage as Storage>::Root, - _working_set: &mut sov_modules_api::WorkingSet, - ) { - } - - fn end_slot_hook(&self, _working_set: &mut sov_modules_api::WorkingSet) {} -} - -impl FinalizeHook for Runtime { - type Context = C; - - fn finalize_hook( - &self, - _root_hash: &<::Storage as Storage>::Root, - _accessory_working_set: &mut AccessoryWorkingSet, - ) { - } -} diff --git a/crates/sovereign-sdk/examples/demo-stf/src/lib.rs b/crates/sovereign-sdk/examples/demo-stf/src/lib.rs deleted file mode 100644 index 6faa65785..000000000 --- a/crates/sovereign-sdk/examples/demo-stf/src/lib.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![deny(missing_docs)] -#![doc = include_str!("../README.md")] - -#[cfg(feature = "native")] -pub mod genesis_config; -mod hooks_impl; -pub mod runtime; -#[cfg(test)] -mod tests; diff --git a/crates/sovereign-sdk/examples/demo-stf/src/runtime.rs b/crates/sovereign-sdk/examples/demo-stf/src/runtime.rs deleted file mode 100644 index 5d614d2ac..000000000 --- a/crates/sovereign-sdk/examples/demo-stf/src/runtime.rs +++ /dev/null @@ -1,104 +0,0 @@ -//! The Rollup entrypoint. -//! -//! On a high level, the rollup node receives serialized call messages from the DA layer and executes them as atomic transactions. -//! Upon reception, the message has to be deserialized and forwarded to an appropriate module. -//! -//! The module-specific logic is implemented by module creators, but all the glue code responsible for message -//! deserialization/forwarding is handled by a rollup `runtime`. -//! -//! In order to define the runtime we need to specify all the modules supported by our rollup (see the `Runtime` struct bellow) -//! -//! The `Runtime` together with associated interfaces (`Genesis`, `DispatchCall`, `MessageCodec`) -//! and derive macros defines: -//! - how the rollup modules are wired up together. -//! - how the state of the rollup is initialized. -//! - how messages are dispatched to appropriate modules. -//! -//! Runtime lifecycle: -//! -//! 1. Initialization: -//! When a rollup is deployed for the first time, it needs to set its genesis state. -//! The `#[derive(Genesis)` macro will generate `Runtime::genesis(config)` method which returns -//! `Storage` with the initialized state. -//! -//! 2. Calls: -//! The `Module` interface defines a `call` method which accepts a module-defined type and triggers the specific `module logic.` -//! In general, the point of a call is to change the module state, but if the call throws an error, -//! no module specific state is updated (the transaction is reverted). -//! -//! `#[derive(MessageCodec)` adds deserialization capabilities to the `Runtime` (implements `decode_call` method). -//! `Runtime::decode_call` accepts serialized call message and returns a type that implements the `DispatchCall` trait. -//! The `DispatchCall` implementation (derived by a macro) forwards the message to the appropriate module and executes its `call` method. - -#![allow(unused_doc_comments)] -#[cfg(feature = "native")] -use citrea_evm::{EvmRpcImpl, EvmRpcServer}; -#[cfg(feature = "native")] -use soft_confirmation_rule_enforcer::{ - SoftConfirmationRuleEnforcerRpcImpl, SoftConfirmationRuleEnforcerRpcServer, -}; -#[cfg(feature = "native")] -use sov_accounts::{AccountsRpcImpl, AccountsRpcServer}; -#[cfg(feature = "native")] -use sov_bank::{BankRpcImpl, BankRpcServer}; -#[cfg(feature = "native")] -pub use sov_modules_api::default_context::DefaultContext; -use sov_modules_api::macros::DefaultRuntime; -#[cfg(feature = "native")] -use sov_modules_api::macros::{expose_rpc, CliWallet}; -#[cfg(feature = "native")] -use sov_modules_api::Spec; -use sov_modules_api::{Context, DispatchCall, Genesis, MessageCodec}; -use sov_rollup_interface::da::DaSpec; -#[cfg(feature = "native")] -use sov_sequencer_registry::{SequencerRegistryRpcImpl, SequencerRegistryRpcServer}; -#[cfg(feature = "native")] -use sov_value_setter::{ValueSetterRpcImpl, ValueSetterRpcServer}; - -#[cfg(feature = "native")] -use crate::genesis_config::GenesisPaths; - -/// The `demo-stf runtime`. -#[cfg_attr(feature = "native", derive(CliWallet), expose_rpc)] -#[derive(Genesis, DispatchCall, MessageCodec, DefaultRuntime)] -#[serialization(borsh::BorshDeserialize, borsh::BorshSerialize)] -#[cfg_attr(feature = "serde", serialization(serde::Serialize, serde::Deserialize))] -pub struct Runtime { - /// The Bank module. - pub bank: sov_bank::Bank, - /// The Sequencer Registry module. - pub sequencer_registry: sov_sequencer_registry::SequencerRegistry, - /// The Value Setter module. - pub value_setter: sov_value_setter::ValueSetter, - /// The Accounts module. - pub accounts: sov_accounts::Accounts, - #[cfg_attr(feature = "native", cli_skip)] - /// The EVM module. - pub evm: citrea_evm::Evm, - /// The soft confirmation rule enforcer module. - pub soft_confirmation_rule_enforcer: - soft_confirmation_rule_enforcer::SoftConfirmationRuleEnforcer, -} - -impl sov_modules_stf_blueprint::Runtime for Runtime -where - C: Context, - Da: DaSpec, -{ - type GenesisConfig = GenesisConfig; - - #[cfg(feature = "native")] - type GenesisPaths = GenesisPaths; - - #[cfg(feature = "native")] - fn rpc_methods(storage: ::Storage) -> jsonrpsee::RpcModule<()> { - get_rpc_methods::(storage) - } - - #[cfg(feature = "native")] - fn genesis_config( - genesis_paths: &Self::GenesisPaths, - ) -> Result { - crate::genesis_config::get_genesis_config(genesis_paths) - } -} diff --git a/crates/sovereign-sdk/examples/demo-stf/src/tests/da_simulation.rs b/crates/sovereign-sdk/examples/demo-stf/src/tests/da_simulation.rs deleted file mode 100644 index 9b0352691..000000000 --- a/crates/sovereign-sdk/examples/demo-stf/src/tests/da_simulation.rs +++ /dev/null @@ -1,55 +0,0 @@ -use std::rc::Rc; - -use sov_data_generators::bank_data::{ - BadNonceBankCallMessages, BadSerializationBankCallMessages, BadSignatureBankCallMessages, - BankMessageGenerator, -}; -use sov_data_generators::value_setter_data::{ValueSetterMessage, ValueSetterMessages}; -use sov_data_generators::MessageGenerator; -use sov_mock_da::MockDaSpec; -use sov_modules_api::default_context::DefaultContext; -use sov_modules_api::default_signature::private_key::DefaultPrivateKey; -use sov_modules_stf_blueprint::RawTx; - -use crate::runtime::Runtime; - -type C = DefaultContext; -type Da = MockDaSpec; - -pub fn simulate_da(value_setter_admin: DefaultPrivateKey) -> Vec { - let mut messages = Vec::default(); - - let bank_generator = BankMessageGenerator::::default(); - let bank_txs = bank_generator.create_raw_txs::>(); - - let value_setter = ValueSetterMessages::new(vec![ValueSetterMessage { - admin: Rc::new(value_setter_admin), - messages: vec![99, 33], - }]); - messages.extend(value_setter.create_raw_txs::>()); - messages.extend(bank_txs); - messages -} - -pub fn simulate_da_with_revert_msg() -> Vec { - let mut messages = Vec::default(); - let bank_generator = BankMessageGenerator::::create_invalid_transfer(); - let bank_txns = bank_generator.create_raw_txs::>(); - messages.extend(bank_txns); - messages -} - -pub fn simulate_da_with_bad_sig() -> Vec { - let b: BadSignatureBankCallMessages = Default::default(); - b.create_raw_txs::>() -} - -pub fn simulate_da_with_bad_nonce() -> Vec { - let b: BadNonceBankCallMessages = Default::default(); - b.create_raw_txs::>() -} - -pub fn simulate_da_with_bad_serialization() -> Vec { - let b: BadSerializationBankCallMessages = Default::default(); - b.create_raw_txs::>() -} diff --git a/crates/sovereign-sdk/examples/demo-stf/src/tests/mod.rs b/crates/sovereign-sdk/examples/demo-stf/src/tests/mod.rs deleted file mode 100644 index 263cfbcea..000000000 --- a/crates/sovereign-sdk/examples/demo-stf/src/tests/mod.rs +++ /dev/null @@ -1,52 +0,0 @@ -// use std::path::Path; - -// use sov_mock_da::MockDaSpec; -// use sov_modules_api::default_context::DefaultContext; -// use sov_modules_api::DaSpec; -// use sov_modules_stf_blueprint::kernels::basic::{BasicKernel, BasicKernelGenesisConfig}; -// use sov_modules_stf_blueprint::{GenesisParams, StfBlueprint}; -// use sov_prover_storage_manager::ProverStorageManager; -// use sov_stf_runner::read_json_file; - -// use crate::genesis_config::{get_genesis_config, GenesisPaths}; -// use crate::runtime::{GenesisConfig, Runtime}; - -// mod da_simulation; -// mod stf_tests; -// mod tx_revert_tests; -// pub(crate) type C = DefaultContext; -// pub(crate) type Da = MockDaSpec; - -// pub(crate) type RuntimeTest = Runtime; -// pub(crate) type StfBlueprintTest = StfBlueprint< -// DefaultContext, -// Da, -// sov_mock_zkvm::MockZkvm<::ValidityCondition>, -// RuntimeTest, -// BasicKernel, -// >; - -// pub(crate) fn create_storage_manager_for_tests( -// path: impl AsRef, -// ) -> ProverStorageManager { -// let config = sov_state::config::Config { -// path: path.as_ref().to_path_buf(), -// }; -// ProverStorageManager::new(config).unwrap() -// } - -// pub(crate) fn get_genesis_config_for_tests( -// ) -> GenesisParams, BasicKernelGenesisConfig> -// { -// let integ_test_conf_dir: &Path = "../resources/test-data/integration-tests".as_ref(); -// let rt_params = -// get_genesis_config::(&GenesisPaths::from_dir(integ_test_conf_dir)) -// .unwrap(); - -// let chain_state = read_json_file(integ_test_conf_dir.join("chain_state.json")).unwrap(); -// let kernel_params = BasicKernelGenesisConfig { chain_state }; -// GenesisParams { -// runtime: rt_params, -// kernel: kernel_params, -// } -// } diff --git a/crates/sovereign-sdk/examples/demo-stf/src/tests/stf_tests.rs b/crates/sovereign-sdk/examples/demo-stf/src/tests/stf_tests.rs deleted file mode 100644 index de636994a..000000000 --- a/crates/sovereign-sdk/examples/demo-stf/src/tests/stf_tests.rs +++ /dev/null @@ -1,296 +0,0 @@ -use sov_cli::wallet_state::PrivateKeyAndAddress; -use sov_data_generators::bank_data::get_default_token_address; -use sov_data_generators::new_test_blob_from_batch; -use sov_mock_da::{MockBlock, MockDaSpec, MOCK_SEQUENCER_DA_ADDRESS}; -use sov_modules_api::default_context::DefaultContext; -use sov_modules_api::default_signature::private_key::DefaultPrivateKey; -use sov_modules_api::{Context, PrivateKey, WorkingSet}; -use sov_modules_stf_blueprint::{Batch, StfBlueprint}; -use sov_rollup_interface::services::da::SlotData; -use sov_rollup_interface::stf::StateTransitionFunction; -use sov_rollup_interface::storage::HierarchicalStorageManager; - -use crate::runtime::Runtime; -use crate::tests::da_simulation::simulate_da; -use crate::tests::{ - create_storage_manager_for_tests, get_genesis_config_for_tests, StfBlueprintTest, C, -}; - -#[test] -fn test_demo_values_in_db() { - let tempdir = tempfile::tempdir().unwrap(); - let path = tempdir.path(); - let mut storage_manager = create_storage_manager_for_tests(path); - let config = get_genesis_config_for_tests(); - - let genesis_block = MockBlock::default(); - let block_1 = genesis_block.next_mock(); - - let last_block = { - let stf: StfBlueprintTest = StfBlueprint::new(); - let storage = storage_manager - .create_storage_on(genesis_block.header()) - .unwrap(); - let (genesis_root, storage) = stf.init_chain(storage, config); - storage_manager - .save_change_set(genesis_block.header(), storage) - .unwrap(); - - let priv_key = read_private_key::().private_key; - let txs = simulate_da(priv_key); - let blob = new_test_blob_from_batch(Batch { txs }, &MOCK_SEQUENCER_DA_ADDRESS, [0; 32]); - - let mut blobs = [blob]; - - let storage = storage_manager.create_storage_on(block_1.header()).unwrap(); - - let result = stf.apply_slot( - &genesis_root, - storage, - Default::default(), - &block_1.header, - &block_1.validity_cond, - &mut blobs, - ); - assert_eq!(1, result.batch_receipts.len()); - // 2 transactions from value setter - // 2 transactions from bank - assert_eq!(4, result.batch_receipts[0].tx_receipts.len()); - - // let apply_blob_outcome = result.batch_receipts[0].clone(); - // assert_eq!( - // SequencerOutcome::Rewarded(0), - // apply_blob_outcome.inner, - // "Sequencer execution should have succeeded but failed " - // ); - - // assert!(has_tx_events(&apply_blob_outcome),); - storage_manager - .save_change_set(block_1.header(), result.change_set) - .unwrap(); - block_1 - }; - - // Generate a new storage instance after dumping data to the db. - { - let next_block = last_block.next_mock(); - let runtime = &mut Runtime::::default(); - let storage = storage_manager - .create_storage_on(next_block.header()) - .unwrap(); - let mut working_set = WorkingSet::new(storage); - let resp = runtime - .bank - .supply_of(get_default_token_address(), &mut working_set) - .unwrap(); - assert_eq!(resp, sov_bank::TotalSupplyResponse { amount: Some(1000) }); - - let resp = runtime.value_setter.query_value(&mut working_set).unwrap(); - - assert_eq!(resp, sov_value_setter::Response { value: Some(33) }); - } -} - -#[test] -fn test_demo_values_in_cache() { - let tempdir = tempfile::tempdir().unwrap(); - let path = tempdir.path(); - let mut storage_manager = create_storage_manager_for_tests(path); - - let stf: StfBlueprintTest = StfBlueprint::new(); - - let config = get_genesis_config_for_tests(); - - let genesis_block = MockBlock::default(); - let storage = storage_manager - .create_storage_on(genesis_block.header()) - .unwrap(); - let (genesis_root, storage) = stf.init_chain(storage, config); - storage_manager - .save_change_set(genesis_block.header(), storage) - .unwrap(); - - let private_key = read_private_key::().private_key; - let txs = simulate_da(private_key); - - let blob = new_test_blob_from_batch(Batch { txs }, &MOCK_SEQUENCER_DA_ADDRESS, [0; 32]); - let mut blobs = [blob]; - let block_1 = genesis_block.next_mock(); - let storage = storage_manager.create_storage_on(block_1.header()).unwrap(); - - let apply_block_result = stf.apply_slot( - &genesis_root, - storage, - Default::default(), - &block_1.header, - &block_1.validity_cond, - &mut blobs, - ); - - assert_eq!(1, apply_block_result.batch_receipts.len()); - // let apply_blob_outcome = apply_block_result.batch_receipts[0].clone(); - - // assert_eq!( - // SequencerOutcome::Rewarded(0), - // apply_blob_outcome.inner, - // "Sequencer execution should have succeeded but failed" - // ); - - // assert!(has_tx_events(&apply_blob_outcome),); - - let runtime = &mut Runtime::::default(); - let mut working_set = WorkingSet::new(apply_block_result.change_set); - - let resp = runtime - .bank - .supply_of(get_default_token_address(), &mut working_set) - .unwrap(); - assert_eq!(resp, sov_bank::TotalSupplyResponse { amount: Some(1000) }); - - let resp = runtime.value_setter.query_value(&mut working_set).unwrap(); - - assert_eq!(resp, sov_value_setter::Response { value: Some(33) }); -} - -#[test] -#[ignore = "end_slot is removed from STF trait"] -fn test_demo_values_not_in_db() { - let tempdir = tempfile::tempdir().unwrap(); - let path = tempdir.path(); - let mut storage_manager = create_storage_manager_for_tests(path); - - let value_setter_admin_private_key = DefaultPrivateKey::generate(); - let genesis_block = MockBlock::default(); - let block_1 = genesis_block.next_mock(); - let block_2 = block_1.next_mock(); - - let config = get_genesis_config_for_tests(); - { - let stf: StfBlueprintTest = StfBlueprint::new(); - - let storage = storage_manager - .create_storage_on(genesis_block.header()) - .unwrap(); - let (genesis_root, storage) = stf.init_chain(storage, config); - storage_manager - .save_change_set(genesis_block.header(), storage) - .unwrap(); - - let txs = simulate_da(value_setter_admin_private_key); - let blob = new_test_blob_from_batch(Batch { txs }, &MOCK_SEQUENCER_DA_ADDRESS, [0; 32]); - let mut blobs = [blob]; - - let storage = storage_manager.create_storage_on(block_1.header()).unwrap(); - - let apply_block_result = stf.apply_slot( - &genesis_root, - storage, - Default::default(), - &block_1.header, - &block_1.validity_cond, - &mut blobs, - ); - - assert_eq!(1, apply_block_result.batch_receipts.len()); - // let apply_blob_outcome = apply_block_result.batch_receipts[0].clone(); - - // assert_eq!( - // SequencerOutcome::Rewarded(0), - // apply_blob_outcome.inner, - // "Sequencer execution should have succeeded but failed", - // ); - } - - // Generate a new storage instance, - // values are missing because change set from apply slot wasn't saved back to storage manager - { - let runtime = &mut Runtime::::default(); - let storage = storage_manager.create_storage_on(block_2.header()).unwrap(); - let mut working_set = WorkingSet::new(storage); - - let resp = runtime - .bank - .supply_of(get_default_token_address(), &mut working_set) - .unwrap(); - assert_eq!(resp, sov_bank::TotalSupplyResponse { amount: Some(1000) }); - - let resp = runtime.value_setter.query_value(&mut working_set).unwrap(); - - assert_eq!(resp, sov_value_setter::Response { value: None }); - } -} - -#[test] -fn test_sequencer_unknown_sequencer() { - let tempdir = tempfile::tempdir().unwrap(); - let path = tempdir.path(); - - let mut config = get_genesis_config_for_tests(); - config.runtime.sequencer_registry.is_preferred_sequencer = false; - - let genesis_block = MockBlock::default(); - let block_1 = genesis_block.next_mock(); - - let mut storage_manager = create_storage_manager_for_tests(path); - let stf: StfBlueprintTest = StfBlueprint::new(); - let (genesis_root, storage) = stf.init_chain( - storage_manager - .create_storage_on(genesis_block.header()) - .unwrap(), - config, - ); - storage_manager - .save_change_set(genesis_block.header(), storage) - .unwrap(); - - let some_sequencer: [u8; 32] = [121; 32]; - - let private_key = read_private_key::().private_key; - let txs = simulate_da(private_key); - let blob = new_test_blob_from_batch(Batch { txs }, &some_sequencer, [0; 32]); - let mut blobs = [blob]; - - let storage = storage_manager.create_storage_on(block_1.header()).unwrap(); - - let apply_block_result = stf.apply_slot( - &genesis_root, - storage, - Default::default(), - &block_1.header, - &block_1.validity_cond, - &mut blobs, - ); - - assert_eq!(1, apply_block_result.batch_receipts.len()); - // let apply_blob_outcome = apply_block_result.batch_receipts[0].clone(); - - // assert_eq!( - // SequencerOutcome::Ignored, - // apply_blob_outcome.inner, - // "Batch should have been skipped due to unknown sequencer" - // ); - - // // Assert that there are no events - // assert!(!has_tx_events(&apply_blob_outcome)); -} - -fn read_private_key() -> PrivateKeyAndAddress { - let token_deployer_data = - std::fs::read_to_string("../test-data/keys/token_deployer_private_key.json") - .expect("Unable to read file to string"); - - let token_deployer: PrivateKeyAndAddress = serde_json::from_str(&token_deployer_data) - .unwrap_or_else(|_| { - panic!( - "Unable to convert data {} to PrivateKeyAndAddress", - &token_deployer_data - ) - }); - - assert!( - token_deployer.is_matching_to_default(), - "Inconsistent key data" - ); - - token_deployer -} diff --git a/crates/sovereign-sdk/examples/demo-stf/src/tests/tx_revert_tests.rs b/crates/sovereign-sdk/examples/demo-stf/src/tests/tx_revert_tests.rs deleted file mode 100644 index de267ef49..000000000 --- a/crates/sovereign-sdk/examples/demo-stf/src/tests/tx_revert_tests.rs +++ /dev/null @@ -1,359 +0,0 @@ -use sov_accounts::Response; -use sov_data_generators::bank_data::{get_default_private_key, get_default_token_address}; -use sov_data_generators::new_test_blob_from_batch; -use sov_mock_da::{MockAddress, MockBlock, MockDaSpec, MOCK_SEQUENCER_DA_ADDRESS}; -use sov_modules_api::default_context::DefaultContext; -use sov_modules_api::{PrivateKey, WorkingSet}; -use sov_modules_stf_blueprint::{Batch, StfBlueprint, TxEffect}; -use sov_rollup_interface::services::da::SlotData; -use sov_rollup_interface::stf::StateTransitionFunction; -use sov_rollup_interface::storage::HierarchicalStorageManager; - -use super::{create_storage_manager_for_tests, get_genesis_config_for_tests, RuntimeTest}; -use crate::runtime::Runtime; -use crate::tests::da_simulation::{ - simulate_da_with_bad_nonce, simulate_da_with_bad_serialization, simulate_da_with_bad_sig, - simulate_da_with_revert_msg, -}; -use crate::tests::StfBlueprintTest; - -// Assume there was proper address and we converted it to bytes already. -const SEQUENCER_DA_ADDRESS: [u8; 32] = [1; 32]; - -#[test] -fn test_tx_revert() { - // Test checks: - // - Batch is successfully applied even with incorrect txs - // - Nonce for bad transactions has increased - - let tempdir = tempfile::tempdir().unwrap(); - - let config = get_genesis_config_for_tests(); - let sequencer_rollup_address = config.runtime.sequencer_registry.seq_rollup_address; - - let genesis_block = MockBlock::default(); - let block_1 = genesis_block.next_mock(); - - let storage = { - let mut storage_manager = create_storage_manager_for_tests(tempdir.path()); - let stf: StfBlueprintTest = StfBlueprint::new(); - - let (genesis_root, storage) = stf.init_chain( - storage_manager - .create_storage_on(genesis_block.header()) - .unwrap(), - config, - ); - storage_manager - .save_change_set(genesis_block.header(), storage) - .unwrap(); - - let txs = simulate_da_with_revert_msg(); - let blob = new_test_blob_from_batch(Batch { txs }, &MOCK_SEQUENCER_DA_ADDRESS, [0; 32]); - let mut blobs = [blob]; - - let storage = storage_manager.create_storage_on(block_1.header()).unwrap(); - let apply_block_result = stf.apply_slot( - &genesis_root, - storage, - Default::default(), - &block_1.header, - &block_1.validity_cond, - &mut blobs, - ); - - assert_eq!(1, apply_block_result.batch_receipts.len()); - // let apply_blob_outcome = apply_block_result.batch_receipts[0].clone(); - - // assert_eq!( - // SequencerOutcome::Rewarded(0), - // apply_blob_outcome.inner, - // "Unexpected outcome: Batch execution should have succeeded", - // ); - - let txn_receipts = apply_block_result.batch_receipts[0].tx_receipts.clone(); - // 3 transactions - // create 1000 tokens - // transfer 15 tokens - // transfer 5000 tokens // this should be reverted - assert_eq!(txn_receipts[0].receipt, TxEffect::Successful); - assert_eq!(txn_receipts[1].receipt, TxEffect::Successful); - assert_eq!(txn_receipts[2].receipt, TxEffect::Reverted); - - apply_block_result.change_set - }; - - // Checks on storage after execution - { - let runtime = &mut Runtime::::default(); - let mut working_set = WorkingSet::new(storage); - let resp = runtime - .bank - .balance_of( - get_default_private_key().default_address(), - get_default_token_address(), - &mut working_set, - ) - .unwrap(); - - assert_eq!(resp.amount, Some(985)); - - let resp = runtime - .sequencer_registry - .sequencer_address( - MockAddress::from(MOCK_SEQUENCER_DA_ADDRESS), - &mut working_set, - ) - .unwrap(); - // Sequencer is not excluded from list of allowed! - assert_eq!(Some(sequencer_rollup_address), resp.address); - - let nonce = match runtime - .accounts - .get_account(get_default_private_key().pub_key(), &mut working_set) - .unwrap() - { - Response::AccountExists { nonce, .. } => nonce, - Response::AccountEmpty => 0, - }; - - // with 3 transactions, the final nonce should be 3 - // 0 -> 1 - // 1 -> 2 - // 2 -> 3 - // minter account should have its nonce increased for 3 transactions - assert_eq!(3, nonce); - } -} - -#[test] -fn test_tx_bad_signature() { - let tempdir = tempfile::tempdir().unwrap(); - let path = tempdir.path(); - - let config = get_genesis_config_for_tests(); - - let genesis_block = MockBlock::default(); - let block_1 = genesis_block.next_mock(); - let storage = { - let mut storage_manager = create_storage_manager_for_tests(path); - let stf: StfBlueprintTest = StfBlueprint::new(); - let (genesis_root, storage) = stf.init_chain( - storage_manager - .create_storage_on(genesis_block.header()) - .unwrap(), - config, - ); - storage_manager - .save_change_set(genesis_block.header(), storage) - .unwrap(); - - let txs = simulate_da_with_bad_sig(); - - let blob = new_test_blob_from_batch(Batch { txs }, &MOCK_SEQUENCER_DA_ADDRESS, [0; 32]); - // let blob_sender = blob.sender(); - let mut blobs = [blob]; - - let storage = storage_manager.create_storage_on(block_1.header()).unwrap(); - let apply_block_result = stf.apply_slot( - &genesis_root, - storage, - Default::default(), - &block_1.header, - &block_1.validity_cond, - &mut blobs, - ); - - assert_eq!(1, apply_block_result.batch_receipts.len()); - // let apply_blob_outcome = apply_block_result.batch_receipts[0].clone(); - - // assert_eq!( - // SequencerOutcome::Slashed{ - // reason:SlashingReason::StatelessVerificationFailed, - // sequencer_da_address: blob_sender, - // }, - // apply_blob_outcome.inner, - // "Unexpected outcome: Stateless verification should have failed due to invalid signature" - // ); - - // The batch receipt contains no events. - // assert!(!has_tx_events(&apply_blob_outcome)); - apply_block_result.change_set - }; - - { - let runtime = &mut Runtime::::default(); - let mut working_set = WorkingSet::new(storage); - let nonce = match runtime - .accounts - .get_account(get_default_private_key().pub_key(), &mut working_set) - .unwrap() - { - Response::AccountExists { nonce, .. } => nonce, - Response::AccountEmpty => 0, - }; - assert_eq!(0, nonce); - } -} - -#[test] -fn test_tx_bad_nonce() { - let tempdir = tempfile::tempdir().unwrap(); - let path = tempdir.path(); - - let config = get_genesis_config_for_tests(); - let genesis_block = MockBlock::default(); - let block_1 = genesis_block.next_mock(); - { - let mut storage_manager = create_storage_manager_for_tests(path); - let stf: StfBlueprintTest = StfBlueprint::new(); - let (genesis_root, storage) = stf.init_chain( - storage_manager - .create_storage_on(genesis_block.header()) - .unwrap(), - config, - ); - storage_manager - .save_change_set(genesis_block.header(), storage) - .unwrap(); - let txs = simulate_da_with_bad_nonce(); - - let blob = new_test_blob_from_batch(Batch { txs }, &MOCK_SEQUENCER_DA_ADDRESS, [0; 32]); - let mut blobs = [blob]; - - let storage = storage_manager.create_storage_on(block_1.header()).unwrap(); - let apply_block_result = stf.apply_slot( - &genesis_root, - storage, - Default::default(), - &block_1.header, - &block_1.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(); - // Bad nonce means that the transaction has to be reverted - assert_eq!(tx_receipts[0].receipt, TxEffect::Reverted); - - // We don't expect the sequencer to be slashed for a bad nonce - // The reason for this is that in cases such as based sequencing, the sequencer can - // still post under the assumption that the nonce is valid (It doesn't know other sequencers - // are also doing this) so it needs to be rewarded. - // We're asserting that here to track if the logic changes - // assert_eq!( - // apply_block_result.batch_receipts[0].inner, - // SequencerOutcome::Rewarded(0) - // ); - } -} - -#[test] -fn test_tx_bad_serialization() { - let tempdir = tempfile::tempdir().unwrap(); - let path = tempdir.path(); - - let config = get_genesis_config_for_tests(); - let sequencer_rollup_address = config.runtime.sequencer_registry.seq_rollup_address; - - let genesis_block = MockBlock::default(); - let block_1 = genesis_block.next_mock(); - let mut storage_manager = create_storage_manager_for_tests(path); - - let (genesis_root, sequencer_balance_before) = { - let stf: StfBlueprintTest = StfBlueprint::new(); - - let (genesis_root, storage) = stf.init_chain( - storage_manager - .create_storage_on(genesis_block.header()) - .unwrap(), - config, - ); - - let balance = { - let runtime: RuntimeTest = Runtime::default(); - let mut working_set = WorkingSet::new(storage.clone()); - - let coins = runtime - .sequencer_registry - .get_coins_to_lock(&mut working_set) - .unwrap(); - - runtime - .bank - .get_balance_of( - sequencer_rollup_address, - coins.token_address, - &mut working_set, - ) - .unwrap() - }; - storage_manager - .save_change_set(genesis_block.header(), storage) - .unwrap(); - (genesis_root, balance) - }; - - let storage = { - let stf: StfBlueprintTest = StfBlueprint::new(); - - let txs = simulate_da_with_bad_serialization(); - let blob = new_test_blob_from_batch(Batch { txs }, &MOCK_SEQUENCER_DA_ADDRESS, [0; 32]); - // let blob_sender = blob.sender(); - let mut blobs = [blob]; - - let storage = storage_manager.create_storage_on(block_1.header()).unwrap(); - let apply_block_result = stf.apply_slot( - &genesis_root, - storage, - Default::default(), - &block_1.header, - &block_1.validity_cond, - &mut blobs, - ); - - assert_eq!(1, apply_block_result.batch_receipts.len()); - // let apply_blob_outcome = apply_block_result.batch_receipts[0].clone(); - - // assert_eq!( - // SequencerOutcome::Slashed { - // reason: SlashingReason::InvalidTransactionEncoding , - // sequencer_da_address: blob_sender, - // }, - // apply_blob_outcome.inner, - // "Unexpected outcome: Stateless verification should have failed due to invalid signature" - // ); - - // The batch receipt contains no events. - // assert!(!has_tx_events(&apply_blob_outcome)); - apply_block_result.change_set - }; - - { - let runtime = &mut Runtime::::default(); - let mut working_set = WorkingSet::new(storage); - - // Sequencer is not in the list of allowed sequencers - - let allowed_sequencer = runtime - .sequencer_registry - .sequencer_address(MockAddress::from(SEQUENCER_DA_ADDRESS), &mut working_set) - .unwrap(); - assert!(allowed_sequencer.address.is_none()); - - // Balance of sequencer is not increased - let coins = runtime - .sequencer_registry - .get_coins_to_lock(&mut working_set) - .unwrap(); - let sequencer_balance_after = runtime - .bank - .get_balance_of( - sequencer_rollup_address, - coins.token_address, - &mut working_set, - ) - .unwrap(); - assert_eq!(sequencer_balance_before, sequencer_balance_after); - } -} diff --git a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/bitcoin/accounts.json b/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/bitcoin/accounts.json deleted file mode 100644 index f65b078f6..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/bitcoin/accounts.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "pub_keys": [] -} diff --git a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/bitcoin/bank.json b/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/bitcoin/bank.json deleted file mode 100644 index d03fcc10f..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/bitcoin/bank.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "tokens": [ - { - "token_name": "sov-demo-token", - "address_and_balances": [ - [ - "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94", - 100000000 - ] - ], - "authorized_minters": [ - "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94" - ], - "salt": 0 - } - ] -} diff --git a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/bitcoin/evm.json b/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/bitcoin/evm.json deleted file mode 100644 index 22ff8f4d9..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/bitcoin/evm.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "data": [ - { - "address": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "balance": "0xffffffffffffffff", - "code": "0x" - } - ], - "chain_id": 5655, - "limit_contract_code_size": null, - "spec": { - "0": "SHANGHAI" - }, - "coinbase": "0x0000000000000000000000000000000000000000", - "starting_base_fee": 1000000000, - "block_gas_limit": 30000000, - "base_fee_params": { - "max_change_denominator": 8, - "elasticity_multiplier": 2 - }, - "timestamp": 0, - "difficulty": 0, - "extra_data": "0x", - "nonce": 0 -} \ No newline at end of file diff --git a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/bitcoin/sequencer_registry.json b/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/bitcoin/sequencer_registry.json deleted file mode 100644 index 07560cfc5..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/bitcoin/sequencer_registry.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "seq_rollup_address": "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94", - "seq_da_address": [ - 2, - 88, - 141, - 32, - 42, - 252, - 193, - 238, - 74, - 181, - 37, - 76, - 120, - 71, - 236, - 37, - 185, - 161, - 53, - 187, - 218, - 15, - 43, - 198, - 158, - 225, - 167, - 20, - 116, - 159, - 215, - 125, - 201 - ], - "coins_to_lock": { - "amount": 50, - "token_address": "sov1zsnx7n2wjvtkr0ttscfgt06pjca3v2e6stxeu49qwynavmk7a8xqlxkkjp" - }, - "is_preferred_sequencer": true -} \ No newline at end of file diff --git a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/bitcoin/soft_confirmation_rule_enforcer.json b/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/bitcoin/soft_confirmation_rule_enforcer.json deleted file mode 100644 index 0a0590216..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/bitcoin/soft_confirmation_rule_enforcer.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "max_l2_blocks_per_l1": 86400, - "authority": "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94", - "l1_fee_rate_change_percentage": 10 -} \ No newline at end of file diff --git a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/bitcoin/value_setter.json b/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/bitcoin/value_setter.json deleted file mode 100644 index 4e209004a..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/bitcoin/value_setter.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "admin": "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94" -} diff --git a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/celestia/accounts.json b/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/celestia/accounts.json deleted file mode 100644 index f65b078f6..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/celestia/accounts.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "pub_keys": [] -} diff --git a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/celestia/bank.json b/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/celestia/bank.json deleted file mode 100644 index d03fcc10f..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/celestia/bank.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "tokens": [ - { - "token_name": "sov-demo-token", - "address_and_balances": [ - [ - "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94", - 100000000 - ] - ], - "authorized_minters": [ - "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94" - ], - "salt": 0 - } - ] -} diff --git a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/celestia/evm.json b/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/celestia/evm.json deleted file mode 100644 index 22ff8f4d9..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/celestia/evm.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "data": [ - { - "address": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "balance": "0xffffffffffffffff", - "code": "0x" - } - ], - "chain_id": 5655, - "limit_contract_code_size": null, - "spec": { - "0": "SHANGHAI" - }, - "coinbase": "0x0000000000000000000000000000000000000000", - "starting_base_fee": 1000000000, - "block_gas_limit": 30000000, - "base_fee_params": { - "max_change_denominator": 8, - "elasticity_multiplier": 2 - }, - "timestamp": 0, - "difficulty": 0, - "extra_data": "0x", - "nonce": 0 -} \ No newline at end of file diff --git a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/celestia/sequencer_registry.json b/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/celestia/sequencer_registry.json deleted file mode 100644 index 205f31e8a..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/celestia/sequencer_registry.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "seq_rollup_address": "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94", - "seq_da_address": [ - 2, - 88, - 141, - 32, - 42, - 252, - 193, - 238, - 74, - 181, - 37, - 76, - 120, - 71, - 236, - 37, - 185, - 161, - 53, - 187, - 218, - 15, - 43, - 198, - 158, - 225, - 167, - 20, - 116, - 159, - 215, - 125, - 201 - ], - "coins_to_lock": { - "amount": 50, - "token_address": "sov1zsnx7n2wjvtkr0ttscfgt06pjca3v2e6stxeu49qwynavmk7a8xqlxkkjp" - }, - "is_preferred_sequencer": true -} diff --git a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/celestia/soft_confirmation_rule_enforcer.json b/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/celestia/soft_confirmation_rule_enforcer.json deleted file mode 100644 index 0a0590216..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/celestia/soft_confirmation_rule_enforcer.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "max_l2_blocks_per_l1": 86400, - "authority": "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94", - "l1_fee_rate_change_percentage": 10 -} \ No newline at end of file diff --git a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/celestia/value_setter.json b/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/celestia/value_setter.json deleted file mode 100644 index 4e209004a..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/celestia/value_setter.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "admin": "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94" -} diff --git a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/mock/accounts.json b/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/mock/accounts.json deleted file mode 100644 index f65b078f6..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/mock/accounts.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "pub_keys": [] -} diff --git a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/mock/bank.json b/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/mock/bank.json deleted file mode 100644 index d03fcc10f..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/mock/bank.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "tokens": [ - { - "token_name": "sov-demo-token", - "address_and_balances": [ - [ - "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94", - 100000000 - ] - ], - "authorized_minters": [ - "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94" - ], - "salt": 0 - } - ] -} diff --git a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/mock/evm.json b/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/mock/evm.json deleted file mode 100644 index 35b1d3196..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/mock/evm.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "data": [ - { - "address": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "balance": "0xffffffffffffffffffffffffffffff", - "code": "0x" - }, - { - "address": "0x66f68692c03eB9C0656D676f2F4bD13eba40D1B7", - "balance": "0xffffffffffffffffffffffffffffff", - "code": "0x" - }, - { - "address": "0xaafB7442f7F00B64057C2e9EaE2815bb63Ee0EcE", - "balance": "0xffffffffffffffffffffffffffffff", - "code": "0x" - }, - { - "address": "0x9fCDf8f60d3009656E50Bf805Cd53C7335b284Fb", - "balance": "0xffffffffffffffffffffffffffffff", - "code": "0x" - }, - { - "address": "0xe756fdf89367EF428b48BCa2d272Ec8EcEC053fD", - "balance": "0xffffffffffffffffffffffffffffff", - "code": "0x" - }, - { - "address": "0x3AEEb871F83C85E68fFD1868bef3425eD6649D39", - "balance": "0xffffffffffffffffffffffffffffff", - "code": "0x" - }, - { - "address": "0xd44821f906E3909b8AE944F7060551c33b922cc9", - "balance": "0xffffffffffffffffffffffffffffff", - "code": "0x" - }, - { - "address": "0x0f820f428AE436C1000b27577bF5bbf09BfeC8f2", - "balance": "0xffffffffffffffffffffffffffffff", - "code": "0x" - }, - { - "address": "0xC2F8Eed77da1583f7bae0a3125Dc7BC426002dDE", - "balance": "0xffffffffffffffffffffffffffffff", - "code": "0x" - } - ], - "chain_id": 5655, - "limit_contract_code_size": null, - "spec": { - "0": "SHANGHAI" - }, - "coinbase": "0x0000000000000000000000000000000000000000", - "starting_base_fee": 1000000000, - "block_gas_limit": 30000000, - "base_fee_params": { - "max_change_denominator": 8, - "elasticity_multiplier": 2 - }, - "timestamp": 0, - "difficulty": 0, - "extra_data": "0x", - "nonce": 0 -} \ No newline at end of file diff --git a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/mock/sequencer_registry.json b/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/mock/sequencer_registry.json deleted file mode 100644 index fe2696ae5..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/mock/sequencer_registry.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "seq_rollup_address": "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94", - "seq_da_address": "0000000000000000000000000000000000000000000000000000000000000000", - "coins_to_lock": { - "amount": 50, - "token_address": "sov1zsnx7n2wjvtkr0ttscfgt06pjca3v2e6stxeu49qwynavmk7a8xqlxkkjp" - }, - "is_preferred_sequencer": true -} diff --git a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/mock/soft_confirmation_rule_enforcer.json b/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/mock/soft_confirmation_rule_enforcer.json deleted file mode 100644 index 0a0590216..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/mock/soft_confirmation_rule_enforcer.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "max_l2_blocks_per_l1": 86400, - "authority": "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94", - "l1_fee_rate_change_percentage": 10 -} \ No newline at end of file diff --git a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/mock/value_setter.json b/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/mock/value_setter.json deleted file mode 100644 index 4e209004a..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/demo-tests/mock/value_setter.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "admin": "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94" -} diff --git a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests-low-limiting-number/accounts.json b/crates/sovereign-sdk/examples/test-data/genesis/integration-tests-low-limiting-number/accounts.json deleted file mode 100644 index f65b078f6..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests-low-limiting-number/accounts.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "pub_keys": [] -} diff --git a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests-low-limiting-number/bank.json b/crates/sovereign-sdk/examples/test-data/genesis/integration-tests-low-limiting-number/bank.json deleted file mode 100644 index 8a1b6f721..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests-low-limiting-number/bank.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "tokens": [ - { - "token_name": "sov-demo-token", - "address_and_balances": [ - [ - "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94", - 100000000 - ] - ], - "authorized_minters": [ - "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94" - ], - "salt": 0 - } - ] -} \ No newline at end of file diff --git a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests-low-limiting-number/evm.json b/crates/sovereign-sdk/examples/test-data/genesis/integration-tests-low-limiting-number/evm.json deleted file mode 100644 index 22ff8f4d9..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests-low-limiting-number/evm.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "data": [ - { - "address": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "balance": "0xffffffffffffffff", - "code": "0x" - } - ], - "chain_id": 5655, - "limit_contract_code_size": null, - "spec": { - "0": "SHANGHAI" - }, - "coinbase": "0x0000000000000000000000000000000000000000", - "starting_base_fee": 1000000000, - "block_gas_limit": 30000000, - "base_fee_params": { - "max_change_denominator": 8, - "elasticity_multiplier": 2 - }, - "timestamp": 0, - "difficulty": 0, - "extra_data": "0x", - "nonce": 0 -} \ No newline at end of file diff --git a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests-low-limiting-number/sequencer_registry.json b/crates/sovereign-sdk/examples/test-data/genesis/integration-tests-low-limiting-number/sequencer_registry.json deleted file mode 100644 index fe2696ae5..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests-low-limiting-number/sequencer_registry.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "seq_rollup_address": "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94", - "seq_da_address": "0000000000000000000000000000000000000000000000000000000000000000", - "coins_to_lock": { - "amount": 50, - "token_address": "sov1zsnx7n2wjvtkr0ttscfgt06pjca3v2e6stxeu49qwynavmk7a8xqlxkkjp" - }, - "is_preferred_sequencer": true -} diff --git a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests-low-limiting-number/soft_confirmation_rule_enforcer.json b/crates/sovereign-sdk/examples/test-data/genesis/integration-tests-low-limiting-number/soft_confirmation_rule_enforcer.json deleted file mode 100644 index f173af4e2..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests-low-limiting-number/soft_confirmation_rule_enforcer.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "max_l2_blocks_per_l1": 10, - "authority": "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94", - "l1_fee_rate_change_percentage": 10 -} \ No newline at end of file diff --git a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests-low-limiting-number/value_setter.json b/crates/sovereign-sdk/examples/test-data/genesis/integration-tests-low-limiting-number/value_setter.json deleted file mode 100644 index 4e209004a..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests-low-limiting-number/value_setter.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "admin": "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94" -} diff --git a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests/accounts.json b/crates/sovereign-sdk/examples/test-data/genesis/integration-tests/accounts.json deleted file mode 100644 index f65b078f6..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests/accounts.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "pub_keys": [] -} diff --git a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests/bank.json b/crates/sovereign-sdk/examples/test-data/genesis/integration-tests/bank.json deleted file mode 100644 index 8a1b6f721..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests/bank.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "tokens": [ - { - "token_name": "sov-demo-token", - "address_and_balances": [ - [ - "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94", - 100000000 - ] - ], - "authorized_minters": [ - "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94" - ], - "salt": 0 - } - ] -} \ No newline at end of file diff --git a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests/evm.json b/crates/sovereign-sdk/examples/test-data/genesis/integration-tests/evm.json deleted file mode 100644 index 7a99c64d3..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests/evm.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "data": [ - { - "address": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "balance": "0xffffffffffffffffffffff", - "code": "0x" - } - ], - "chain_id": 5655, - "limit_contract_code_size": null, - "spec": { - "0": "SHANGHAI" - }, - "coinbase": "0x0000000000000000000000000000000000000000", - "starting_base_fee": 1000000000, - "block_gas_limit": 30000000, - "base_fee_params": { - "max_change_denominator": 8, - "elasticity_multiplier": 2 - }, - "timestamp": 0, - "difficulty": 0, - "extra_data": "0x", - "nonce": 0 -} \ No newline at end of file diff --git a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests/sequencer_registry.json b/crates/sovereign-sdk/examples/test-data/genesis/integration-tests/sequencer_registry.json deleted file mode 100644 index fe2696ae5..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests/sequencer_registry.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "seq_rollup_address": "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94", - "seq_da_address": "0000000000000000000000000000000000000000000000000000000000000000", - "coins_to_lock": { - "amount": 50, - "token_address": "sov1zsnx7n2wjvtkr0ttscfgt06pjca3v2e6stxeu49qwynavmk7a8xqlxkkjp" - }, - "is_preferred_sequencer": true -} diff --git a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests/soft_confirmation_rule_enforcer.json b/crates/sovereign-sdk/examples/test-data/genesis/integration-tests/soft_confirmation_rule_enforcer.json deleted file mode 100644 index 3bec25a59..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests/soft_confirmation_rule_enforcer.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "max_l2_blocks_per_l1": 86400, - "authority": "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94", - "l1_fee_rate_change_percentage": 10 - -} \ No newline at end of file diff --git a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests/value_setter.json b/crates/sovereign-sdk/examples/test-data/genesis/integration-tests/value_setter.json deleted file mode 100644 index 4e209004a..000000000 --- a/crates/sovereign-sdk/examples/test-data/genesis/integration-tests/value_setter.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "admin": "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94" -} diff --git a/crates/sovereign-sdk/examples/test-data/keys/minter_private_key.json b/crates/sovereign-sdk/examples/test-data/keys/minter_private_key.json deleted file mode 100644 index ab9e24319..000000000 --- a/crates/sovereign-sdk/examples/test-data/keys/minter_private_key.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "private_key": { - "key_pair": [ - 35, 110, 128, 203, 34, 44, 78, 208, 67, 27, 9, 59, 58, 197, 62, 106, 167, - 162, 39, 63, 225, 244, 53, 28, 211, 84, 152, 154, 130, 52, 50, 162 - ] - }, - "address": "sov15vspj48hpttzyvxu8kzq5klhvaczcpyxn6z6k0hwpwtzs4a6wkvqwr57gc" -} diff --git a/crates/sovereign-sdk/examples/test-data/keys/token_deployer_private_key.json b/crates/sovereign-sdk/examples/test-data/keys/token_deployer_private_key.json deleted file mode 100644 index b09514aa4..000000000 --- a/crates/sovereign-sdk/examples/test-data/keys/token_deployer_private_key.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "private_key": { - "key_pair": [ - 117, 251, 248, 217, 135, 70, 194, 105, 46, 80, 41, 66, 185, 56, 200, 35, - 121, 253, 9, 234, 159, 91, 96, 212, 211, 158, 135, 225, 180, 36, 104, 253 - ] - }, - "address": "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94" -} diff --git a/crates/sovereign-sdk/examples/test-data/keys/tx_signer_private_key.json b/crates/sovereign-sdk/examples/test-data/keys/tx_signer_private_key.json deleted file mode 100644 index 231d87a28..000000000 --- a/crates/sovereign-sdk/examples/test-data/keys/tx_signer_private_key.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "private_key": { - "key_pair": [ - 39, 195, 119, 77, 82, 231, 30, 162, 102, 169, 197, 37, 108, 217, 139, 154, - 230, 126, 98, 242, 174, 94, 211, 74, 102, 141, 184, 234, 168, 62, 27, 172 - ] - }, - "address": "sov1dnhqk4mdsj2kwv4xymt8a624xuahfx8906j9usdkx7ensfghndkq8p33f7" -} diff --git a/crates/sovereign-sdk/examples/test-data/requests/burn.json b/crates/sovereign-sdk/examples/test-data/requests/burn.json deleted file mode 100644 index 991b5aaa0..000000000 --- a/crates/sovereign-sdk/examples/test-data/requests/burn.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Burn": { - "coins": { - "amount": 300, - "token_address": "sov16m8fxq0x5wc5aw75fx9rus2p7g2l22zf4re72c3m058g77cdjemsavg2ft" - } - } -} diff --git a/crates/sovereign-sdk/examples/test-data/requests/create_token.json b/crates/sovereign-sdk/examples/test-data/requests/create_token.json deleted file mode 100644 index 7b792ac5f..000000000 --- a/crates/sovereign-sdk/examples/test-data/requests/create_token.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "CreateToken": { - "salt": 11, - "token_name": "sov-test-token", - "initial_balance": 1000, - "minter_address": "sov15vspj48hpttzyvxu8kzq5klhvaczcpyxn6z6k0hwpwtzs4a6wkvqwr57gc", - "authorized_minters": [ - "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94", - "sov15vspj48hpttzyvxu8kzq5klhvaczcpyxn6z6k0hwpwtzs4a6wkvqwr57gc" - ] - } -} diff --git a/crates/sovereign-sdk/examples/test-data/requests/mint.json b/crates/sovereign-sdk/examples/test-data/requests/mint.json deleted file mode 100644 index aeb6e9236..000000000 --- a/crates/sovereign-sdk/examples/test-data/requests/mint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Mint": { - "coins": { - "amount": 3000, - "token_address": "sov1zdwj8thgev2u3yyrrlekmvtsz4av4tp3m7dm5mx5peejnesga27svq9m72" - }, - "minter_address": "sov15vspj48hpttzyvxu8kzq5klhvaczcpyxn6z6k0hwpwtzs4a6wkvqwr57gc" - } -} diff --git a/crates/sovereign-sdk/examples/test-data/requests/nft/create_collection.json b/crates/sovereign-sdk/examples/test-data/requests/nft/create_collection.json deleted file mode 100644 index b51a9e409..000000000 --- a/crates/sovereign-sdk/examples/test-data/requests/nft/create_collection.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "CreateCollection": { - "name": "Test Collection", - "collection_uri": "https://foo.bar/test_collection" - } -} diff --git a/crates/sovereign-sdk/examples/test-data/requests/nft/freeze_collection.json b/crates/sovereign-sdk/examples/test-data/requests/nft/freeze_collection.json deleted file mode 100644 index bd6715c49..000000000 --- a/crates/sovereign-sdk/examples/test-data/requests/nft/freeze_collection.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "FreezeCollection": { - "collection_name": "Test Collection" - } -} diff --git a/crates/sovereign-sdk/examples/test-data/requests/nft/update_token_uri.json b/crates/sovereign-sdk/examples/test-data/requests/nft/update_token_uri.json deleted file mode 100644 index f4bedf769..000000000 --- a/crates/sovereign-sdk/examples/test-data/requests/nft/update_token_uri.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "UpdateNft": { - "collection_address": "sov1j2e3dh76nmuw4gctrqduh0wzqdny8c62z36r2q3883rknw3ky3vsk9g02a", - "token_id": 42, - "token_uri": "https://foo.bar/test_collection/nft_new/42", - "frozen": null - } -} diff --git a/crates/sovereign-sdk/examples/test-data/requests/register_sequencer.json b/crates/sovereign-sdk/examples/test-data/requests/register_sequencer.json deleted file mode 100644 index 1b8f0fa9c..000000000 --- a/crates/sovereign-sdk/examples/test-data/requests/register_sequencer.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Register": { - "da_address": [ - 13, 5, 25, 31, 28, 30, 5, 27, 20, 6, 29, 10, 14, 29, 20, 12, 22, 13, 19, - 1, 0, 11, 9, 15, 23, 13, 14, 1, 9, 27, 9, 14 - ] - } -} diff --git a/crates/sovereign-sdk/examples/test-data/requests/transfer.json b/crates/sovereign-sdk/examples/test-data/requests/transfer.json deleted file mode 100644 index dac1d8638..000000000 --- a/crates/sovereign-sdk/examples/test-data/requests/transfer.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Transfer": { - "to": "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqklh0qh", - "coins": { - "amount": 200, - "token_address": "sov1zdwj8thgev2u3yyrrlekmvtsz4av4tp3m7dm5mx5peejnesga27svq9m72" - } - } -} diff --git a/crates/sovereign-sdk/fuzz/Cargo.lock b/crates/sovereign-sdk/fuzz/Cargo.lock index 756266110..0fbee0cf6 100644 --- a/crates/sovereign-sdk/fuzz/Cargo.lock +++ b/crates/sovereign-sdk/fuzz/Cargo.lock @@ -2255,17 +2255,14 @@ dependencies = [ "arbitrary", "bcs", "borsh", - "hex", "jmt", "proptest", "proptest-derive", "serde", - "serde_json", "sha2", "sov-db", "sov-modules-core", "sov-rollup-interface", - "thiserror", ] [[package]] diff --git a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-accessory-state/Cargo.toml b/crates/sovereign-sdk/module-system/module-implementations/examples/sov-accessory-state/Cargo.toml deleted file mode 100644 index e2df25e68..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-accessory-state/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -[package] -name = "sov-accessory-state" -authors = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -repository = { workspace = true } - -version = { workspace = true } -readme = "README.md" -publish = false -resolver = "2" - -[dependencies] -jsonrpsee = { workspace = true, features = ["macros", "client-core", "server"], optional = true } -sov-modules-api = { path = "../../../sov-modules-api", default-features = false, features = ["macros"] } -sov-state = { path = "../../../sov-state" } -serde = { workspace = true, optional = true } -borsh = { workspace = true, features = ["rc"] } - -[dev-dependencies] -tempfile = { workspace = true } -sov-prover-storage-manager = { path = "../../../../full-node/sov-prover-storage-manager", features = ["test-utils"] } - -[features] -default = [] -native = ["serde", "sov-modules-api/native", "dep:jsonrpsee"] diff --git a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-accessory-state/README.md b/crates/sovereign-sdk/module-system/module-implementations/examples/sov-accessory-state/README.md deleted file mode 100644 index de24103e3..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-accessory-state/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# The `sov-accessory-state` module - -This module has no useful functionality, but it illustrates the ability to store data outside of the JMT, called "accessory state". - -Accessory state does not contribute to the state root hash and can be written during zkVM execution, but reads are only allowed in a native execution context. Accessory state data can be used for tooling, serving JSON-RPC data, debugging, and any other purpose that is not core to the core functioning of the module without incurring in major performance penalties. diff --git a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-accessory-state/src/lib.rs b/crates/sovereign-sdk/module-system/module-implementations/examples/sov-accessory-state/src/lib.rs deleted file mode 100644 index 08f0b95f1..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-accessory-state/src/lib.rs +++ /dev/null @@ -1,74 +0,0 @@ -#![deny(missing_docs)] -#![doc = include_str!("../README.md")] - -#[cfg(feature = "native")] -mod query; - -#[cfg(feature = "native")] -pub use query::*; -use sov_modules_api::prelude::*; -use sov_modules_api::{ - AccessoryStateValue, CallResponse, Context, Error, Module, ModuleInfo, StateValue, WorkingSet, -}; - -/// [`AccessorySetter`] is a module that stores data both *inside* the JMT and -/// *outside* the JMT. -/// -/// Data stored inside the JMT contributes to the state root hash, and is always -/// accessible. This costs significant compute, and should be avoided for all -/// data that is not necessary to the core functioning of the rollup. Other data -/// that facilitates serving queries over JSON-RPC or only accessed by tooling -/// doesn't need to be verifiable, and can thus be stored outside the JMT much -/// more cheaply. Since accessory data is not included in the state root hash, -/// it is not accessible inside the zkVM and can only be accessed with -/// `#[cfg(feature = "native")]`. -#[derive(ModuleInfo)] -pub struct AccessorySetter { - /// The address of the module. - #[address] - pub address: C::Address, - /// Some arbitrary value stored in the JMT to demonstrate the difference - /// between the JMT and accessory state. - #[state] - pub state_value: StateValue, - /// A non-JMT value stored in the accessory state. - #[state] - pub accessory_value: AccessoryStateValue, -} - -/// The [`Module::CallMessage`] for [`AccessorySetter`]. -#[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Debug, PartialEq)] -pub enum CallMessage { - /// Sets the value of [`AccessorySetter::state_value`]. - SetValue(String), - /// Stores some arbitrary value in the accessory state. - SetValueAccessory(String), -} - -impl Module for AccessorySetter { - type Context = C; - - type Config = (); - - type CallMessage = CallMessage; - - type Event = (); - - fn call( - &mut self, - msg: Self::CallMessage, - _context: &Self::Context, - working_set: &mut WorkingSet, - ) -> Result { - match msg { - CallMessage::SetValueAccessory(new_value) => { - self.accessory_value - .set(&new_value, &mut working_set.accessory_state()); - } - CallMessage::SetValue(new_value) => { - self.state_value.set(&new_value, working_set); - } - }; - Ok(CallResponse::default()) - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-accessory-state/src/query.rs b/crates/sovereign-sdk/module-system/module-implementations/examples/sov-accessory-state/src/query.rs deleted file mode 100644 index b6f015e12..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-accessory-state/src/query.rs +++ /dev/null @@ -1,27 +0,0 @@ -//! JSON-RPC server implementation for the [`AccessorySetter`] module. - -use jsonrpsee::core::RpcResult; -use sov_modules_api::macros::rpc_gen; -use sov_modules_api::prelude::*; -use sov_modules_api::WorkingSet; - -use super::AccessorySetter; - -/// Response type to the `accessorySetter_value` endpoint. -#[derive(Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, Clone)] -pub struct ValueResponse { - /// The value stored in the accessory state. - pub value: Option, -} - -#[rpc_gen(client, server, namespace = "accessorySetter")] -impl AccessorySetter { - /// Returns the latest value set in the accessory state via - /// [`CallMessage::SetValueAccessory`](crate::CallMessage::SetValueAccessory). - #[rpc_method(name = "value")] - pub fn query_value(&self, working_set: &mut WorkingSet) -> RpcResult { - Ok(ValueResponse { - value: self.accessory_value.get(&mut working_set.accessory_state()), - }) - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-accessory-state/tests/test.rs b/crates/sovereign-sdk/module-system/module-implementations/examples/sov-accessory-state/tests/test.rs deleted file mode 100644 index 2a335d17a..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-accessory-state/tests/test.rs +++ /dev/null @@ -1,73 +0,0 @@ -#![cfg(feature = "native")] - -use sov_accessory_state::{AccessorySetter, CallMessage}; -use sov_modules_api::default_context::DefaultContext; -use sov_modules_api::prelude::*; -use sov_modules_api::{Address, Context, Module, SpecId, WorkingSet}; -use sov_prover_storage_manager::new_orphan_storage; -use sov_state::Storage; - -#[test] -/// Check that: -/// 1. Accessory state does not change normal state root hash -/// 2. Accessory state is saved to underlying the database -fn test_accessory_value_setter() { - let tmpdir = tempfile::tempdir().unwrap(); - let storage = new_orphan_storage(tmpdir.path()).unwrap(); - let mut working_set_for_state = WorkingSet::new(storage.clone()); - let mut working_set_for_accessory = WorkingSet::new(storage.clone()); - let mut working_set_for_check: WorkingSet = WorkingSet::new(storage.clone()); - - let admin = Address::from([1; 32]); - let sequencer = Address::from([2; 32]); - let context = DefaultContext::new(admin, sequencer, 1, SpecId::Genesis, 0); - - let mut module = AccessorySetter::::default(); - - module.genesis(&(), &mut working_set_for_state).unwrap(); - module - .call( - CallMessage::SetValue("FooBar".to_string()), - &context, - &mut working_set_for_state, - ) - .unwrap(); - - let (reads_writes, mut witness) = working_set_for_state.checkpoint().freeze(); - let state_root_hash = storage - .validate_and_commit(reads_writes, &mut witness) - .unwrap(); - - module - .call( - CallMessage::SetValueAccessory("FooBar".to_string()), - &context, - &mut working_set_for_accessory, - ) - .unwrap(); - - let mut checkpoint = working_set_for_accessory.checkpoint(); - let (reads_writes, mut witness) = checkpoint.freeze(); - let accessory_writes = checkpoint.freeze_non_provable(); - let state_root_hash_2 = storage - .validate_and_commit_with_accessory_update(reads_writes, &mut witness, &accessory_writes) - .unwrap(); - - assert_eq!( - Some("FooBar".to_string()), - module.state_value.get(&mut working_set_for_check), - "Provable state has not been propagated to the underlying storage!" - ); - assert_eq!( - Some("FooBar".to_string()), - module - .accessory_value - .get(&mut working_set_for_check.accessory_state()), - "Accessory state has not been propagated to the underlying storage!" - ); - - assert_eq!( - state_root_hash, state_root_hash_2, - "Accessory update has affected the state root hash!" - ); -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter/Cargo.toml b/crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter/Cargo.toml deleted file mode 100644 index 9c60aa694..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -name = "sov-value-setter" -description = "A Sovereign SDK example module for setting/reading value from state" -authors = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -repository = { workspace = true } - -version = { workspace = true } -readme = "README.md" -resolver = "2" -publish = false - - -[dev-dependencies] -tempfile = { workspace = true } -sov-modules-api = { path = "../../../sov-modules-api", features = ["native"] } -sov-prover-storage-manager = { path = "../../../../full-node/sov-prover-storage-manager", features = ["test-utils"] } - - -[dependencies] -anyhow = { workspace = true } -sov-modules-api = { path = "../../../sov-modules-api" } -sov-state = { path = "../../../sov-state" } -schemars = { workspace = true, optional = true } -serde = { workspace = true } -serde_json = { workspace = true, optional = true } -thiserror = { workspace = true } -borsh = { workspace = true, features = ["rc"] } -jsonrpsee = { workspace = true, features = ["macros", "client-core", "server"], optional = true } -clap = { workspace = true, optional = true } - -[features] -default = ["native"] -native = ["serde", "serde_json", "jsonrpsee", "schemars", "clap", "sov-modules-api/native", "sov-state/native"] -serde = [] diff --git a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter/README.md b/crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter/README.md deleted file mode 100644 index 67241ad53..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# An example of a `SOV-MODULE` - -It demonstrates the following concepts: - -### 1. Module structure: - -- `lib.rs` contains `ValueSetter` module definition and `sov_modules_api::Module` trait implementation for `ValueSetter`. -- `genesis.rs` contains the module initialization logic. -- `call.rs` contains methods that change module state in response to `CallMessage`. -- `query.rs` contains functions for querying the module state. - -### 2. Functionality: - -The `admin` (specified in the `ValueSetter` genesis) can update a single `u32` value by creating `CallMessage::SetValue(new_value)` message. Anyone can query the module state by calling the `valueSetter_queryValue` endpoint. - -For implementation details, please check comments in the `genesis.rs, call.rs & query.rs`. \ No newline at end of file diff --git a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter/src/call.rs b/crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter/src/call.rs deleted file mode 100644 index 1e043245c..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter/src/call.rs +++ /dev/null @@ -1,57 +0,0 @@ -use std::fmt::Debug; - -use anyhow::Result; -#[cfg(feature = "native")] -use sov_modules_api::macros::CliWalletArg; -use sov_modules_api::prelude::*; -use sov_modules_api::{CallResponse, WorkingSet}; -use thiserror::Error; - -use super::ValueSetter; - -/// This enumeration represents the available call messages for interacting with the `sov-value-setter` module. -#[cfg_attr(feature = "native", derive(CliWalletArg), derive(schemars::JsonSchema))] -#[cfg_attr( - feature = "serde", - derive(serde::Serialize), - derive(serde::Deserialize) -)] -#[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Debug, PartialEq, Clone)] -pub enum CallMessage { - /// value to set - SetValue( - /// new value - u32, - ), -} - -/// Example of a custom error. -#[derive(Debug, Error)] -enum SetValueError { - #[error("Only admin can change the value")] - WrongSender, -} - -impl ValueSetter { - /// Sets `value` field to the `new_value`, only admin is authorized to call this method. - pub(crate) fn set_value( - &self, - new_value: u32, - context: &C, - working_set: &mut WorkingSet, - ) -> Result { - // If admin is not then early return: - let admin = self.admin.get_or_err(working_set)?; - - if &admin != context.sender() { - // Here we use a custom error type. - Err(SetValueError::WrongSender)?; - } - - // This is how we set a new value: - self.value.set(&new_value, working_set); - working_set.add_event("set", &format!("value_set: {new_value:?}")); - - Ok(CallResponse::default()) - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter/src/genesis.rs b/crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter/src/genesis.rs deleted file mode 100644 index fc1c9167c..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter/src/genesis.rs +++ /dev/null @@ -1,46 +0,0 @@ -use anyhow::Result; -use sov_modules_api::prelude::*; -use sov_modules_api::WorkingSet; - -use super::ValueSetter; - -/// Initial configuration for sov-value-setter module. -#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq)] -pub struct ValueSetterConfig { - /// Admin of the module. - pub admin: C::Address, -} - -impl ValueSetter { - /// Initializes module with the `admin` role. - pub(crate) fn init_module( - &self, - admin_config: &::Config, - working_set: &mut WorkingSet, - ) -> Result<()> { - self.admin.set(&admin_config.admin, working_set); - Ok(()) - } -} - -#[cfg(all(test, feature = "native"))] -mod tests { - use sov_modules_api::default_context::DefaultContext; - use sov_modules_api::Address; - - use crate::ValueSetterConfig; - - #[test] - fn test_config_serialization() { - let admin = Address::from([1; 32]); - let config = ValueSetterConfig:: { admin }; - - let data = r#" - { - "admin":"sov1qyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqs259tk3" - }"#; - - let parsed_config: ValueSetterConfig = serde_json::from_str(data).unwrap(); - assert_eq!(parsed_config, config); - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter/src/lib.rs b/crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter/src/lib.rs deleted file mode 100644 index aad68efaf..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter/src/lib.rs +++ /dev/null @@ -1,64 +0,0 @@ -#![deny(missing_docs)] -#![doc = include_str!("../README.md")] -mod call; -mod genesis; - -#[cfg(all(test, feature = "native"))] -mod tests; - -#[cfg(feature = "native")] -mod query; - -pub use call::*; -pub use genesis::*; -#[cfg(feature = "native")] -pub use query::*; -use sov_modules_api::{Error, ModuleInfo, WorkingSet}; - -/// A new module: -/// - Must derive `ModuleInfo` -/// - Must contain `[address]` field -/// - Can contain any number of ` #[state]` or `[module]` fields -#[cfg_attr(feature = "native", derive(sov_modules_api::ModuleCallJsonSchema))] -#[derive(ModuleInfo)] -pub struct ValueSetter { - /// Address of the module. - #[address] - pub address: C::Address, - - /// Some value kept in the state. - #[state] - pub value: sov_modules_api::StateValue, - - /// Holds the address of the admin user who is allowed to update the value. - #[state] - pub admin: sov_modules_api::StateValue, -} - -impl sov_modules_api::Module for ValueSetter { - type Context = C; - - type Config = ValueSetterConfig; - - type CallMessage = call::CallMessage; - - type Event = (); - - fn genesis(&self, config: &Self::Config, working_set: &mut WorkingSet) -> Result<(), Error> { - // The initialization logic - Ok(self.init_module(config, working_set)?) - } - - fn call( - &mut self, - msg: Self::CallMessage, - context: &Self::Context, - working_set: &mut WorkingSet, - ) -> Result { - match msg { - call::CallMessage::SetValue(new_value) => { - Ok(self.set_value(new_value, context, working_set)?) - } - } - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter/src/query.rs b/crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter/src/query.rs deleted file mode 100644 index 098d1e118..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter/src/query.rs +++ /dev/null @@ -1,25 +0,0 @@ -//! Defines rpc queries exposed by the module -use jsonrpsee::core::RpcResult; -use sov_modules_api::macros::rpc_gen; -use sov_modules_api::prelude::*; -use sov_modules_api::WorkingSet; - -use super::ValueSetter; - -/// Response returned from the valueSetter_queryValue endpoint. -#[derive(serde::Serialize, serde::Deserialize, Debug, Eq, PartialEq, Clone)] -pub struct Response { - /// Value saved in the module's state. - pub value: Option, -} - -#[rpc_gen(client, server, namespace = "valueSetter")] -impl ValueSetter { - /// Queries the state of the module. - #[rpc_method(name = "queryValue")] - pub fn query_value(&self, working_set: &mut WorkingSet) -> RpcResult { - Ok(Response { - value: self.value.get(working_set), - }) - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter/src/tests.rs b/crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter/src/tests.rs deleted file mode 100644 index 2d356ff43..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-value-setter/src/tests.rs +++ /dev/null @@ -1,110 +0,0 @@ -use sov_modules_api::default_context::{DefaultContext, ZkDefaultContext}; -use sov_modules_api::{Address, Context, Event, Module, WorkingSet}; -use sov_prover_storage_manager::new_orphan_storage; -use sov_state::ZkStorage; - -use super::ValueSetter; -use crate::{call, query, ValueSetterConfig}; - -#[test] -fn test_value_setter() { - let tmpdir = tempfile::tempdir().unwrap(); - let mut working_set = WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - let admin = Address::from([1; 32]); - let sequencer = Address::from([2; 32]); - // Test Native-Context - #[cfg(feature = "native")] - { - let config = ValueSetterConfig { admin }; - let context = DefaultContext::new(admin, sequencer, 1, sov_modules_api::SpecId::Genesis, 0); - test_value_setter_helper(context, &config, &mut working_set); - } - - let (_, witness) = working_set.checkpoint().freeze(); - - // Test Zk-Context - { - let config = ValueSetterConfig { admin }; - let zk_context = - ZkDefaultContext::new(admin, sequencer, 1, sov_modules_api::SpecId::Genesis, 0); - let mut zk_working_set = WorkingSet::with_witness(ZkStorage::new(), witness); - test_value_setter_helper(zk_context, &config, &mut zk_working_set); - } -} - -fn test_value_setter_helper( - context: C, - config: &ValueSetterConfig, - working_set: &mut WorkingSet, -) { - let mut module = ValueSetter::::default(); - module.genesis(config, working_set).unwrap(); - - let new_value = 99; - let call_msg = call::CallMessage::SetValue(new_value); - - // Test events - { - module.call(call_msg, &context, working_set).unwrap(); - let event = &working_set.events()[0]; - assert_eq!(event, &Event::new("set", "value_set: 99")); - } - - // Test query - { - let query_response = module.query_value(working_set).unwrap(); - - assert_eq!( - query::Response { - value: Some(new_value) - }, - query_response - ) - } -} - -#[test] -fn test_err_on_sender_is_not_admin() { - let sender = Address::from([1; 32]); - let sequencer = Address::from([2; 32]); - - let tmpdir = tempfile::tempdir().unwrap(); - let storage = new_orphan_storage(tmpdir.path()).unwrap(); - let mut prover_working_set = WorkingSet::new(storage); - - let sender_not_admin = Address::from([2; 32]); - // Test Prover-Context - { - let config = ValueSetterConfig { - admin: sender_not_admin, - }; - let context = - DefaultContext::new(sender, sequencer, 1, sov_modules_api::SpecId::Genesis, 0); - test_err_on_sender_is_not_admin_helper(context, &config, &mut prover_working_set); - } - let (_, witness) = prover_working_set.checkpoint().freeze(); - - // Test Zk-Context - { - let config = ValueSetterConfig { - admin: sender_not_admin, - }; - let zk_backing_store = ZkStorage::new(); - let zk_context = - ZkDefaultContext::new(sender, sequencer, 1, sov_modules_api::SpecId::Genesis, 0); - 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); - } -} - -fn test_err_on_sender_is_not_admin_helper( - context: C, - config: &ValueSetterConfig, - working_set: &mut WorkingSet, -) { - let module = ValueSetter::::default(); - module.genesis(config, working_set).unwrap(); - let resp = module.set_value(11, &context, working_set); - - assert!(resp.is_err()); -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter/Cargo.toml b/crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter/Cargo.toml deleted file mode 100644 index 5219edf94..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter/Cargo.toml +++ /dev/null @@ -1,34 +0,0 @@ -[package] -name = "sov-vec-setter" -description = "A Sovereign SDK example module for setting/reading vectors from state" -authors = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -repository = { workspace = true } - -version = { workspace = true } -readme = "README.md" -resolver = "2" -publish = false - -[dev-dependencies] -tempfile = { workspace = true } -sov-modules-api = { path = "../../../sov-modules-api", features = ["native", "macros"] } -sov-prover-storage-manager = { path = "../../../../full-node/sov-prover-storage-manager", features = ["test-utils"] } - -[dependencies] -anyhow = { workspace = true } -sov-modules-api = { path = "../../../sov-modules-api", default-features = false, features = ["macros"] } -sov-state = { path = "../../../sov-state", default-features = false } -schemars = { workspace = true, optional = true } -serde = { workspace = true } -serde_json = { workspace = true, optional = true } -thiserror = { workspace = true } -borsh = { workspace = true, features = ["rc"] } -jsonrpsee = { workspace = true, features = ["macros", "client-core", "server"], optional = true } -clap = { workspace = true, optional = true } - -[features] -default = ["native"] -native = ["serde_json", "jsonrpsee", "schemars", "clap", "sov-modules-api/native"] diff --git a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter/README.md b/crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter/README.md deleted file mode 100644 index ad83f8ed3..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# An example of a `SOV-MODULE` - -It demonstrates the following concepts: - -### 1. Module structure: - -- `lib.rs` contains `VecSetter` module definition and `sov_modules_api::Module` trait implementation for `VecSetter`. -- `genesis.rs` contains the module initialization logic. -- `call.rs` contains methods that change module state in response to `CallMessage`. -- `query.rs` contains functions for querying the module state. - -### 2. Functionality: - -The `admin` (specified in the `VecSetter` genesis) can update a single `u32` value by creating `CallMessage::SetValue(new_value)` message. Anyone can query the module state by calling the `vecSetter_queryValue` endpoint. - -For implementation details, please check comments in the `genesis.rs, call.rs & query.rs`. \ No newline at end of file diff --git a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter/src/call.rs b/crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter/src/call.rs deleted file mode 100644 index 2a17c4f93..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter/src/call.rs +++ /dev/null @@ -1,151 +0,0 @@ -use std::fmt::Debug; - -use anyhow::Result; -#[cfg(feature = "native")] -use sov_modules_api::macros::CliWalletArg; -use sov_modules_api::prelude::*; -use sov_modules_api::{CallResponse, WorkingSet}; -use thiserror::Error; - -use super::VecSetter; - -/// This enumeration represents the available call messages for interacting with the `sov-vec-setter` module. -#[cfg_attr( - feature = "native", - derive(serde::Serialize), - derive(serde::Deserialize), - derive(CliWalletArg), - derive(schemars::JsonSchema) -)] -#[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Debug, PartialEq, Clone)] -pub enum CallMessage { - /// value to push - PushValue(u32), - /// value to set - SetValue { - /// index to set - index: usize, - /// value to set - value: u32, - }, - /// values to set - SetAllValues(Vec), - /// Pop - PopValue, -} - -/// Example of a custom error. -#[derive(Debug, Error)] -enum SetValueError { - #[error("Only admin can change the value")] - WrongSender, -} - -impl VecSetter { - /// Pushes `value` field to the `vector`, only admin is authorized to call this method. - pub(crate) fn push_value( - &self, - new_value: u32, - context: &C, - working_set: &mut WorkingSet, - ) -> Result { - // If admin is not then early return: - let admin = self.admin.get_or_err(working_set)?; - - if &admin != context.sender() { - // Here we use a custom error type. - Err(SetValueError::WrongSender)?; - } - - // This is how we push a new value to vector: - self.vector.push(&new_value, working_set); - - let new_length = self.vector.len(working_set); - - working_set.add_event( - "push", - &format!("value_push: {new_value:?}, new length: {new_length:?}"), - ); - - Ok(CallResponse::default()) - } - - /// Sets `value` field to the given index of `vector`, only admin is authorized to call this method. - pub(crate) fn set_value( - &self, - index: usize, - new_value: u32, - context: &C, - working_set: &mut WorkingSet, - ) -> Result { - // If admin is not then early return: - let admin = self.admin.get_or_err(working_set)?; - - if &admin != context.sender() { - // Here we use a custom error type. - Err(SetValueError::WrongSender)?; - } - - // This is how we set a new value: - self.vector.set(index, &new_value, working_set)?; - - working_set.add_event( - "set", - &format!("value_set: {new_value:?} for index: {index:?}"), - ); - - Ok(CallResponse::default()) - } - - /// Sets `values` completely to the `vector`, only admin is authorized to call this method. - pub(crate) fn set_all_values( - &self, - values: Vec, - context: &C, - working_set: &mut WorkingSet, - ) -> Result { - // If admin is not then early return: - let admin = self.admin.get_or_err(working_set)?; - - if &admin != context.sender() { - // Here we use a custom error type. - Err(SetValueError::WrongSender)?; - } - - // This is how we set all the vector: - self.vector.set_all(values, working_set); - - let new_length = self.vector.len(working_set); - - working_set.add_event("set_all", &format!("new length: {new_length:?}")); - - Ok(CallResponse::default()) - } - - /// Pops last value from the `vector`, only admin is authorized to call this method. - pub(crate) fn pop_value( - &self, - context: &C, - working_set: &mut WorkingSet, - ) -> Result { - // If admin is not then early return: - let admin = self.admin.get_or_err(working_set)?; - - if &admin != context.sender() { - // Here we use a custom error type. - Err(SetValueError::WrongSender)?; - } - - // This is how we pop last value value: - let pop_value = self.vector.pop(working_set); - - let new_length = self.vector.len(working_set); - - working_set.add_event( - "pop", - &format!("value_pop: {pop_value:?}, new length: {new_length:?}"), - ); - - Ok(CallResponse::default()) - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter/src/genesis.rs b/crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter/src/genesis.rs deleted file mode 100644 index 9f8c3c13f..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter/src/genesis.rs +++ /dev/null @@ -1,17 +0,0 @@ -use anyhow::Result; -use sov_modules_api::prelude::*; -use sov_modules_api::WorkingSet; - -use super::VecSetter; - -impl VecSetter { - /// Initializes module with the `admin` role. - pub(crate) fn init_module( - &self, - admin_config: &::Config, - working_set: &mut WorkingSet, - ) -> Result<()> { - self.admin.set(&admin_config.admin, working_set); - Ok(()) - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter/src/lib.rs b/crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter/src/lib.rs deleted file mode 100644 index b3ec6ac51..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter/src/lib.rs +++ /dev/null @@ -1,75 +0,0 @@ -#![deny(missing_docs)] -#![doc = include_str!("../README.md")] -mod call; -mod genesis; - -#[cfg(feature = "native")] -mod query; - -pub use call::CallMessage; -#[cfg(feature = "native")] -pub use query::*; -use serde::{Deserialize, Serialize}; -use sov_modules_api::{Error, ModuleInfo, WorkingSet}; - -/// Initial configuration for sov-vec-setter module. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct VecSetterConfig { - /// Admin of the module. - pub admin: C::Address, -} - -/// A new module: -/// - Must derive `ModuleInfo` -/// - Must contain `[address]` field -/// - Can contain any number of ` #[state]` or `[module]` fields -#[cfg_attr(feature = "native", derive(sov_modules_api::ModuleCallJsonSchema))] -#[derive(ModuleInfo)] -pub struct VecSetter { - /// Address of the module. - #[address] - pub address: C::Address, - - /// Some vector kept in the state. - #[state] - pub vector: sov_modules_api::StateVec, - - /// Holds the address of the admin user who is allowed to update the vector. - #[state] - pub admin: sov_modules_api::StateValue, -} - -impl sov_modules_api::Module for VecSetter { - type Context = C; - - type Config = VecSetterConfig; - - type CallMessage = call::CallMessage; - - type Event = (); - - fn genesis(&self, config: &Self::Config, working_set: &mut WorkingSet) -> Result<(), Error> { - // The initialization logic - Ok(self.init_module(config, working_set)?) - } - - fn call( - &mut self, - msg: Self::CallMessage, - context: &Self::Context, - working_set: &mut WorkingSet, - ) -> Result { - match msg { - call::CallMessage::PushValue(new_value) => { - Ok(self.push_value(new_value, context, working_set)?) - } - call::CallMessage::SetValue { index, value } => { - Ok(self.set_value(index, value, context, working_set)?) - } - call::CallMessage::SetAllValues(values) => { - Ok(self.set_all_values(values, context, working_set)?) - } - call::CallMessage::PopValue => Ok(self.pop_value(context, working_set)?), - } - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter/src/query.rs b/crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter/src/query.rs deleted file mode 100644 index 3a4c7466b..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter/src/query.rs +++ /dev/null @@ -1,41 +0,0 @@ -use jsonrpsee::core::RpcResult; -use sov_modules_api::macros::rpc_gen; -use sov_modules_api::{StateVecAccessor, WorkingSet}; - -use super::VecSetter; - -/// Response returned from the vecSetter_queryVec endpoint. -#[derive(serde::Serialize, serde::Deserialize, Debug, Eq, PartialEq, Clone)] -pub struct QueryResponse { - /// Value saved in the module's state vector. - pub value: Option, -} - -/// Response returned from the vecSetter_lenVec endpoint -#[derive(serde::Serialize, serde::Deserialize, Debug, Eq, PartialEq, Clone)] -pub struct LenResponse { - /// Length of the vector - pub value: usize, -} - -#[rpc_gen(client, server, namespace = "vecSetter")] -impl VecSetter { - /// Queries the state vector of the module. - #[rpc_method(name = "queryVec")] - pub fn query_vec( - &self, - index: usize, - working_set: &mut WorkingSet, - ) -> RpcResult { - Ok(QueryResponse { - value: self.vector.get(index, working_set), - }) - } - /// Queries the length of the vector - #[rpc_method(name = "lenVec")] - pub fn len_vec(&self, working_set: &mut WorkingSet) -> RpcResult { - Ok(LenResponse { - value: self.vector.len(working_set), - }) - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter/tests/tests.rs b/crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter/tests/tests.rs deleted file mode 100644 index 92dcb7b71..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/examples/sov-vec-setter/tests/tests.rs +++ /dev/null @@ -1,56 +0,0 @@ -use sov_modules_api::default_context::DefaultContext; -use sov_modules_api::{Address, Context, Module, StateVecAccessor, WorkingSet}; -use sov_prover_storage_manager::new_orphan_storage; -use sov_vec_setter::{CallMessage, VecSetter, VecSetterConfig}; - -// rustfmt doesn't like long lines, but it's easier to read in this case. -#[rustfmt::skip] -fn test_cases() -> Vec<(Address, Address, CallMessage, Option>)> { - let admin = Address::from([1; 32]); - let not_admin = Address::from([2; 32]); - let sequencer = Address::from([3; 32]); - - // (sender, call, expected vec contents or None if call should fail) - vec![ - (admin, sequencer, CallMessage::PushValue(1), Some(vec![1])), - (admin, sequencer, CallMessage::PushValue(2), Some(vec![1, 2])), - (admin, sequencer, CallMessage::PopValue, Some(vec![1])), - (not_admin, sequencer, CallMessage::PopValue, None), - (admin, sequencer, CallMessage::PopValue, Some(vec![])), - (not_admin, sequencer, CallMessage::SetValue { index: 0, value: 10 }, None), - (admin, sequencer, CallMessage::SetValue { index: 0, value: 10 }, None), - (admin, sequencer, CallMessage::PushValue(8), Some(vec![8])), - (admin, sequencer, CallMessage::SetValue { index: 0, value: 10 }, Some(vec![10])), - (admin, sequencer, CallMessage::PushValue(0), Some(vec![10, 0])), - (admin, sequencer, CallMessage::SetAllValues(vec![11, 12]), Some(vec![11, 12])), - (not_admin, sequencer, CallMessage::SetAllValues(vec![]), None), - ] -} - -#[test] -fn test_vec_setter_calls() { - let tmpdir = tempfile::tempdir().unwrap(); - - let storage = new_orphan_storage(tmpdir.path()).unwrap(); - let mut working_set = WorkingSet::new(storage); - - let admin = Address::from([1; 32]); - let config = VecSetterConfig { admin }; - - let mut vec_setter = VecSetter::default(); - vec_setter.genesis(&config, &mut working_set).unwrap(); - - for (sender, sequencer, call, expected_contents) in test_cases().iter().cloned() { - let context = - DefaultContext::new(sender, sequencer, 1, sov_modules_api::SpecId::Genesis, 0); - - let call_result = vec_setter.call(call, &context, &mut working_set); - - if call_result.is_ok() { - let vec_contents = vec_setter.vector.iter(&mut working_set).collect::>(); - assert_eq!(Some(vec_contents), expected_contents); - } else { - assert_eq!(expected_contents, None); - } - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/module-template/Cargo.toml b/crates/sovereign-sdk/module-system/module-implementations/module-template/Cargo.toml deleted file mode 100644 index eefe3494a..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/module-template/Cargo.toml +++ /dev/null @@ -1,40 +0,0 @@ -[package] -name = "module-template" -authors = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -repository = { workspace = true } - -version = { workspace = true } -readme = "README.md" -publish = false -resolver = "2" - -[dependencies] -anyhow = { workspace = true } -arbitrary = { workspace = true, optional = true } -borsh = { workspace = true, features = ["rc"] } -proptest = { workspace = true, optional = true } -proptest-derive = { workspace = true, optional = true } -schemars = { workspace = true, optional = true } -serde = { workspace = true } -serde_json = { workspace = true, optional = true } -thiserror = { workspace = true } - -sov-bank = { path = "../sov-bank" } -sov-modules-api = { path = "../../sov-modules-api", default-features = false } -sov-state = { path = "../../sov-state" } - - -[dev-dependencies] -tempfile = { workspace = true } -module-template = { path = ".", features = ["native"] } -sov-prover-storage-manager = { path = "../../../full-node/sov-prover-storage-manager", features = [ - "test-utils", -] } - -[features] -default = [] -arbitrary = ["dep:arbitrary", "dep:proptest", "dep:proptest-derive"] -native = ["serde_json", "schemars", "sov-modules-api/native"] diff --git a/crates/sovereign-sdk/module-system/module-implementations/module-template/README.md b/crates/sovereign-sdk/module-system/module-implementations/module-template/README.md deleted file mode 100644 index fcf17ff71..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/module-template/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# A simple template for creating modules - -It demonstrates the following concepts: - -### 1. Module structure: - -- `lib.rs` contains `ExampleModule` module definition and `sov_modules_api::Module` trait implementation for `ExampleModule`. -- `genesis.rs` contains the module initialization logic. -- `call.rs` contains methods that change module state in response to `CallMessage`. -- `query.rs` contains functions for querying the module state. - -### 2. Functionality: - -Anyone can update the value stored in the example module by sending a `CallMessage::SetValue(new_value)` message. Anyone can query the module state by invoking the public `get_value` function. - -For implementation details, please check comments in the `genesis.rs, call.rs & query.rs`. \ No newline at end of file diff --git a/crates/sovereign-sdk/module-system/module-implementations/module-template/src/call.rs b/crates/sovereign-sdk/module-system/module-implementations/module-template/src/call.rs deleted file mode 100644 index 5563df1aa..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/module-template/src/call.rs +++ /dev/null @@ -1,36 +0,0 @@ -use std::fmt::Debug; - -use anyhow::Result; -use sov_modules_api::prelude::*; -use sov_modules_api::{CallResponse, WorkingSet}; - -use crate::ExampleModule; - -/// This enumeration represents the available call messages for interacting with -/// the `ExampleModule` module. -/// The `derive` for [`schemars::JsonSchema`] is a requirement of -/// [`sov_modules_api::ModuleCallJsonSchema`]. -#[cfg_attr(feature = "native", derive(schemars::JsonSchema))] -#[cfg_attr( - feature = "arbitrary", - derive(arbitrary::Arbitrary, proptest_derive::Arbitrary) -)] -#[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Debug, PartialEq)] -pub enum CallMessage { - SetValue(u32), -} - -impl ExampleModule { - /// Sets `value` field to the `new_value` - pub(crate) fn set_value( - &self, - new_value: u32, - _context: &C, - working_set: &mut WorkingSet, - ) -> Result { - self.value.set(&new_value, working_set); - working_set.add_event("set", &format!("value_set: {new_value:?}")); - - Ok(CallResponse::default()) - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/module-template/src/genesis.rs b/crates/sovereign-sdk/module-system/module-implementations/module-template/src/genesis.rs deleted file mode 100644 index 996b55d35..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/module-template/src/genesis.rs +++ /dev/null @@ -1,14 +0,0 @@ -use anyhow::Result; -use sov_modules_api::WorkingSet; - -use crate::ExampleModule; - -impl ExampleModule { - pub(crate) fn init_module( - &self, - _config: &::Config, - _working_set: &mut WorkingSet, - ) -> Result<()> { - Ok(()) - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/module-template/src/lib.rs b/crates/sovereign-sdk/module-system/module-implementations/module-template/src/lib.rs deleted file mode 100644 index b2433c7b1..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/module-template/src/lib.rs +++ /dev/null @@ -1,64 +0,0 @@ -mod call; -mod genesis; -#[cfg(feature = "native")] -mod query; -pub use call::CallMessage; -#[cfg(feature = "native")] -pub use query::*; -use serde::{Deserialize, Serialize}; -use sov_modules_api::{Error, ModuleInfo, WorkingSet}; - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ExampleModuleConfig {} - -/// A new module: -/// - Must derive `ModuleInfo` -/// - Must contain `[address]` field -/// - Can contain any number of ` #[state]` or `[module]` fields -/// - Should derive `ModuleCallJsonSchema` if the "native" feature is enabled. -/// This is optional, and is only used to generate a JSON Schema for your -/// module's call messages (which is useful to develop clients, CLI tooling -/// etc.). -#[cfg_attr(feature = "native", derive(sov_modules_api::ModuleCallJsonSchema))] -#[derive(ModuleInfo)] -pub struct ExampleModule { - /// Address of the module. - #[address] - pub address: C::Address, - - /// Some value kept in the state. - #[state] - pub value: sov_modules_api::StateValue, - - /// Reference to the Bank module. - #[module] - pub(crate) _bank: sov_bank::Bank, -} - -impl sov_modules_api::Module for ExampleModule { - type Context = C; - - type Config = ExampleModuleConfig; - - type CallMessage = call::CallMessage; - - type Event = (); - - fn genesis(&self, config: &Self::Config, working_set: &mut WorkingSet) -> Result<(), Error> { - // The initialization logic - Ok(self.init_module(config, working_set)?) - } - - fn call( - &mut self, - msg: Self::CallMessage, - context: &Self::Context, - working_set: &mut WorkingSet, - ) -> Result { - match msg { - call::CallMessage::SetValue(new_value) => { - Ok(self.set_value(new_value, context, working_set)?) - } - } - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/module-template/src/query.rs b/crates/sovereign-sdk/module-system/module-implementations/module-template/src/query.rs deleted file mode 100644 index 2b3f1e4e1..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/module-template/src/query.rs +++ /dev/null @@ -1,18 +0,0 @@ -use sov_modules_api::prelude::*; -use sov_modules_api::WorkingSet; - -use super::ExampleModule; - -#[derive(serde::Serialize, serde::Deserialize, Debug, Eq, PartialEq)] -pub struct Response { - pub value: Option, -} - -impl ExampleModule { - /// Queries the state of the module. - pub fn query_value(&self, working_set: &mut WorkingSet) -> Response { - Response { - value: self.value.get(working_set), - } - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/module-template/tests/value_setter.rs b/crates/sovereign-sdk/module-system/module-implementations/module-template/tests/value_setter.rs deleted file mode 100644 index b92c0c301..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/module-template/tests/value_setter.rs +++ /dev/null @@ -1,64 +0,0 @@ -use module_template::{CallMessage, ExampleModule, ExampleModuleConfig, Response}; -use sov_modules_api::default_context::{DefaultContext, ZkDefaultContext}; -use sov_modules_api::{Address, Context, Event, Module, SpecId, WorkingSet}; -use sov_prover_storage_manager::new_orphan_storage; -use sov_state::ZkStorage; - -#[test] -fn test_value_setter() { - let tmpdir = tempfile::tempdir().unwrap(); - - let storage = new_orphan_storage(tmpdir.path()).unwrap(); - let mut working_set = WorkingSet::new(storage); - - let admin = Address::from([1; 32]); - let sequencer = Address::from([2; 32]); - - // Test Native-Context - { - let config = ExampleModuleConfig {}; - let context = DefaultContext::new(admin, sequencer, 1, SpecId::Genesis, 0); - test_value_setter_helper(context, &config, &mut working_set); - } - - let (_, witness) = working_set.checkpoint().freeze(); - - // Test Zk-Context - { - let config = ExampleModuleConfig {}; - let zk_context = ZkDefaultContext::new(admin, sequencer, 1, SpecId::Genesis, 0); - let mut zk_working_set = WorkingSet::with_witness(ZkStorage::new(), witness); - test_value_setter_helper(zk_context, &config, &mut zk_working_set); - } -} - -fn test_value_setter_helper( - context: C, - config: &ExampleModuleConfig, - working_set: &mut WorkingSet, -) { - let mut module = ExampleModule::::default(); - module.genesis(config, working_set).unwrap(); - - let new_value = 99; - let call_msg = CallMessage::SetValue(new_value); - - // Test events - { - module.call(call_msg, &context, working_set).unwrap(); - let event = &working_set.events()[0]; - assert_eq!(event, &Event::new("set", "value_set: 99")); - } - - // Test query - #[cfg(feature = "native")] - { - let query_response = module.query_value(working_set); - assert_eq!( - Response { - value: Some(new_value) - }, - query_response - ) - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-bank/Cargo.toml b/crates/sovereign-sdk/module-system/module-implementations/sov-bank/Cargo.toml index 65033bfea..54ed4166c 100644 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-bank/Cargo.toml +++ b/crates/sovereign-sdk/module-system/module-implementations/sov-bank/Cargo.toml @@ -50,3 +50,6 @@ native = [ cli = ["native"] serde = [] test-utils = [] + +[package.metadata.cargo-udeps.ignore] +development = ["sov-bank"] diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/archival_query_test.rs b/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/archival_query_test.rs deleted file mode 100644 index 652835e73..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/archival_query_test.rs +++ /dev/null @@ -1,288 +0,0 @@ -mod helpers; - -use helpers::*; -use sov_bank::{get_genesis_token_address, Amount, Bank, CallMessage, Coins}; -use sov_modules_api::default_context::DefaultContext; -use sov_modules_api::{Address, Context, Module, SpecId, StateReaderAndWriter, WorkingSet}; -use sov_prover_storage_manager::{new_orphan_storage, SnapshotManager}; -use sov_state::storage::{StorageKey, StorageValue}; -use sov_state::{ProverStorage, Storage}; - -#[test] -fn transfer_initial_token() { - let initial_balance = 100; - let bank_config = create_bank_config_with_token(4, initial_balance); - let tmpdir = tempfile::tempdir().unwrap(); - let prover_storage = new_orphan_storage(tmpdir.path()).unwrap(); - let mut working_set = WorkingSet::new(prover_storage.clone()); - let mut bank = Bank::default(); - bank.genesis(&bank_config, &mut working_set).unwrap(); - - let token_address = get_genesis_token_address::( - &bank_config.tokens[0].token_name, - bank_config.tokens[0].salt, - ); - let sender_address = bank_config.tokens[0].address_and_balances[0].0; - let sequencer_address = bank_config.tokens[0].address_and_balances[3].0; - let receiver_address = bank_config.tokens[0].address_and_balances[1].0; - assert_ne!(sender_address, receiver_address); - - let (sender_balance, receiver_balance) = query_sender_receiver_balances( - &bank, - token_address, - sender_address, - receiver_address, - &mut working_set, - ); - assert_eq!((sender_balance, receiver_balance), (100, 100)); - commit(working_set, prover_storage.clone()); - - let mut working_set: WorkingSet = WorkingSet::new(prover_storage.clone()); - - transfer( - &mut bank, - token_address, - sender_address, - sequencer_address, - receiver_address, - 10, - &mut working_set, - ); - let (sender_balance, receiver_balance) = query_sender_receiver_balances( - &bank, - token_address, - sender_address, - receiver_address, - &mut working_set, - ); - assert_eq!((sender_balance, receiver_balance), (90, 110)); - - commit(working_set, prover_storage.clone()); - - let mut working_set: WorkingSet = WorkingSet::new(prover_storage.clone()); - - transfer( - &mut bank, - token_address, - sender_address, - sequencer_address, - receiver_address, - 10, - &mut working_set, - ); - let (sender_balance, receiver_balance) = query_sender_receiver_balances( - &bank, - token_address, - sender_address, - receiver_address, - &mut working_set, - ); - assert_eq!((sender_balance, receiver_balance), (80, 120)); - commit(working_set, prover_storage.clone()); - - // Archival tests - - let archival_slot: u64 = 2; - let mut working_set: WorkingSet = WorkingSet::new(prover_storage.clone()); - working_set.set_archival_version(archival_slot); - - let (sender_balance, receiver_balance) = query_sender_receiver_balances( - &bank, - token_address, - sender_address, - receiver_address, - &mut working_set, - ); - assert_eq!((sender_balance, receiver_balance), (90, 110)); - - // modify in archival - transfer( - &mut bank, - token_address, - sender_address, - sequencer_address, - receiver_address, - 5, - &mut working_set, - ); - - let (sender_balance, receiver_balance) = query_sender_receiver_balances( - &bank, - token_address, - sender_address, - receiver_address, - &mut working_set, - ); - assert_eq!((sender_balance, receiver_balance), (85, 115)); - - let archival_slot: u64 = 1; - let mut working_set: WorkingSet = WorkingSet::new(prover_storage.clone()); - working_set.set_archival_version(archival_slot); - let (sender_balance, receiver_balance) = query_sender_receiver_balances( - &bank, - token_address, - sender_address, - receiver_address, - &mut working_set, - ); - assert_eq!((sender_balance, receiver_balance), (100, 100)); - - transfer( - &mut bank, - token_address, - sender_address, - sequencer_address, - receiver_address, - 45, - &mut working_set, - ); - - let (sender_balance, receiver_balance) = query_sender_receiver_balances( - &bank, - token_address, - sender_address, - receiver_address, - &mut working_set, - ); - assert_eq!((sender_balance, receiver_balance), (55, 145)); - - working_set.unset_archival_version(); - let (sender_balance, receiver_balance) = query_sender_receiver_balances( - &bank, - token_address, - sender_address, - receiver_address, - &mut working_set, - ); - assert_eq!((sender_balance, receiver_balance), (80, 120)); - - // Accessory tests - - transfer( - &mut bank, - token_address, - sender_address, - sequencer_address, - receiver_address, - 10, - &mut working_set, - ); - let (sender_balance, receiver_balance) = query_sender_receiver_balances( - &bank, - token_address, - sender_address, - receiver_address, - &mut working_set, - ); - assert_eq!((sender_balance, receiver_balance), (70, 130)); - - let mut accessory_state = working_set.accessory_state(); - accessory_state.set(&StorageKey::from("k"), StorageValue::from(b"v1".to_vec())); - let val = accessory_state.get(&StorageKey::from("k")).unwrap(); - assert_eq!("v1", String::from_utf8(val.value().to_vec()).unwrap()); - - commit(working_set, prover_storage.clone()); - - // next block - - let mut working_set: WorkingSet = WorkingSet::new(prover_storage.clone()); - transfer( - &mut bank, - token_address, - sender_address, - sequencer_address, - receiver_address, - 10, - &mut working_set, - ); - let (sender_balance, receiver_balance) = query_sender_receiver_balances( - &bank, - token_address, - sender_address, - receiver_address, - &mut working_set, - ); - assert_eq!((sender_balance, receiver_balance), (60, 140)); - let mut accessory_state = working_set.accessory_state(); - accessory_state.set(&StorageKey::from("k"), StorageValue::from(b"v2".to_vec())); - let val = accessory_state.get(&StorageKey::from("k")).unwrap(); - assert_eq!("v2", String::from_utf8(val.value().to_vec()).unwrap()); - - commit(working_set, prover_storage.clone()); - - // archival versioned state query - - let archival_slot = 3; - let mut working_set: WorkingSet = WorkingSet::new(prover_storage.clone()); - working_set.set_archival_version(archival_slot); - let mut accessory_state = working_set.accessory_state(); - let val = accessory_state.get(&StorageKey::from("k")).unwrap(); - assert_eq!("v1", String::from_utf8(val.value().to_vec()).unwrap()); - - // archival accessory set - - accessory_state.set(&StorageKey::from("k"), StorageValue::from(b"v3".to_vec())); - let val = accessory_state.get(&StorageKey::from("k")).unwrap(); - assert_eq!("v3", String::from_utf8(val.value().to_vec()).unwrap()); - - working_set.unset_archival_version(); - let mut accessory_state = working_set.accessory_state(); - let val = accessory_state.get(&StorageKey::from("k")).unwrap(); - assert_eq!("v2", String::from_utf8(val.value().to_vec()).unwrap()); -} - -fn query_sender_receiver_balances( - bank: &Bank, - token_address: Address, - sender_address: Address, - receiver_address: Address, - working_set: &mut WorkingSet, -) -> (u64, u64) { - let sender_balance = bank - .get_balance_of(sender_address, token_address, working_set) - .unwrap(); - let receiver_balance = bank - .get_balance_of(receiver_address, token_address, working_set) - .unwrap(); - (sender_balance, receiver_balance) -} - -fn transfer( - bank: &mut Bank, - token_address: Address, - sender_address: Address, - sequencer_address: Address, - receiver_address: Address, - transfer_amount: Amount, - working_set: &mut WorkingSet, -) { - let transfer_message = CallMessage::Transfer { - to: receiver_address, - coins: Coins { - amount: transfer_amount, - token_address, - }, - }; - - let sender_context = C::new(sender_address, sequencer_address, 1, SpecId::Genesis, 0); - - bank.call(transfer_message, &sender_context, working_set) - .expect("Transfer call failed"); -} - -fn commit(working_set: WorkingSet, storage: ProverStorage) { - // Save checkpoint - let mut checkpoint = working_set.checkpoint(); - - let (cache_log, mut witness) = checkpoint.freeze(); - - let (_, authenticated_node_batch, _) = storage - .compute_state_update(cache_log, &mut witness) - .expect("jellyfish merkle tree update must succeed"); - - let working_set = checkpoint.to_revertable(); - - let accessory_log = working_set.checkpoint().freeze_non_provable(); - - storage.commit(&authenticated_node_batch, &accessory_log); -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/burn_test.rs b/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/burn_test.rs deleted file mode 100644 index 29b8e60dc..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/burn_test.rs +++ /dev/null @@ -1,210 +0,0 @@ -use helpers::{generate_address, query_total_supply, query_user_balance, C}; -use sov_bank::{ - get_genesis_token_address, get_token_address, Bank, BankConfig, CallMessage, Coins, -}; -use sov_modules_api::{Context, Error, Module, SpecId, WorkingSet}; -use sov_prover_storage_manager::{new_orphan_storage, SnapshotManager}; -use sov_state::ProverStorage; - -use crate::helpers::create_bank_config_with_token; - -mod helpers; - -pub type Storage = ProverStorage; - -#[test] -fn burn_deployed_tokens() { - let mut bank = Bank::::default(); - let tmpdir = tempfile::tempdir().unwrap(); - let mut working_set = WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - let empty_bank_config = BankConfig:: { tokens: vec![] }; - bank.genesis(&empty_bank_config, &mut working_set).unwrap(); - - let sender_address = generate_address("just_sender"); - let sequencer_address = generate_address("sequencer"); - let sender_context = C::new(sender_address, sequencer_address, 1, SpecId::Genesis, 0); - let minter_address = generate_address("minter"); - let minter_context = C::new(minter_address, sequencer_address, 1, SpecId::Genesis, 0); - - let salt = 0; - let token_name = "Token1".to_owned(); - let initial_balance = 100; - let token_address = get_token_address::(&token_name, minter_address.as_ref(), salt); - - // --- - // Deploying token - let mint_message = CallMessage::CreateToken { - salt, - token_name, - initial_balance, - minter_address, - authorized_minters: vec![minter_address], - }; - bank.call(mint_message, &minter_context, &mut working_set) - .expect("Failed to mint token"); - // No events at the moment. If there are, needs to be checked - assert!(working_set.events().is_empty()); - - let previous_total_supply = query_total_supply(&bank, token_address, &mut working_set); - assert_eq!(Some(initial_balance), previous_total_supply); - - // ----- - // Burn - let burn_amount = 10; - let burn_message = CallMessage::Burn { - coins: Coins { - amount: burn_amount, - token_address, - }, - }; - - bank.call(burn_message.clone(), &minter_context, &mut working_set) - .expect("Failed to burn token"); - assert!(working_set.events().is_empty()); - - let current_total_supply = query_total_supply(&bank, token_address, &mut working_set); - assert_eq!(Some(initial_balance - burn_amount), current_total_supply); - let minter_balance = query_user_balance(&bank, minter_address, token_address, &mut working_set); - assert_eq!(Some(initial_balance - burn_amount), minter_balance); - - let previous_total_supply = current_total_supply; - // --- - // Burn by another user, who doesn't have tokens at all - let failed_to_burn = bank.call(burn_message, &sender_context, &mut working_set); - assert!(failed_to_burn.is_err()); - let Error::ModuleError(err) = failed_to_burn.err().unwrap(); - let mut chain = err.chain(); - let message_1 = chain.next().unwrap().to_string(); - let message_2 = chain.next().unwrap().to_string(); - assert!(chain.next().is_none()); - assert_eq!( - format!( - "Failed to burn coins(token_address={} amount={}) from owner {}", - token_address, burn_amount, sender_address - ), - message_1 - ); - let expected_error_part = format!( - "Value not found for prefix: \"Bank/tokens/{}\" and: storage key", - token_address - ); - println!("m{:?}", message_2); - assert!(message_2.starts_with(&expected_error_part)); - - let current_total_supply = query_total_supply(&bank, token_address, &mut working_set); - assert_eq!(previous_total_supply, current_total_supply); - let sender_balance = query_user_balance(&bank, sender_address, token_address, &mut working_set); - assert_eq!(None, sender_balance); - - // --- - // Allow burning zero tokens - let burn_zero_message = CallMessage::Burn { - coins: Coins { - amount: 0, - token_address, - }, - }; - - bank.call(burn_zero_message, &minter_context, &mut working_set) - .expect("Failed to burn token"); - assert!(working_set.events().is_empty()); - let minter_balance_after = - query_user_balance(&bank, minter_address, token_address, &mut working_set); - assert_eq!(minter_balance, minter_balance_after); - - // --- - // Burn more than available - let burn_message = CallMessage::Burn { - coins: Coins { - amount: initial_balance + 10, - token_address, - }, - }; - - let failed_to_burn = bank.call(burn_message, &minter_context, &mut working_set); - assert!(failed_to_burn.is_err()); - let Error::ModuleError(err) = failed_to_burn.err().unwrap(); - let mut chain = err.chain(); - let message_1 = chain.next().unwrap().to_string(); - let message_2 = chain.next().unwrap().to_string(); - assert!(chain.next().is_none()); - assert_eq!( - format!( - "Failed to burn coins(token_address={} amount={}) from owner {}", - token_address, - initial_balance + 10, - minter_address - ), - message_1 - ); - assert_eq!( - format!("Insufficient funds for {}", minter_address), - message_2 - ); - - // --- - // Try to burn non existing token - let token_address = get_token_address::("NotRealToken2", minter_address.as_ref(), salt); - let burn_message = CallMessage::Burn { - coins: Coins { - amount: 1, - token_address, - }, - }; - - let failed_to_burn = bank.call(burn_message, &minter_context, &mut working_set); - assert!(failed_to_burn.is_err()); - let Error::ModuleError(err) = failed_to_burn.err().unwrap(); - let mut chain = err.chain(); - let message_1 = chain.next().unwrap().to_string(); - let message_2 = chain.next().unwrap().to_string(); - assert!(chain.next().is_none()); - assert_eq!( - format!( - "Failed to burn coins(token_address={} amount={}) from owner {}", - token_address, 1, minter_address - ), - message_1 - ); - // Note, no token address in root cause message. - let expected_error_part = "Value not found for prefix: \"Bank/tokens/\" and: storage key"; - assert!(message_2.starts_with(expected_error_part)); -} - -#[test] -fn burn_initial_tokens() { - let initial_balance = 100; - let bank_config = create_bank_config_with_token(2, initial_balance); - let tmpdir = tempfile::tempdir().unwrap(); - let mut working_set = WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - let mut bank = Bank::default(); - bank.genesis(&bank_config, &mut working_set).unwrap(); - - let token_address = get_genesis_token_address::( - &bank_config.tokens[0].token_name, - bank_config.tokens[0].salt, - ); - let sender_address = bank_config.tokens[0].address_and_balances[0].0; - let sequencer_address = bank_config.tokens[0].address_and_balances[1].0; - - let balance_before = query_user_balance(&bank, sender_address, token_address, &mut working_set); - assert_eq!(Some(initial_balance), balance_before); - - let burn_amount = 10; - let burn_message = CallMessage::Burn { - coins: Coins { - amount: burn_amount, - token_address, - }, - }; - - let context = C::new(sender_address, sequencer_address, 1, SpecId::Genesis, 0); - bank.call(burn_message, &context, &mut working_set) - .expect("Failed to burn token"); - assert!(working_set.events().is_empty()); - - let balance_after = query_user_balance(&bank, sender_address, token_address, &mut working_set); - assert_eq!(Some(initial_balance - burn_amount), balance_after); - - // Assume that the rest of edge cases are similar to deployed tokens -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/create_token_test.rs b/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/create_token_test.rs deleted file mode 100644 index eb0cc4bc5..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/create_token_test.rs +++ /dev/null @@ -1,71 +0,0 @@ -use helpers::*; -use sov_bank::{get_token_address, Bank, CallMessage}; -use sov_modules_api::utils::generate_address; -use sov_modules_api::{Context, Module, SpecId, WorkingSet}; -use sov_prover_storage_manager::new_orphan_storage; - -mod helpers; - -#[test] -fn initial_and_deployed_token() { - let bank_config = create_bank_config_with_token(1, 100); - let tmpdir = tempfile::tempdir().unwrap(); - let mut working_set = WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - let mut bank = Bank::default(); - bank.genesis(&bank_config, &mut working_set).unwrap(); - - let sender_address = generate_address::("sender"); - let sequencer_address = generate_address::("sequencer"); - let sender_context = C::new(sender_address, sequencer_address, 1, SpecId::Genesis, 0); - let minter_address = generate_address::("minter"); - let initial_balance = 500; - let token_name = "Token1".to_owned(); - let salt = 1; - let token_address = get_token_address::(&token_name, sender_address.as_ref(), salt); - let create_token_message = CallMessage::CreateToken:: { - salt, - token_name: token_name.clone(), - initial_balance, - minter_address, - authorized_minters: vec![minter_address], - }; - - bank.call(create_token_message, &sender_context, &mut working_set) - .expect("Failed to create token"); - - assert!(working_set.events().is_empty()); - - let sender_balance = bank.get_balance_of(sender_address, token_address, &mut working_set); - assert!(sender_balance.is_none()); - - let observed_token_name = bank - .get_token_name(&token_address, &mut working_set) - .expect("Token is missing its name"); - assert_eq!(&token_name, &observed_token_name); - - let minter_balance = bank.get_balance_of(minter_address, token_address, &mut working_set); - assert_eq!(Some(initial_balance), minter_balance); - - let total_supply = bank - .get_total_supply_of(&token_address, &mut working_set) - .unwrap(); - assert_eq!(initial_balance, total_supply); -} - -#[test] -/// Currently integer overflow happens on bank genesis -fn overflow_max_supply() { - let bank = Bank::::default(); - let tmpdir = tempfile::tempdir().unwrap(); - let mut working_set = WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - - let bank_config = create_bank_config_with_token(2, u64::MAX - 2); - - let genesis_result = bank.genesis(&bank_config, &mut working_set); - assert!(genesis_result.is_err()); - - assert_eq!( - "Total supply overflow", - genesis_result.unwrap_err().to_string() - ); -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/freeze_test.rs b/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/freeze_test.rs deleted file mode 100644 index bd85768df..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/freeze_test.rs +++ /dev/null @@ -1,183 +0,0 @@ -use helpers::{query_total_supply, query_user_balance, C}; -use sov_bank::{get_token_address, Bank, BankConfig, CallMessage, Coins}; -use sov_modules_api::default_context::DefaultContext; -use sov_modules_api::utils::generate_address; -use sov_modules_api::{Context, Error, Module, SpecId, WorkingSet}; -use sov_prover_storage_manager::{new_orphan_storage, SnapshotManager}; -use sov_state::ProverStorage; - -mod helpers; - -pub type Storage = ProverStorage; - -#[test] -fn freeze_token() { - let mut bank = Bank::::default(); - let tmpdir = tempfile::tempdir().unwrap(); - let mut working_set = WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - let empty_bank_config = BankConfig:: { tokens: vec![] }; - bank.genesis(&empty_bank_config, &mut working_set).unwrap(); - - let minter_address = generate_address::("minter"); - let sequencer_address = generate_address::("sequencer"); - let minter_context = C::new(minter_address, sequencer_address, 1, SpecId::Genesis, 0); - - let salt = 0; - let token_name = "Token1".to_owned(); - let initial_balance = 100; - let token_address = get_token_address::(&token_name, minter_address.as_ref(), salt); - - // --- - // Deploying token - let mint_message = CallMessage::CreateToken { - salt, - token_name: token_name.clone(), - initial_balance, - minter_address, - authorized_minters: vec![minter_address], - }; - let _minted = bank - .call(mint_message, &minter_context, &mut working_set) - .expect("Failed to mint token"); - // No events at the moment. If there are, needs to be checked - assert!(working_set.events().is_empty()); - - // ----- - // Freeze - let freeze_message = CallMessage::Freeze { token_address }; - - let _freeze = bank - .call(freeze_message, &minter_context, &mut working_set) - .expect("Failed to freeze token"); - assert!(working_set.events().is_empty()); - - // ---- - // Try to freeze an already frozen token - let freeze_message = CallMessage::Freeze { token_address }; - - let freeze = bank.call(freeze_message, &minter_context, &mut working_set); - assert!(freeze.is_err()); - let Error::ModuleError(err) = freeze.err().unwrap(); - let mut chain = err.chain(); - let message_1 = chain.next().unwrap().to_string(); - let message_2 = chain.next().unwrap().to_string(); - assert!(chain.next().is_none()); - assert_eq!( - format!( - "Failed freeze token_address={} by sender {}", - token_address, minter_address - ), - message_1 - ); - assert_eq!(format!("Token {} is already frozen", token_name), message_2); - - // create a second token - let token_name_2 = "Token2".to_owned(); - let initial_balance = 100; - let token_address_2 = get_token_address::(&token_name_2, minter_address.as_ref(), salt); - - // --- - // Deploying second token - let mint_message = CallMessage::CreateToken { - salt, - token_name: token_name_2.clone(), - initial_balance, - minter_address, - authorized_minters: vec![minter_address], - }; - let _minted = bank - .call(mint_message, &minter_context, &mut working_set) - .expect("Failed to mint token"); - // No events at the moment. If there are, needs to be checked - assert!(working_set.events().is_empty()); - - // Try to freeze with a non authorized minter - let unauthorized_address = generate_address::("unauthorized_address"); - let sequencer_address = generate_address::("sequencer"); - let unauthorized_context = C::new( - unauthorized_address, - sequencer_address, - 1, - SpecId::Genesis, - 0, - ); - let freeze_message = CallMessage::Freeze { - token_address: token_address_2, - }; - - let freeze = bank.call(freeze_message, &unauthorized_context, &mut working_set); - assert!(freeze.is_err()); - let Error::ModuleError(err) = freeze.err().unwrap(); - let mut chain = err.chain(); - let message_1 = chain.next().unwrap().to_string(); - let message_2 = chain.next().unwrap().to_string(); - assert!(chain.next().is_none()); - assert_eq!( - format!( - "Failed freeze token_address={} by sender {}", - token_address_2, unauthorized_address - ), - message_1 - ); - assert_eq!( - format!( - "Sender {} is not an authorized minter of token {}", - unauthorized_address, token_name_2 - ), - message_2 - ); - - // Try to mint a frozen token - let mint_amount = 10; - let new_holder = generate_address::("new_holder"); - let mint_message = CallMessage::Mint { - coins: Coins { - amount: mint_amount, - token_address, - }, - minter_address: new_holder, - }; - - let minted = bank.call(mint_message, &minter_context, &mut working_set); - assert!(minted.is_err()); - - let Error::ModuleError(err) = minted.err().unwrap(); - let mut chain = err.chain(); - let message_1 = chain.next().unwrap().to_string(); - let message_2 = chain.next().unwrap().to_string(); - assert!(chain.next().is_none()); - assert_eq!( - format!( - "Failed mint coins(token_address={} amount={}) to {} by authorizer {}", - token_address, mint_amount, new_holder, minter_address - ), - message_1 - ); - assert_eq!( - format!("Attempt to mint frozen token {}", token_name), - message_2 - ); - - // ----- - // Try to mint an unfrozen token, sanity check - let mint_amount = 10; - let mint_message = CallMessage::Mint { - coins: Coins { - amount: mint_amount, - token_address: token_address_2, - }, - minter_address, - }; - - let _minted = bank - .call(mint_message, &minter_context, &mut working_set) - .expect("Failed to mint token"); - assert!(working_set.events().is_empty()); - - let total_supply = query_total_supply(&bank, token_address_2, &mut working_set); - assert_eq!(Some(initial_balance + mint_amount), total_supply); - - let bal = query_user_balance(&bank, minter_address, token_address_2, &mut working_set); - - assert_eq!(Some(110), bal); -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/gas_test.rs b/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/gas_test.rs deleted file mode 100644 index 0fb9d7846..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/gas_test.rs +++ /dev/null @@ -1,124 +0,0 @@ -use helpers::*; -use sov_bank::{get_genesis_token_address, Bank, BankConfig, CallMessage, TokenConfig}; -use sov_modules_api::macros::config_constant; -use sov_modules_api::utils::generate_address; -use sov_modules_api::{Context, Module, SpecId, WorkingSet}; -use sov_prover_storage_manager::new_orphan_storage; -use tempfile::TempDir; - -mod helpers; - -#[allow(dead_code)] -pub struct BankGasTestCase { - ws: WorkingSet, - bank: Bank, - ctx: C, - message: CallMessage, - tmpdir: TempDir, - gas_limit: u64, - native_price: u64, - zk_price: u64, -} - -impl BankGasTestCase { - pub fn init(sender_balance: u64) -> Self { - #[config_constant] - const GAS_TOKEN_ADDRESS: &'static str; - let tmpdir = tempfile::tempdir().unwrap(); - - // create a base token with an initial balance to pay for the gas - let base_token_name = "sov-gas-token"; - let salt = 0; - - // sanity check the token address - let base_token_address = get_genesis_token_address::(base_token_name, salt); - assert_eq!(&base_token_address.to_string(), GAS_TOKEN_ADDRESS); - - // generate a token configuration with the provided arguments - let sender_address = generate_address::("sender"); - let address_and_balances = vec![(sender_address, sender_balance)]; - let authorized_minters = vec![]; - let bank_config: BankConfig = BankConfig { - tokens: vec![TokenConfig { - token_name: base_token_name.to_string(), - address_and_balances, - authorized_minters, - salt, - }], - }; - - // create a context using the generated account as sender - let height = 1; - let minter_address = generate_address::("minter"); - let sequencer_address = generate_address::("sequencer"); - let ctx = C::new( - sender_address, - sequencer_address, - height, - SpecId::Genesis, - 0, - ); - - // create a bank instance - let bank = Bank::default(); - let storage = new_orphan_storage(tmpdir.path()).unwrap(); - let mut ws = WorkingSet::new(storage); - bank.genesis(&bank_config, &mut ws).unwrap(); - - // sanity test the sender balance - let balance = bank.get_balance_of(sender_address, base_token_address, &mut ws); - assert_eq!(balance, Some(sender_balance)); - - // generate a create dummy token message - let token_name = "dummy".to_string(); - let initial_balance = 500; - let message = CallMessage::CreateToken:: { - salt, - token_name, - initial_balance, - minter_address, - authorized_minters: vec![minter_address], - }; - - Self { - ws, - bank, - ctx, - message, - tmpdir, - gas_limit: sender_balance, - native_price: 0, - zk_price: 0, - } - } - - pub fn with_native_price(mut self, price: u64) -> Self { - self.native_price = price; - self - } - - pub fn with_zk_price(mut self, price: u64) -> Self { - self.zk_price = price; - self - } - - pub fn execute(self) -> anyhow::Result { - let Self { - mut ws, - mut bank, - ctx, - message, - tmpdir, - gas_limit: _, - native_price: _, - zk_price: _, - } = self; - - bank.call(message, &ctx, &mut ws)?; - - // can unlock storage dir - let _ = tmpdir; - - Ok(0) - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/helpers/mod.rs b/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/helpers/mod.rs deleted file mode 100644 index d49df9e4c..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/helpers/mod.rs +++ /dev/null @@ -1,60 +0,0 @@ -use sov_bank::{BankConfig, TokenConfig, TotalSupplyResponse}; -use sov_modules_api::default_context::DefaultContext; -use sov_modules_api::utils::generate_address as gen_address_generic; -use sov_modules_api::Address; - -pub type C = DefaultContext; - -// This code is not actually dead; rustc treats each test file as a separate crate -// so this code looks unused during some of the compilations. -#[allow(dead_code)] -pub fn generate_address(name: &str) -> Address { - gen_address_generic::(name) -} - -#[allow(dead_code)] -pub fn create_bank_config_with_token( - addresses_count: usize, - initial_balance: u64, -) -> BankConfig { - let address_and_balances = (0..addresses_count) - .map(|i| { - let key = format!("key_{}", i); - let addr = generate_address(&key); - (addr, initial_balance) - }) - .collect(); - - let token_config = TokenConfig { - token_name: "InitialToken".to_owned(), - address_and_balances, - authorized_minters: vec![], - salt: 5, - }; - - BankConfig { - tokens: vec![token_config], - } -} - -// used in tests only -#[allow(dead_code)] -pub fn query_user_balance( - bank: &sov_bank::Bank, - user_address: Address, - token_address: Address, - working_set: &mut sov_modules_api::WorkingSet, -) -> Option { - bank.get_balance_of(user_address, token_address, working_set) -} - -// used in tests only -#[allow(dead_code)] -pub fn query_total_supply( - bank: &sov_bank::Bank, - token_address: Address, - working_set: &mut sov_modules_api::WorkingSet, -) -> Option { - let total_supply: TotalSupplyResponse = bank.supply_of(token_address, working_set).unwrap(); - total_supply.amount -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/mint_test.rs b/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/mint_test.rs deleted file mode 100644 index 183fc2be7..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/mint_test.rs +++ /dev/null @@ -1,290 +0,0 @@ -use helpers::{query_total_supply, query_user_balance, C}; -use sov_bank::{get_token_address, Bank, BankConfig, CallMessage, Coins}; -use sov_modules_api::utils::generate_address; -use sov_modules_api::{Context, Error, Module, SpecId, WorkingSet}; -use sov_prover_storage_manager::{new_orphan_storage, SnapshotManager}; -use sov_state::ProverStorage; - -mod helpers; - -pub type Storage = ProverStorage; - -#[test] -fn mint_token() { - let mut bank = Bank::::default(); - let tmpdir = tempfile::tempdir().unwrap(); - let mut working_set = WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - let empty_bank_config = BankConfig:: { tokens: vec![] }; - bank.genesis(&empty_bank_config, &mut working_set).unwrap(); - - let minter_address = generate_address::("minter"); - let sequencer_address = generate_address::("sequencer"); - let minter_context = C::new(minter_address, sequencer_address, 1, SpecId::Genesis, 0); - - let salt = 0; - let token_name = "Token1".to_owned(); - let initial_balance = 100; - let token_address = get_token_address::(&token_name, minter_address.as_ref(), salt); - - // --- - // Deploying token - let mint_message = CallMessage::CreateToken { - salt, - token_name: token_name.clone(), - initial_balance, - minter_address, - authorized_minters: vec![minter_address], - }; - let _minted = bank - .call(mint_message, &minter_context, &mut working_set) - .expect("Failed to mint token"); - // No events at the moment. If there are, needs to be checked - assert!(working_set.events().is_empty()); - - let previous_total_supply = query_total_supply(&bank, token_address, &mut working_set); - assert_eq!(Some(initial_balance), previous_total_supply); - - // ----- - // Mint Additional - let mint_amount = 10; - let new_holder = generate_address::("new_holder"); - let mint_message = CallMessage::Mint { - coins: Coins { - amount: mint_amount, - token_address, - }, - minter_address: new_holder, - }; - - let _minted = bank - .call(mint_message.clone(), &minter_context, &mut working_set) - .expect("Failed to mint token"); - assert!(working_set.events().is_empty()); - - let total_supply = query_total_supply(&bank, token_address, &mut working_set); - assert_eq!(Some(initial_balance + mint_amount), total_supply); - - // check user balance after minting - let balance = query_user_balance(&bank, new_holder, token_address, &mut working_set); - assert_eq!(Some(10), balance); - - // check original token creation balance - let bal = query_user_balance(&bank, minter_address, token_address, &mut working_set); - assert_eq!(Some(100), bal); - - // Mint with an un-authorized user - let unauthorized_address = generate_address::("unauthorized_address"); - let sequencer_address = generate_address::("sequencer"); - let unauthorized_context = C::new( - unauthorized_address, - sequencer_address, - 1, - SpecId::Genesis, - 0, - ); - let unauthorized_mint = bank.call(mint_message, &unauthorized_context, &mut working_set); - - assert!(unauthorized_mint.is_err()); - - let Error::ModuleError(err) = unauthorized_mint.err().unwrap(); - let mut chain = err.chain(); - - let message_1 = chain.next().unwrap().to_string(); - let message_2 = chain.next().unwrap().to_string(); - assert!(chain.next().is_none()); - - assert_eq!( - format!( - "Failed mint coins(token_address={} amount={}) to {} by authorizer {}", - token_address, mint_amount, new_holder, unauthorized_address - ), - message_1 - ); - assert_eq!( - format!( - "Sender {} is not an authorized minter of token {}", - unauthorized_address, token_name, - ), - message_2 - ); - - // Authorized minter test - let salt = 0; - let token_name = "Token_New".to_owned(); - let initial_balance = 100; - let token_address = get_token_address::(&token_name, minter_address.as_ref(), salt); - let authorized_minter_address_1 = generate_address::("authorized_minter_1"); - let authorized_minter_address_2 = generate_address::("authorized_minter_2"); - let sequencer_address = generate_address::("sequencer"); - // --- - // Deploying token - let mint_message = CallMessage::CreateToken { - salt, - token_name: token_name.clone(), - initial_balance, - minter_address, - authorized_minters: vec![authorized_minter_address_1, authorized_minter_address_2], - }; - let _minted = bank - .call(mint_message, &minter_context, &mut working_set) - .expect("Failed to mint token"); - // No events at the moment. If there are, needs to be checked - assert!(working_set.events().is_empty()); - - // Try to mint new token with original token creator, in this case minter_context - let mint_amount = 10; - let new_holder = generate_address::("new_holder_2"); - let mint_message = CallMessage::Mint { - coins: Coins { - amount: mint_amount, - token_address, - }, - minter_address: new_holder, - }; - - let minted = bank.call(mint_message, &minter_context, &mut working_set); - assert!(minted.is_err()); - let Error::ModuleError(err) = minted.err().unwrap(); - let mut chain = err.chain(); - - let message_1 = chain.next().unwrap().to_string(); - let message_2 = chain.next().unwrap().to_string(); - assert!(chain.next().is_none()); - assert_eq!( - format!( - "Failed mint coins(token_address={} amount={}) to {} by authorizer {}", - token_address, mint_amount, new_holder, minter_address, - ), - message_1 - ); - assert_eq!( - format!( - "Sender {} is not an authorized minter of token {}", - minter_address, token_name - ), - message_2 - ); - // Try to mint new token with authorized sender 2 - let authorized_minter_2_context = C::new( - authorized_minter_address_2, - sequencer_address, - 1, - SpecId::Genesis, - 0, - ); - let mint_message = CallMessage::Mint { - coins: Coins { - amount: mint_amount, - token_address, - }, - minter_address: new_holder, - }; - - let _minted = bank - .call(mint_message, &authorized_minter_2_context, &mut working_set) - .expect("Failed to mint token"); - let supply = query_total_supply(&bank, token_address, &mut working_set); - assert!(working_set.events().is_empty()); - assert_eq!(Some(110), supply); - - // Try to mint new token with authorized sender 1 - let authorized_minter_1_context = C::new( - authorized_minter_address_1, - sequencer_address, - 1, - SpecId::Genesis, - 0, - ); - let mint_message = CallMessage::Mint { - coins: Coins { - amount: mint_amount, - token_address, - }, - minter_address: new_holder, - }; - - let _minted = bank - .call(mint_message, &authorized_minter_1_context, &mut working_set) - .expect("Failed to mint token"); - let supply = query_total_supply(&bank, token_address, &mut working_set); - assert!(working_set.events().is_empty()); - assert_eq!(Some(120), supply); - - // Overflow test - account balance - let overflow_mint_message = CallMessage::Mint { - coins: Coins { - amount: u64::MAX, - token_address, - }, - minter_address: new_holder, - }; - - let minted = bank.call( - overflow_mint_message, - &authorized_minter_1_context, - &mut working_set, - ); - assert!(minted.is_err()); - let Error::ModuleError(err) = minted.err().unwrap(); - let mut chain = err.chain(); - let message_1 = chain.next().unwrap().to_string(); - let message_2 = chain.next().unwrap().to_string(); - assert!(chain.next().is_none()); - assert_eq!( - format!( - "Failed mint coins(token_address={} amount={}) to {} by authorizer {}", - token_address, - u64::MAX, - new_holder, - authorized_minter_address_1, - ), - message_1 - ); - assert_eq!( - "Account balance overflow in the mint method of bank module", - message_2, - ); - // assert that the supply is unchanged after the overflow mint - let supply = query_total_supply(&bank, token_address, &mut working_set); - assert_eq!(Some(120), supply); - - // Overflow test 2 - total supply - let new_holder = generate_address::("new_holder_3"); - let overflow_mint_message = CallMessage::Mint { - coins: Coins { - amount: u64::MAX - 1, - token_address, - }, - minter_address: new_holder, - }; - - let minted = bank.call( - overflow_mint_message, - &authorized_minter_1_context, - &mut working_set, - ); - assert!(minted.is_err()); - let Error::ModuleError(err) = minted.err().unwrap(); - let mut chain = err.chain(); - let message_1 = chain.next().unwrap().to_string(); - let message_2 = chain.next().unwrap().to_string(); - assert!(chain.next().is_none()); - assert_eq!( - format!( - "Failed mint coins(token_address={} amount={}) to {} by authorizer {}", - token_address, - u64::MAX - 1, - new_holder, - authorized_minter_address_1, - ), - message_1 - ); - assert_eq!( - "Total Supply overflow in the mint method of bank module", - message_2, - ); - - // assert that the supply is unchanged after the overflow mint - let supply = query_total_supply(&bank, token_address, &mut working_set); - assert_eq!(Some(120), supply); -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/transfer_test.rs b/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/transfer_test.rs deleted file mode 100644 index d90a85e68..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-bank/tests/transfer_test.rs +++ /dev/null @@ -1,337 +0,0 @@ -mod helpers; - -use helpers::*; -use sov_bank::{ - get_genesis_token_address, get_token_address, Bank, BankConfig, CallMessage, Coins, -}; -use sov_modules_api::utils::generate_address; -use sov_modules_api::{Context, Error, Module, SpecId, WorkingSet}; -use sov_prover_storage_manager::{new_orphan_storage, SnapshotManager}; -use sov_state::ProverStorage; - -pub type Storage = ProverStorage; - -#[test] -fn transfer_initial_token() { - let initial_balance = 100; - let transfer_amount = 10; - let bank_config = create_bank_config_with_token(4, initial_balance); - let token_name = bank_config.tokens[0].token_name.clone(); - let tmpdir = tempfile::tempdir().unwrap(); - let mut working_set = WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - let mut bank = Bank::default(); - bank.genesis(&bank_config, &mut working_set).unwrap(); - - let token_address = get_genesis_token_address::( - &bank_config.tokens[0].token_name, - bank_config.tokens[0].salt, - ); - let sender_address = bank_config.tokens[0].address_and_balances[0].0; - let receiver_address = bank_config.tokens[0].address_and_balances[1].0; - let sequencer_address = bank_config.tokens[0].address_and_balances[3].0; - assert_ne!(sender_address, receiver_address); - - let sender_balance_before = - query_user_balance(&bank, sender_address, token_address, &mut working_set); - let receiver_balance_before = - query_user_balance(&bank, receiver_address, token_address, &mut working_set); - let total_supply_before = query_total_supply(&bank, token_address, &mut working_set); - assert!(total_supply_before.is_some()); - - assert_eq!(Some(initial_balance), sender_balance_before); - assert_eq!(sender_balance_before, receiver_balance_before); - let sender_context = C::new(sender_address, sequencer_address, 1, SpecId::Genesis, 0); - - // Transfer happy test - { - let transfer_message = CallMessage::Transfer { - to: receiver_address, - coins: Coins { - amount: transfer_amount, - token_address, - }, - }; - - bank.call(transfer_message, &sender_context, &mut working_set) - .expect("Transfer call failed"); - assert!(working_set.events().is_empty()); - - let sender_balance_after = - query_user_balance(&bank, sender_address, token_address, &mut working_set); - let receiver_balance_after = - query_user_balance(&bank, receiver_address, token_address, &mut working_set); - - assert_eq!( - Some(initial_balance - transfer_amount), - sender_balance_after - ); - assert_eq!( - Some(initial_balance + transfer_amount), - receiver_balance_after - ); - let total_supply_after = query_total_supply(&bank, token_address, &mut working_set); - assert_eq!(total_supply_before, total_supply_after); - } - - // Not enough balance - { - let transfer_message = CallMessage::Transfer { - to: receiver_address, - coins: Coins { - amount: initial_balance + 1, - token_address, - }, - }; - - let result = bank.call(transfer_message, &sender_context, &mut working_set); - assert!(result.is_err()); - let Error::ModuleError(err) = result.err().unwrap(); - let mut chain = err.chain(); - let message_1 = chain.next().unwrap().to_string(); - let message_2 = chain.next().unwrap().to_string(); - let message_3 = chain.next().unwrap().to_string(); - assert!(chain.next().is_none()); - assert_eq!( - format!( - "Failed transfer from={} to={} of coins(token_address={} amount={})", - sender_address, - receiver_address, - token_address, - initial_balance + 1, - ), - message_1 - ); - assert_eq!( - format!( - "Incorrect balance on={} for token={}", - sender_address, token_name - ), - message_2, - ); - assert_eq!( - format!("Insufficient funds for {}", sender_address), - message_3, - ); - } - - // Non existent token - { - let salt = 13; - let token_name = "NonExistingToken".to_owned(); - let token_address = get_token_address::(&token_name, sender_address.as_ref(), salt); - - let transfer_message = CallMessage::Transfer { - to: receiver_address, - coins: Coins { - amount: 1, - token_address, - }, - }; - - let result = bank.call(transfer_message, &sender_context, &mut working_set); - assert!(result.is_err()); - let Error::ModuleError(err) = result.err().unwrap(); - let mut chain = err.chain(); - let message_1 = chain.next().unwrap().to_string(); - let message_2 = chain.next().unwrap().to_string(); - assert!(chain.next().is_none()); - assert_eq!( - format!( - "Failed transfer from={} to={} of coins(token_address={} amount={})", - sender_address, receiver_address, token_address, 1, - ), - message_1 - ); - assert!( - // .starts_with("Value not found for prefix: \"sov_bank/Bank/tokens/\" and: storage key")); - message_2.starts_with("Value not found for prefix: \"Bank/tokens/\" and: storage key") - ); - } - - // Sender does not exist - { - let unknown_sender = generate_address::("non_existing_sender"); - let sequencer = generate_address::("sequencer"); - let unknown_sender_context = C::new(unknown_sender, sequencer, 1, SpecId::Genesis, 0); - - let sender_balance = - query_user_balance(&bank, unknown_sender, token_address, &mut working_set); - assert!(sender_balance.is_none()); - - let receiver_balance_before = - query_user_balance(&bank, receiver_address, token_address, &mut working_set); - - let transfer_message = CallMessage::Transfer { - to: receiver_address, - coins: Coins { - amount: 1, - token_address, - }, - }; - - let result = bank.call(transfer_message, &unknown_sender_context, &mut working_set); - assert!(result.is_err()); - let Error::ModuleError(err) = result.err().unwrap(); - let mut chain = err.chain(); - let message_1 = chain.next().unwrap().to_string(); - let message_2 = chain.next().unwrap().to_string(); - let message_3 = chain.next().unwrap().to_string(); - assert!(chain.next().is_none()); - - assert_eq!( - format!( - "Failed transfer from={} to={} of coins(token_address={} amount={})", - unknown_sender, receiver_address, token_address, 1, - ), - message_1 - ); - assert_eq!( - format!( - "Incorrect balance on={} for token={}", - unknown_sender, token_name - ), - message_2, - ); - - // "Value not found for prefix: \"sov_bank/Bank/tokens/{}\" and: storage key", - let expected_message_part = format!( - "Value not found for prefix: \"Bank/tokens/{}\" and: storage key", - token_address - ); - - assert!(message_3.contains(&expected_message_part)); - - let receiver_balance_after = - query_user_balance(&bank, receiver_address, token_address, &mut working_set); - assert_eq!(receiver_balance_before, receiver_balance_after); - } - - // Receiver does not exist - { - let unknown_receiver = generate_address::("non_existing_receiver"); - - let receiver_balance_before = - query_user_balance(&bank, unknown_receiver, token_address, &mut working_set); - assert!(receiver_balance_before.is_none()); - - let transfer_message = CallMessage::Transfer { - to: unknown_receiver, - coins: Coins { - amount: 1, - token_address, - }, - }; - - bank.call(transfer_message, &sender_context, &mut working_set) - .expect("Transfer call failed"); - assert!(working_set.events().is_empty()); - - let receiver_balance_after = - query_user_balance(&bank, unknown_receiver, token_address, &mut working_set); - assert_eq!(Some(1), receiver_balance_after) - } - - // Sender equals receiver - { - let total_supply_before = query_total_supply(&bank, token_address, &mut working_set); - let sender_balance_before = - query_user_balance(&bank, sender_address, token_address, &mut working_set); - assert!(sender_balance_before.is_some()); - - let transfer_message = CallMessage::Transfer { - to: sender_address, - coins: Coins { - amount: 1, - token_address, - }, - }; - bank.call(transfer_message, &sender_context, &mut working_set) - .expect("Transfer call failed"); - assert!(working_set.events().is_empty()); - - let sender_balance_after = - query_user_balance(&bank, sender_address, token_address, &mut working_set); - assert_eq!(sender_balance_before, sender_balance_after); - let total_supply_after = query_total_supply(&bank, token_address, &mut working_set); - assert_eq!(total_supply_after, total_supply_before); - } -} - -#[test] -fn transfer_deployed_token() { - let mut bank = Bank::::default(); - let tmpdir = tempfile::tempdir().unwrap(); - let mut working_set = WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - let empty_bank_config = BankConfig:: { tokens: vec![] }; - bank.genesis(&empty_bank_config, &mut working_set).unwrap(); - - let sender_address = generate_address::("just_sender"); - let receiver_address = generate_address::("just_receiver"); - let sequencer_address = generate_address::("just_sequencer"); - - let salt = 10; - let token_name = "Token1".to_owned(); - let initial_balance = 1000; - let token_address = get_token_address::(&token_name, sender_address.as_ref(), salt); - - assert_ne!(sender_address, receiver_address); - - let sender_balance_before = - query_user_balance(&bank, sender_address, token_address, &mut working_set); - let receiver_balance_before = - query_user_balance(&bank, receiver_address, token_address, &mut working_set); - let total_supply_before = query_total_supply(&bank, token_address, &mut working_set); - assert!(total_supply_before.is_none()); - - assert!(sender_balance_before.is_none()); - assert!(receiver_balance_before.is_none()); - let sender_context = C::new(sender_address, sequencer_address, 1, SpecId::Genesis, 0); - - let mint_message = CallMessage::CreateToken { - salt, - token_name, - initial_balance, - minter_address: sender_address, - authorized_minters: vec![sender_address], - }; - bank.call(mint_message, &sender_context, &mut working_set) - .expect("Failed to mint token"); - // No events at the moment. If there are, needs to be checked - assert!(working_set.events().is_empty()); - let total_supply_before = query_total_supply(&bank, token_address, &mut working_set); - assert!(total_supply_before.is_some()); - - let sender_balance_before = - query_user_balance(&bank, sender_address, token_address, &mut working_set); - let receiver_balance_before = - query_user_balance(&bank, receiver_address, token_address, &mut working_set); - - assert_eq!(Some(initial_balance), sender_balance_before); - assert!(receiver_balance_before.is_none()); - - let transfer_amount = 15; - let transfer_message = CallMessage::Transfer { - to: receiver_address, - coins: Coins { - amount: transfer_amount, - token_address, - }, - }; - - bank.call(transfer_message, &sender_context, &mut working_set) - .expect("Transfer call failed"); - assert!(working_set.events().is_empty()); - - let sender_balance_after = - query_user_balance(&bank, sender_address, token_address, &mut working_set); - let receiver_balance_after = - query_user_balance(&bank, receiver_address, token_address, &mut working_set); - - assert_eq!( - Some(initial_balance - transfer_amount), - sender_balance_after - ); - assert_eq!(Some(transfer_amount), receiver_balance_after); - let total_supply_after = query_total_supply(&bank, token_address, &mut working_set); - assert_eq!(total_supply_before, total_supply_after); -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives/Cargo.toml b/crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives/Cargo.toml deleted file mode 100644 index fb7d0ab0b..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -name = "sov-prover-incentives" -description = "A Sovereign SDK module for incentivizing provers" -authors = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -repository = { workspace = true } - -version = { workspace = true } -readme = "README.md" -resolver = "2" - -[dev-dependencies] -tempfile = { workspace = true } -sov-mock-da = { path = "../../../adapters/mock-da", features = ["native"] } -sov-mock-zkvm = { path = "../../../adapters/mock-zkvm" } -sov-modules-api = { path = "../../sov-modules-api", features = ["native"] } -sov-prover-storage-manager = { path = "../../../full-node/sov-prover-storage-manager", features = ["test-utils"] } - - -[dependencies] -anyhow = { workspace = true } -borsh = { workspace = true, features = ["rc"] } -bincode = { workspace = true } -schemars = { workspace = true, optional = true } -serde = { workspace = true } -serde_json = { workspace = true, optional = true } - -sov-bank = { path = "../sov-bank" } -sov-modules-api = { path = "../../sov-modules-api" } -sov-state = { path = "../../sov-state" } - - -[features] -default = ["native"] -native = ["serde_json", "schemars", "sov-state/native", "sov-modules-api/native"] diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives/README.md b/crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives/README.md deleted file mode 100644 index 5c28c6d6b..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Prover Incentives - -**_This module is a placeholder for the logic incentivizing provers_** - -This module implements the logic for processing proof transactions. Such -logic is necessary if you want to reward provers or do anything else that's "aware" of proof -generation inside you state transition function. - -Currently, this module allows provers to register and de-register, and allows the on-chain validation -of proofs from registered provers. If proof validation fails, the offending prover is slashed. - -This module does _not_ reward provers - incentives for provers will depend on gas metering, which has -yet to be implemented. diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives/src/call.rs b/crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives/src/call.rs deleted file mode 100644 index 539f330d1..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives/src/call.rs +++ /dev/null @@ -1,160 +0,0 @@ -use std::fmt::Debug; - -use anyhow::Result; -use borsh::{BorshDeserialize, BorshSerialize}; -use sov_bank::Coins; -use sov_modules_api::prelude::*; -use sov_modules_api::{CallResponse, WorkingSet}; - -use crate::ProverIncentives; - -/// This enumeration represents the available call messages for interacting with the `ExampleModule` module. -#[cfg_attr(feature = "native", derive(schemars::JsonSchema))] -#[derive(BorshDeserialize, BorshSerialize, Debug, PartialEq)] -// TODO: allow call messages to borrow data -// https://github.com/Sovereign-Labs/sovereign-sdk/issues/274 -pub enum CallMessage { - /// Bonds the prover with provided bond. - BondProver(u64), - /// Unbonds the prover. - UnbondProver, - /// Verifies the provided proof (of format `Vec`) - VerifyProof(Vec), -} - -impl ProverIncentives { - /// A helper function for the `bond_prover` call. Also used to bond provers - /// during genesis when no context is available. - pub(super) fn bond_prover_helper( - &self, - bond_amount: u64, - prover: &C::Address, - working_set: &mut WorkingSet, - ) -> Result { - // Transfer the bond amount from the sender to the module's address. - // On failure, no state is changed - let coins = Coins { - token_address: self - .bonding_token_address - .get(working_set) - .expect("Bonding token address must be set"), - amount: bond_amount, - }; - self.bank - .transfer_from(prover, &self.address, coins, working_set)?; - - // Update our record of the total bonded amount for the sender. - // This update is infallible, so no value can be destroyed. - let old_balance = self - .bonded_provers - .get(prover, working_set) - .unwrap_or_default(); - let total_balance = old_balance + bond_amount; - self.bonded_provers.set(prover, &total_balance, working_set); - - // Emit the bonding event - working_set.add_event( - "bonded_prover", - &format!("new_deposit: {bond_amount:?}. total_bond: {total_balance:?}"), - ); - - Ok(CallResponse::default()) - } - - /// Try to bond the requested amount of coins from context.sender() - pub(crate) fn bond_prover( - &self, - bond_amount: u64, - context: &C, - working_set: &mut WorkingSet, - ) -> Result { - self.bond_prover_helper(bond_amount, context.sender(), working_set) - } - - /// Try to unbond the requested amount of coins with context.sender() as the beneficiary. - pub(crate) fn unbond_prover( - &self, - context: &C, - working_set: &mut WorkingSet, - ) -> Result { - // Get the prover's old balance. - if let Some(old_balance) = self.bonded_provers.get(context.sender(), working_set) { - // Transfer the bond amount from the sender to the module's address. - // On failure, no state is changed - let coins = Coins { - token_address: self - .bonding_token_address - .get(working_set) - .expect("Bonding token address must be set"), - amount: old_balance, - }; - // Try to unbond the entire balance - // If the unbonding fails, no state is changed - self.bank - .transfer_from(&self.address, context.sender(), coins, working_set)?; - - // Update our internal tracking of the total bonded amount for the sender. - self.bonded_provers.set(context.sender(), &0, working_set); - - // Emit the unbonding event - working_set.add_event( - "unbonded_prover", - &format!("amount_withdrawn: {old_balance:?}"), - ); - } - - Ok(CallResponse::default()) - } - - /// Try to process a zk proof, if the prover is bonded. - pub(crate) fn process_proof( - &self, - proof: &[u8], - context: &C, - working_set: &mut WorkingSet, - ) -> Result { - // Get the prover's old balance. - // Revert if they aren't bonded - let old_balance = self - .bonded_provers - .get_or_err(context.sender(), working_set)?; - - // Check that the prover has enough balance to process the proof. - let minimum_bond = self.minimum_bond.get_or_err(working_set)?; - - anyhow::ensure!(old_balance >= minimum_bond, "Prover is not bonded"); - let code_commitment = self - .commitment_of_allowed_verifier_method - .get_or_err(working_set)?; - - // Lock the prover's bond amount. - self.bonded_provers - .set(context.sender(), &(old_balance - minimum_bond), working_set); - - // Don't return an error for invalid proofs - those are expected and shouldn't cause reverts. - if let Ok(_public_outputs) = - Vm::verify(proof, &code_commitment).map_err(|e| anyhow::format_err!("{:?}", e)) - { - // TODO: decide what the proof output is and do something with it - // https://github.com/Sovereign-Labs/sovereign-sdk/issues/272 - - // Unlock the prover's bond - // TODO: reward the prover with newly minted tokens as appropriate based on gas fees. - // https://github.com/Sovereign-Labs/sovereign-sdk/issues/271 - self.bonded_provers - .set(context.sender(), &old_balance, working_set); - - working_set.add_event( - "processed_valid_proof", - &format!("prover: {:?}", context.sender()), - ); - } else { - working_set.add_event( - "processed_invalid_proof", - &format!("slashed_prover: {:?}", context.sender()), - ); - } - - Ok(CallResponse::default()) - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives/src/genesis.rs b/crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives/src/genesis.rs deleted file mode 100644 index 22431c18f..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives/src/genesis.rs +++ /dev/null @@ -1,50 +0,0 @@ -use anyhow::Result; -use serde::{Deserialize, Serialize}; -use sov_modules_api::prelude::*; -use sov_modules_api::{WorkingSet, Zkvm}; - -use crate::ProverIncentives; - -/// Configuration of the prover incentives module. Specifies the -/// address of the bonding token, the minimum bond, the commitment to -/// the allowed verifier method and a set of initial provers with their -/// bonding amount. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ProverIncentivesConfig { - /// The address of the token to be used for bonding. - pub bonding_token_address: C::Address, - /// The minimum bond for a prover. - pub minimum_bond: u64, - /// A code commitment to be used for verifying proofs - pub commitment_of_allowed_verifier_method: Vm::CodeCommitment, - /// A list of initial provers and their bonded amount. - pub initial_provers: Vec<(C::Address, u64)>, -} - -impl ProverIncentives { - /// Init the [`ProverIncentives`] module using the provided `config`. - /// Sets the minimum amount necessary to bond, the commitment to the verifier circuit - /// the bonding token address and builds the set of initial provers. - pub(crate) fn init_module( - &self, - config: &::Config, - working_set: &mut WorkingSet, - ) -> Result<()> { - anyhow::ensure!( - !config.initial_provers.is_empty(), - "At least one prover must be set at genesis!" - ); - - self.minimum_bond.set(&config.minimum_bond, working_set); - self.commitment_of_allowed_verifier_method - .set(&config.commitment_of_allowed_verifier_method, working_set); - self.bonding_token_address - .set(&config.bonding_token_address, working_set); - - for (prover, bond) in config.initial_provers.iter() { - self.bond_prover_helper(*bond, prover, working_set)?; - } - - Ok(()) - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives/src/lib.rs b/crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives/src/lib.rs deleted file mode 100644 index fb11a6842..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives/src/lib.rs +++ /dev/null @@ -1,84 +0,0 @@ -#![deny(missing_docs)] -#![doc = include_str!("../README.md")] -mod call; -mod genesis; - -#[cfg(all(test, feature = "native"))] -mod tests; - -#[cfg(feature = "native")] -mod query; - -pub use call::*; -pub use genesis::*; -/// The response type used by RPC queries. -#[cfg(feature = "native")] -pub use query::*; -use sov_modules_api::{Context, Error, ModuleInfo, WorkingSet, Zkvm}; -use sov_state::codec::BcsCodec; - -/// A new module: -/// - Must derive `ModuleInfo` -/// - Must contain `[address]` field -/// - Can contain any number of ` #[state]` or `[module]` fields -#[cfg_attr(feature = "native", derive(sov_modules_api::ModuleCallJsonSchema))] -#[derive(ModuleInfo)] -pub struct ProverIncentives { - /// Address of the module. - #[address] - pub address: C::Address, - - /// The address of the token used for bonding provers - #[state] - pub bonding_token_address: sov_modules_api::StateValue, - - /// The code commitment to be used for verifying proofs - #[state] - pub commitment_of_allowed_verifier_method: - sov_modules_api::StateValue, - - /// The set of registered provers and their bonded amount. - #[state] - pub bonded_provers: sov_modules_api::StateMap, - - /// The minimum bond for a prover to be eligible for onchain verification - #[state] - pub minimum_bond: sov_modules_api::StateValue, - - /// Reference to the Bank module. - #[module] - pub(crate) bank: sov_bank::Bank, -} - -impl sov_modules_api::Module for ProverIncentives { - type Context = C; - - type Config = ProverIncentivesConfig; - - type CallMessage = call::CallMessage; - - type Event = (); - - fn genesis(&self, config: &Self::Config, working_set: &mut WorkingSet) -> Result<(), Error> { - // The initialization logic - Ok(self.init_module(config, working_set)?) - } - - fn call( - &mut self, - msg: Self::CallMessage, - context: &Self::Context, - working_set: &mut WorkingSet, - ) -> Result { - match msg { - call::CallMessage::BondProver(bond_amount) => { - self.bond_prover(bond_amount, context, working_set) - } - call::CallMessage::UnbondProver => self.unbond_prover(context, working_set), - call::CallMessage::VerifyProof(proof) => { - self.process_proof(&proof, context, working_set) - } - } - .map_err(|e| e.into()) - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives/src/query.rs b/crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives/src/query.rs deleted file mode 100644 index 1a339fd38..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives/src/query.rs +++ /dev/null @@ -1,28 +0,0 @@ -use serde::{Deserialize, Serialize}; -use sov_modules_api::{StateMapAccessor, WorkingSet}; - -use super::ProverIncentives; - -/// The structure containing the response returned by the `get_bond_amount` query. -#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] -pub struct Response { - /// The bond value stored as a `u64`. - pub value: u64, -} - -impl ProverIncentives { - /// Queries the state of the module and returns the bond amount of the address `address`. - /// If the `address` is not bonded, returns a default value. - pub fn get_bond_amount( - &self, - address: C::Address, - working_set: &mut WorkingSet, - ) -> Response { - Response { - value: self - .bonded_provers - .get(&address, working_set) - .unwrap_or_default(), // self.value.get(working_set), - } - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives/src/tests.rs b/crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives/src/tests.rs deleted file mode 100644 index 3ae427280..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-prover-incentives/src/tests.rs +++ /dev/null @@ -1,234 +0,0 @@ -use sov_mock_da::MockValidityCond; -use sov_mock_zkvm::{MockCodeCommitment, MockProof, MockZkvm}; -use sov_modules_api::default_context::DefaultContext; -use sov_modules_api::digest::Digest; -use sov_modules_api::prelude::*; -use sov_modules_api::{Address, Context, Module, Spec, SpecId, WorkingSet}; -use sov_prover_storage_manager::new_orphan_storage; - -use crate::ProverIncentives; - -type C = DefaultContext; - -const BOND_AMOUNT: u64 = 1000; -const MOCK_CODE_COMMITMENT: MockCodeCommitment = MockCodeCommitment([0u8; 32]); - -/// Generates an address by hashing the provided `key`. -pub fn generate_address(key: &str) -> ::Address { - let hash: [u8; 32] = ::Hasher::digest(key.as_bytes()).into(); - Address::from(hash) -} - -fn create_bank_config() -> ( - sov_bank::BankConfig, - ::Address, - ::Address, -) { - let prover_address = generate_address("prover_pub_key"); - let sequencer_address = generate_address("sequencer_pub_key"); - - let token_config = sov_bank::TokenConfig { - token_name: "InitialToken".to_owned(), - address_and_balances: vec![(prover_address, BOND_AMOUNT * 5)], - authorized_minters: vec![prover_address], - salt: 2, - }; - - ( - sov_bank::BankConfig { - tokens: vec![token_config], - }, - prover_address, - sequencer_address, - ) -} - -fn setup( - working_set: &mut WorkingSet, -) -> ( - ProverIncentives>, - Address, - Address, -) { - // Initialize bank - let (bank_config, prover_address, sequencer) = create_bank_config(); - let bank = sov_bank::Bank::::default(); - bank.genesis(&bank_config, working_set) - .expect("bank genesis must succeed"); - - let token_address = sov_bank::get_genesis_token_address::( - &bank_config.tokens[0].token_name, - bank_config.tokens[0].salt, - ); - - // initialize prover incentives - let module = ProverIncentives::>::default(); - let config = crate::ProverIncentivesConfig { - bonding_token_address: token_address, - minimum_bond: BOND_AMOUNT, - commitment_of_allowed_verifier_method: MockCodeCommitment([0u8; 32]), - initial_provers: vec![(prover_address, BOND_AMOUNT)], - }; - - module - .genesis(&config, working_set) - .expect("prover incentives genesis must succeed"); - (module, prover_address, sequencer) -} - -#[test] -fn test_burn_on_invalid_proof() { - let tmpdir = tempfile::tempdir().unwrap(); - let mut working_set = WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - let (module, prover_address, sequencer) = setup(&mut working_set); - - // Assert that the prover has the correct bond amount before processing the proof - assert_eq!( - module - .get_bond_amount(prover_address, &mut working_set) - .value, - BOND_AMOUNT - ); - - // Process an invalid proof - { - let context = DefaultContext::new(prover_address, sequencer, 1, SpecId::Genesis, 0); - let proof = MockProof { - program_id: MOCK_CODE_COMMITMENT, - is_valid: false, - log: vec![], - }; - module - .process_proof(proof.encode_to_vec().as_ref(), &context, &mut working_set) - .expect("An invalid proof is not an error"); - } - - // Assert that the prover's bond amount has been burned - assert_eq!( - module - .get_bond_amount(prover_address, &mut working_set) - .value, - 0 - ); -} - -#[test] -fn test_valid_proof() { - let tmpdir = tempfile::tempdir().unwrap(); - let mut working_set = WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - let (module, prover_address, sequencer) = setup(&mut working_set); - - // Assert that the prover has the correct bond amount before processing the proof - assert_eq!( - module - .get_bond_amount(prover_address, &mut working_set) - .value, - BOND_AMOUNT - ); - - // Process a valid proof - { - let context = DefaultContext::new(prover_address, sequencer, 1, SpecId::Genesis, 0); - let proof = MockProof { - program_id: MOCK_CODE_COMMITMENT, - is_valid: true, - log: vec![], - }; - module - .process_proof(proof.encode_to_vec().as_ref(), &context, &mut working_set) - .expect("An invalid proof is not an error"); - } - - // Assert that the prover's bond amount has not been burned - assert_eq!( - module - .get_bond_amount(prover_address, &mut working_set) - .value, - BOND_AMOUNT - ); -} - -#[test] -fn test_unbonding() { - let tmpdir = tempfile::tempdir().unwrap(); - let mut working_set = WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - let (module, prover_address, sequencer) = setup(&mut working_set); - let context = DefaultContext::new(prover_address, sequencer, 1, SpecId::Genesis, 0); - let token_address = module - .bonding_token_address - .get(&mut working_set) - .expect("bonding token address was set at genesis"); - - // Assert that the prover has bonded tokens - assert_eq!( - module - .get_bond_amount(prover_address, &mut working_set) - .value, - BOND_AMOUNT - ); - - // Get their *unlocked* balance before undbonding - let initial_unlocked_balance = { - module - .bank - .get_balance_of(prover_address, token_address, &mut working_set) - .unwrap_or_default() - }; - - // Unbond the prover - module - .unbond_prover(&context, &mut working_set) - .expect("Unbonding should succeed"); - - // Assert that the prover no longer has bonded tokens - assert_eq!( - module - .get_bond_amount(prover_address, &mut working_set) - .value, - 0 - ); - - // Assert that the prover's unlocked balance has increased by the amount they unbonded - let unlocked_balance = - module - .bank - .get_balance_of(prover_address, token_address, &mut working_set); - assert_eq!( - unlocked_balance, - Some(BOND_AMOUNT + initial_unlocked_balance) - ); -} - -#[test] -fn test_prover_not_bonded() { - let tmpdir = tempfile::tempdir().unwrap(); - let mut working_set = WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - let (module, prover_address, sequencer) = setup(&mut working_set); - let context = DefaultContext::new(prover_address, sequencer, 1, SpecId::Genesis, 0); - - // Unbond the prover - module - .unbond_prover(&context, &mut working_set) - .expect("Unbonding should succeed"); - - // Assert that the prover no longer has bonded tokens - assert_eq!( - module - .get_bond_amount(prover_address, &mut working_set) - .value, - 0 - ); - - // Process a valid proof - { - let proof = MockProof { - program_id: MOCK_CODE_COMMITMENT, - is_valid: true, - log: vec![], - }; - // Assert that processing a valid proof fails - assert!(module - .process_proof(proof.encode_to_vec().as_ref(), &context, &mut working_set) - .is_err()) - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/Cargo.toml b/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/Cargo.toml deleted file mode 100644 index bd49d0645..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/Cargo.toml +++ /dev/null @@ -1,76 +0,0 @@ -[package] -name = "sov-sequencer-registry" -description = "A Sovereign SDK module for registering rollup sequencers" -authors = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -repository = { workspace = true } - -version = { workspace = true } -readme = "README.md" - -resolver = "2" - -[dependencies] -anyhow = { workspace = true } -arbitrary = { workspace = true, optional = true } -clap = { workspace = true, optional = true } -proptest = { workspace = true, optional = true } -proptest-derive = { workspace = true, optional = true } -sov-bank = { path = "../sov-bank" } -sov-modules-api = { path = "../../sov-modules-api", default-features = false } -sov-state = { path = "../../sov-state" } -schemars = { workspace = true, optional = true } -serde = { workspace = true } -serde_json = { workspace = true, optional = true } -borsh = { workspace = true, features = ["rc"] } -jsonrpsee = { workspace = true, features = [ - "macros", - "client-core", - "server", -], optional = true } -sov-zk-cycle-macros = { path = "../../../utils/zk-cycle-macros", optional = true } -risc0-zkvm = { workspace = true, default-features = false, features = [ - "std", -], optional = true } -risc0-zkvm-platform = { workspace = true, optional = true } -sov-zk-cycle-utils = { path = "../../../utils/zk-cycle-utils", optional = true } - -[dev-dependencies] -tempfile = { workspace = true } -sov-sequencer-registry = { path = ".", features = ["native"] } -sov-mock-da = { path = "../../../adapters/mock-da", features = ["native"] } -sov-prover-storage-manager = { path = "../../../full-node/sov-prover-storage-manager", features = [ - "test-utils", -] } - -[features] -bench = [ - "sov-zk-cycle-macros/bench", - "risc0-zkvm", - "risc0-zkvm-platform", - "sov-zk-cycle-utils", -] -default = [] -arbitrary = ["dep:arbitrary", "dep:proptest", "dep:proptest-derive"] -native = [ - "serde", - "serde_json", - "jsonrpsee", - "schemars", - "clap", - "sov-state/native", - "sov-modules-api/native", - # This: - "sov-bank/native", -] -serde = [] - -[package.metadata.cargo-udeps.ignore] -normal = [ - "risc0-zkvm", - "risc0-zkvm-platform", - "sov-zk-cycle-macros", - "sov-zk-cycle-utils", -] diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/README.md b/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/README.md deleted file mode 100644 index 16ebbdee5..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# `sov-sequencer-registry` module - -The `sov-sequencer-registry` module is responsible for sequencer registration, slashing, and rewards. At the moment, only a centralized sequencer is supported. The sequencer's address and bond are registered during the rollup deployment. diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/src/call.rs b/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/src/call.rs deleted file mode 100644 index 070533617..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/src/call.rs +++ /dev/null @@ -1,82 +0,0 @@ -use anyhow::bail; -#[cfg(feature = "native")] -use sov_modules_api::macros::CliWalletArg; -use sov_modules_api::prelude::*; -use sov_modules_api::{CallResponse, WorkingSet}; - -use crate::SequencerRegistry; - -/// This enumeration represents the available call messages for interacting with -/// the `sov-sequencer-registry` module. -#[cfg_attr(feature = "native", derive(schemars::JsonSchema), derive(CliWalletArg))] -#[cfg_attr( - feature = "serde", - derive(serde::Serialize), - derive(serde::Deserialize) -)] -#[cfg_attr( - feature = "arbitrary", - derive(arbitrary::Arbitrary, proptest_derive::Arbitrary) -)] -#[derive(Debug, PartialEq, Clone, borsh::BorshSerialize, borsh::BorshDeserialize)] -pub enum CallMessage { - /// Add a new sequencer to the sequencer registry. - Register { - /// The raw Da address of the sequencer you're registering. - da_address: Vec, - }, - /// Remove a sequencer from the sequencer registry. - Exit { - /// The raw Da address of the sequencer you're removing. - da_address: Vec, - }, -} - -impl SequencerRegistry { - pub(crate) fn register( - &self, - da_address: &Da::Address, - context: &C, - working_set: &mut WorkingSet, - ) -> anyhow::Result { - let sequencer = context.sender(); - self.register_sequencer(da_address, sequencer, working_set)?; - Ok(CallResponse::default()) - } - - pub(crate) fn exit( - &self, - da_address: &Da::Address, - context: &C, - working_set: &mut WorkingSet, - ) -> anyhow::Result { - let locker = &self.address; - let coins = self.coins_to_lock.get_or_err(working_set)?; - let sequencer = context.sender(); - - let belongs_to = self - .allowed_sequencers - .get_or_err(da_address, working_set)?; - - if sequencer != &belongs_to { - bail!("Unauthorized exit attempt"); - } - - self.delete(da_address, working_set); - - self.bank - .transfer_from(locker, sequencer, coins, working_set)?; - - Ok(CallResponse::default()) - } - - pub(crate) fn delete(&self, da_address: &Da::Address, working_set: &mut WorkingSet) { - self.allowed_sequencers.delete(da_address, working_set); - - if let Some(preferred_sequencer) = self.preferred_sequencer.get(working_set) { - if da_address == &preferred_sequencer { - self.preferred_sequencer.delete(working_set); - } - } - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/src/genesis.rs b/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/src/genesis.rs deleted file mode 100644 index 8eb242580..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/src/genesis.rs +++ /dev/null @@ -1,117 +0,0 @@ -use anyhow::Result; -use serde::{Deserialize, Serialize}; -use sov_modules_api::prelude::*; -use sov_modules_api::WorkingSet; - -use crate::SequencerRegistry; - -/// Genesis configuration for the [`SequencerRegistry`] module. -/// -/// This `struct` must be passed as an argument to -/// [`Module::genesis`](sov_modules_api::Module::genesis). -/// -// TODO: Should we allow multiple sequencers in genesis? -#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)] -#[serde(bound = "C::Address: serde::Serialize + serde::de::DeserializeOwned")] -pub struct SequencerConfig { - /// The rollup address of the sequencer. - pub seq_rollup_address: C::Address, - /// The Data Availability (DA) address of the sequencer. - pub seq_da_address: Da::Address, - /// Coins that will be slashed if the sequencer is malicious. - /// - /// The coins will be transferred from - /// [`SequencerConfig::seq_rollup_address`] to this module's address - /// ([`sov_modules_api::ModuleInfo::address`]) and locked away until the sequencer - /// decides to exit (unregister). - /// - /// Only sequencers that are [`SequencerRegistry::is_sender_allowed`] list are - /// allowed to exit. - pub coins_to_lock: sov_bank::Coins, - /// Determines whether this sequencer is *regular* or *preferred*. - /// - /// Batches from the preferred sequencer are always processed first in - /// block, which means the preferred sequencer can guarantee soft - /// confirmation time for transactions. - pub is_preferred_sequencer: bool, -} - -impl SequencerRegistry { - pub(crate) fn init_module( - &self, - config: &::Config, - working_set: &mut WorkingSet, - ) -> Result<()> { - self.coins_to_lock.set(&config.coins_to_lock, working_set); - self.register_sequencer( - &config.seq_da_address, - &config.seq_rollup_address, - working_set, - )?; - if config.is_preferred_sequencer { - self.preferred_sequencer - .set(&config.seq_da_address, working_set); - } - - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use std::str::FromStr; - - use sov_bank::Coins; - use sov_mock_da::{MockAddress, MockDaSpec}; - use sov_modules_api::default_context::DefaultContext; - use sov_modules_api::{AddressBech32, Spec}; - - use crate::SequencerConfig; - - #[test] - fn test_config_serialization() { - let seq_rollup_address: ::Address = AddressBech32::from_str( - "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94", - ) - .unwrap() - .into(); - - let token_address: ::Address = AddressBech32::from_str( - "sov1zsnx7n2wjvtkr0ttscfgt06pjca3v2e6stxeu49qwynavmk7a8xqlxkkjp", - ) - .unwrap() - .into(); - - let coins = Coins:: { - amount: 50, - token_address, - }; - - let seq_da_addreess = MockAddress::from_str( - "0000000000000000000000000000000000000000000000000000000000000000", - ) - .unwrap(); - - let config = SequencerConfig:: { - seq_rollup_address, - seq_da_address: seq_da_addreess, - coins_to_lock: coins, - is_preferred_sequencer: true, - }; - - let data = r#" - { - "seq_rollup_address":"sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94", - "seq_da_address":"0000000000000000000000000000000000000000000000000000000000000000", - "coins_to_lock":{ - "amount":50, - "token_address":"sov1zsnx7n2wjvtkr0ttscfgt06pjca3v2e6stxeu49qwynavmk7a8xqlxkkjp" - }, - "is_preferred_sequencer":true - }"#; - - let parsed_config: SequencerConfig = - serde_json::from_str(data).unwrap(); - assert_eq!(config, parsed_config) - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/src/hooks.rs b/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/src/hooks.rs deleted file mode 100644 index 9f60ad715..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/src/hooks.rs +++ /dev/null @@ -1,35 +0,0 @@ -use sov_modules_api::hooks::ApplyBlobHooks; -use sov_modules_api::{BlobReaderTrait, Context, WorkingSet}; -#[cfg(all(target_os = "zkvm", feature = "bench"))] -use sov_zk_cycle_macros::cycle_tracker; -#[cfg(all(target_os = "zkvm", feature = "bench"))] -use sov_zk_cycle_utils::print_cycle_count; - -use crate::{SequencerOutcome, SequencerRegistry}; - -impl ApplyBlobHooks - for SequencerRegistry -{ - type Context = C; - type BlobResult = SequencerOutcome; - - #[cfg_attr(all(target_os = "zkvm", feature = "bench"), cycle_tracker)] - fn begin_blob_hook( - &self, - blob: &mut Da::BlobTransaction, - working_set: &mut WorkingSet, - ) -> anyhow::Result<()> { - #[cfg(all(target_os = "zkvm", feature = "bench"))] - print_cycle_count(); - if !self.is_sender_allowed(&blob.sender(), working_set) { - anyhow::bail!("sender {} is not allowed to submit blobs", blob.sender()); - } - #[cfg(all(target_os = "zkvm", feature = "bench"))] - print_cycle_count(); - Ok(()) - } - - fn end_blob_hook(&self, _working_set: &mut WorkingSet) -> anyhow::Result<()> { - Ok(()) - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/src/lib.rs b/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/src/lib.rs deleted file mode 100644 index 1bcfdb458..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/src/lib.rs +++ /dev/null @@ -1,161 +0,0 @@ -//! The `sov-sequencer-registry` module is responsible for sequencer -//! registration, slashing, and rewards. At the moment, only a centralized -//! sequencer is supported. The sequencer's address and bond are registered -//! during the rollup deployment. -//! -//! The module implements the [`sov_modules_api::hooks::ApplyBlobHooks`] trait. - -#![deny(missing_docs)] -mod call; -mod genesis; -mod hooks; -#[cfg(feature = "native")] -mod query; -pub use call::*; -pub use genesis::*; -#[cfg(feature = "native")] -pub use query::*; -use sov_modules_api::prelude::*; -use sov_modules_api::{CallResponse, Error, ModuleInfo, StateMap, StateValue, WorkingSet}; -use sov_state::codec::BcsCodec; - -/// The `sov-sequencer-registry` module `struct`. -#[cfg_attr(feature = "native", derive(sov_modules_api::ModuleCallJsonSchema))] -#[derive(Clone, ModuleInfo)] -pub struct SequencerRegistry { - /// The address of the `sov_sequencer_registry` module. - /// Note: this is address is generated by the module framework and the - /// corresponding private key is unknown. - #[address] - pub(crate) address: C::Address, - - /// Reference to the Bank module. - #[module] - pub(crate) bank: sov_bank::Bank, - - /// Only batches from sequencers from this list are going to be processed. - #[state] - pub(crate) allowed_sequencers: StateMap, - - /// Optional preferred sequencer. - /// If set, batches from this sequencer will be processed first in block, - /// So this sequencer can guarantee soft confirmation time for transactions - #[state] - pub(crate) preferred_sequencer: StateValue, - - /// Coin's that will be slashed if the sequencer is malicious. - /// The coins will be transferred from - /// [`SequencerConfig::seq_rollup_address`] to - /// [`SequencerRegistry::address`] and locked forever, until sequencer - /// decides to exit (unregister). - /// - /// Only sequencers in the [`SequencerRegistry::allowed_sequencers`] list are - /// allowed to exit. - #[state] - pub(crate) coins_to_lock: StateValue>, -} - -/// Result of applying a blob, from sequencer's point of view. -pub enum SequencerOutcome { - /// The blob was applied successfully and the operation is concluded. - Completed, - /// The blob was *not* applied successfully. The sequencer has been slashed - /// as a result of the invalid blob. - Slashed { - /// The address of the sequencer that was slashed. - sequencer: Da::Address, - }, -} - -impl sov_modules_api::Module - for SequencerRegistry -{ - type Context = C; - - type Config = SequencerConfig; - - type CallMessage = CallMessage; - - type Event = (); - - fn genesis(&self, config: &Self::Config, working_set: &mut WorkingSet) -> Result<(), Error> { - Ok(self.init_module(config, working_set)?) - } - - fn call( - &mut self, - message: Self::CallMessage, - context: &Self::Context, - working_set: &mut WorkingSet, - ) -> Result { - Ok(match message { - CallMessage::Register { da_address } => { - let da_address = Da::Address::try_from(&da_address)?; - self.register(&da_address, context, working_set)? - } - CallMessage::Exit { da_address } => { - let da_address = Da::Address::try_from(&da_address)?; - self.exit(&da_address, context, working_set)? - } - }) - } -} - -impl SequencerRegistry { - /// Returns the configured amount of [`Coins`](sov_bank::Coins) to lock. - pub fn get_coins_to_lock(&self, working_set: &mut WorkingSet) -> Option> { - self.coins_to_lock.get(working_set) - } - - pub(crate) fn register_sequencer( - &self, - da_address: &Da::Address, - rollup_address: &C::Address, - working_set: &mut WorkingSet, - ) -> anyhow::Result<()> { - if self - .allowed_sequencers - .get(da_address, working_set) - .is_some() - { - anyhow::bail!("sequencer {} already registered", rollup_address) - } - let locker = &self.address; - let coins = self.coins_to_lock.get_or_err(working_set)?; - self.bank - .transfer_from(rollup_address, locker, coins, working_set)?; - - self.allowed_sequencers - .set(da_address, rollup_address, working_set); - - Ok(()) - } - - /// Returns the preferred sequencer, or [`None`] it wasn't set. - /// - /// Read about [`SequencerConfig::is_preferred_sequencer`] to learn about - /// preferred sequencers. - pub fn get_preferred_sequencer(&self, working_set: &mut WorkingSet) -> Option { - self.preferred_sequencer.get(working_set) - } - - /// Returns the rollup address of the preferred sequencer, or [`None`] it wasn't set. - /// - /// Read about [`SequencerConfig::is_preferred_sequencer`] to learn about - /// preferred sequencers. - pub fn get_preferred_sequencer_rollup_address( - &self, - working_set: &mut WorkingSet, - ) -> Option { - self.preferred_sequencer.get(working_set).map(|da_addr| { - self.allowed_sequencers - .get(&da_addr, working_set) - .expect("Preferred Sequencer must have known address on rollup") - }) - } - - /// Checks whether `sender` is a registered sequencer. - pub fn is_sender_allowed(&self, sender: &Da::Address, working_set: &mut WorkingSet) -> bool { - self.allowed_sequencers.get(sender, working_set).is_some() - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/src/query.rs b/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/src/query.rs deleted file mode 100644 index a7c3ab2f2..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/src/query.rs +++ /dev/null @@ -1,34 +0,0 @@ -//! Defines rpc queries exposed by the sequencer registry module, along with the relevant types -use jsonrpsee::core::RpcResult; -use sov_modules_api::macros::rpc_gen; -use sov_modules_api::{Context, StateMapAccessor, WorkingSet}; - -use crate::SequencerRegistry; - -/// The response type to the `getSequencerDddress` RPC method. -#[cfg_attr( - feature = "native", - derive(serde::Deserialize, serde::Serialize, Clone) -)] -#[derive(Debug, Eq, PartialEq)] -pub struct SequencerAddressResponse { - /// The rollup address of the requested sequencer. - pub address: Option, -} - -#[rpc_gen(client, server, namespace = "sequencer")] -impl SequencerRegistry { - /// Returns the rollup address of the sequencer with the given DA address. - /// - /// The response only contains data if the sequencer is registered. - #[rpc_method(name = "getSequencerAddress")] - pub fn sequencer_address( - &self, - da_address: Da::Address, - working_set: &mut WorkingSet, - ) -> RpcResult> { - Ok(SequencerAddressResponse { - address: self.allowed_sequencers.get(&da_address, working_set), - }) - } -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/tests/helpers/mod.rs b/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/tests/helpers/mod.rs deleted file mode 100644 index 7e4efbb82..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/tests/helpers/mod.rs +++ /dev/null @@ -1,129 +0,0 @@ -use jsonrpsee::core::RpcResult; -use sov_mock_da::{MockAddress, MockDaSpec}; -use sov_modules_api::default_context::DefaultContext; -use sov_modules_api::digest::Digest; -use sov_modules_api::{Address, Module, Spec, WorkingSet}; -use sov_sequencer_registry::{SequencerConfig, SequencerRegistry}; - -pub type C = DefaultContext; -pub type Da = MockDaSpec; - -pub const GENESIS_SEQUENCER_KEY: &str = "sequencer_1"; -pub const GENESIS_SEQUENCER_DA_ADDRESS: [u8; 32] = [1; 32]; -pub const ANOTHER_SEQUENCER_KEY: &str = "sequencer_2"; -#[allow(dead_code)] -pub const ANOTHER_SEQUENCER_DA_ADDRESS: [u8; 32] = [2; 32]; -pub const UNKNOWN_SEQUENCER_KEY: &str = "sequencer_3"; -#[allow(dead_code)] -pub const REWARD_SEQUENCER_KEY: &str = "sequencer_4"; -#[allow(dead_code)] -pub const UNKNOWN_SEQUENCER_DA_ADDRESS: [u8; 32] = [3; 32]; -pub const LOW_FUND_KEY: &str = "zero_funds"; -pub const INITIAL_BALANCE: u64 = 210; -pub const LOCKED_AMOUNT: u64 = 200; - -pub struct TestSequencer { - pub bank: sov_bank::Bank, - pub bank_config: sov_bank::BankConfig, - - pub registry: SequencerRegistry, - pub sequencer_config: SequencerConfig, -} - -impl TestSequencer { - pub fn genesis(&mut self, working_set: &mut WorkingSet) { - self.bank.genesis(&self.bank_config, working_set).unwrap(); - - self.registry - .genesis(&self.sequencer_config, working_set) - .unwrap(); - } - - #[allow(dead_code)] - pub fn query_balance_via_bank( - &mut self, - working_set: &mut WorkingSet, - ) -> RpcResult { - self.bank.balance_of( - self.sequencer_config.seq_rollup_address, - self.sequencer_config.coins_to_lock.token_address, - working_set, - ) - } - - #[allow(dead_code)] - pub fn query_balance( - &mut self, - user_address: ::Address, - working_set: &mut WorkingSet, - ) -> RpcResult { - self.bank.balance_of( - user_address, - self.sequencer_config.coins_to_lock.token_address, - working_set, - ) - } -} - -pub fn create_bank_config() -> (sov_bank::BankConfig, ::Address) { - let seq_address = generate_address(GENESIS_SEQUENCER_KEY); - - let token_config = sov_bank::TokenConfig { - token_name: "InitialToken".to_owned(), - address_and_balances: vec![ - (seq_address, INITIAL_BALANCE), - (generate_address(ANOTHER_SEQUENCER_KEY), INITIAL_BALANCE), - (generate_address(UNKNOWN_SEQUENCER_KEY), INITIAL_BALANCE), - (generate_address(LOW_FUND_KEY), 3), - ], - authorized_minters: vec![], - salt: 8, - }; - - ( - sov_bank::BankConfig { - tokens: vec![token_config], - }, - seq_address, - ) -} - -pub fn create_sequencer_config( - seq_rollup_address: ::Address, - token_address: ::Address, -) -> SequencerConfig { - SequencerConfig { - seq_rollup_address, - seq_da_address: MockAddress::from(GENESIS_SEQUENCER_DA_ADDRESS), - coins_to_lock: sov_bank::Coins { - amount: LOCKED_AMOUNT, - token_address, - }, - is_preferred_sequencer: false, - } -} - -pub fn create_test_sequencer() -> TestSequencer { - let bank = sov_bank::Bank::::default(); - let (bank_config, seq_rollup_address) = create_bank_config(); - - let token_address = sov_bank::get_genesis_token_address::( - &bank_config.tokens[0].token_name, - bank_config.tokens[0].salt, - ); - - let registry = SequencerRegistry::::default(); - let sequencer_config = create_sequencer_config(seq_rollup_address, token_address); - - TestSequencer { - bank, - bank_config, - registry, - sequencer_config, - } -} - -pub fn generate_address(key: &str) -> ::Address { - let hash: [u8; 32] = ::Hasher::digest(key.as_bytes()).into(); - Address::from(hash) -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/tests/hooks_test.rs b/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/tests/hooks_test.rs deleted file mode 100644 index f53b19eef..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/tests/hooks_test.rs +++ /dev/null @@ -1,138 +0,0 @@ -use helpers::*; -use sov_mock_da::{MockAddress, MockBlob}; -use sov_modules_api::hooks::ApplyBlobHooks; -use sov_modules_api::WorkingSet; -use sov_prover_storage_manager::new_orphan_storage; -use sov_sequencer_registry::SequencerRegistry; - -mod helpers; - -#[test] -fn begin_blob_hook_known_sequencer() { - let mut test_sequencer = create_test_sequencer(); - let tmpdir = tempfile::tempdir().unwrap(); - let working_set = &mut WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - test_sequencer.genesis(working_set); - - let balance_after_genesis = { - let resp = test_sequencer.query_balance_via_bank(working_set).unwrap(); - resp.amount.unwrap() - }; - assert_eq!(INITIAL_BALANCE - LOCKED_AMOUNT, balance_after_genesis); - - let genesis_sequencer_da_address = MockAddress::from(GENESIS_SEQUENCER_DA_ADDRESS); - - let mut test_blob = MockBlob::new(Vec::new(), genesis_sequencer_da_address, [0_u8; 32]); - - test_sequencer - .registry - .begin_blob_hook(&mut test_blob, working_set) - .unwrap(); - - let resp = test_sequencer.query_balance_via_bank(working_set).unwrap(); - assert_eq!(balance_after_genesis, resp.amount.unwrap()); - let resp = test_sequencer - .registry - .sequencer_address(genesis_sequencer_da_address, working_set) - .unwrap(); - assert!(resp.address.is_some()); -} - -#[test] -fn begin_blob_hook_unknown_sequencer() { - let mut test_sequencer = create_test_sequencer(); - let tmpdir = tempfile::tempdir().unwrap(); - let working_set = &mut WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - test_sequencer.genesis(working_set); - - let mut test_blob = MockBlob::new( - Vec::new(), - MockAddress::from(UNKNOWN_SEQUENCER_DA_ADDRESS), - [0_u8; 32], - ); - - let result = test_sequencer - .registry - .begin_blob_hook(&mut test_blob, working_set); - assert!(result.is_err()); - let expected_message = format!( - "sender {} is not allowed to submit blobs", - MockAddress::from(UNKNOWN_SEQUENCER_DA_ADDRESS) - ); - let actual_message = result.err().unwrap().to_string(); - assert_eq!(expected_message, actual_message); -} - -#[test] -fn end_blob_hook_success() { - let mut test_sequencer = create_test_sequencer(); - let tmpdir = tempfile::tempdir().unwrap(); - let working_set = &mut WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - test_sequencer.genesis(working_set); - let balance_after_genesis = { - let resp = test_sequencer.query_balance_via_bank(working_set).unwrap(); - resp.amount.unwrap() - }; - assert_eq!(INITIAL_BALANCE - LOCKED_AMOUNT, balance_after_genesis); - - let genesis_sequencer_da_address = MockAddress::from(GENESIS_SEQUENCER_DA_ADDRESS); - - let mut test_blob = MockBlob::new(Vec::new(), genesis_sequencer_da_address, [0_u8; 32]); - - test_sequencer - .registry - .begin_blob_hook(&mut test_blob, working_set) - .unwrap(); - - as ApplyBlobHooks>::end_blob_hook( - &test_sequencer.registry, - working_set, - ) - .unwrap(); - let resp = test_sequencer.query_balance_via_bank(working_set).unwrap(); - assert_eq!(balance_after_genesis, resp.amount.unwrap()); - let resp = test_sequencer - .registry - .sequencer_address(genesis_sequencer_da_address, working_set) - .unwrap(); - assert!(resp.address.is_some()); -} - -#[test] -fn end_blob_hook_slash_unknown_sequencer() { - let mut test_sequencer = create_test_sequencer(); - let tmpdir = tempfile::tempdir().unwrap(); - let working_set = &mut WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - test_sequencer.genesis(working_set); - - let mut test_blob = MockBlob::new( - Vec::new(), - MockAddress::from(GENESIS_SEQUENCER_DA_ADDRESS), - [0_u8; 32], - ); - - let sequencer_address = MockAddress::from(UNKNOWN_SEQUENCER_DA_ADDRESS); - - test_sequencer - .registry - .begin_blob_hook(&mut test_blob, working_set) - .unwrap(); - - let resp = test_sequencer - .registry - .sequencer_address(sequencer_address, working_set) - .unwrap(); - assert!(resp.address.is_none()); - - as ApplyBlobHooks>::end_blob_hook( - &test_sequencer.registry, - working_set, - ) - .unwrap(); - - let resp = test_sequencer - .registry - .sequencer_address(sequencer_address, working_set) - .unwrap(); - assert!(resp.address.is_none()); -} diff --git a/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/tests/sequencer_registry_test.rs b/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/tests/sequencer_registry_test.rs deleted file mode 100644 index 7d12ffbaf..000000000 --- a/crates/sovereign-sdk/module-system/module-implementations/sov-sequencer-registry/tests/sequencer_registry_test.rs +++ /dev/null @@ -1,281 +0,0 @@ -use helpers::*; -use sov_mock_da::MockAddress; -use sov_modules_api::{Context, Error, Module, ModuleInfo, SpecId, WorkingSet}; -use sov_prover_storage_manager::new_orphan_storage; -use sov_sequencer_registry::{CallMessage, SequencerRegistry}; - -mod helpers; - -// Happy path for registration and exit -// This test checks: -// - genesis sequencer is present after genesis -// - registration works, and funds are deducted -// - exit works and funds are returned -#[test] -fn test_registration_lifecycle() { - let mut test_sequencer = create_test_sequencer(); - let tmpdir = tempfile::tempdir().unwrap(); - let working_set = &mut WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - test_sequencer.genesis(working_set); - - // Check genesis - { - let sequencer_address = generate_address(GENESIS_SEQUENCER_KEY); - let registry_response = test_sequencer - .registry - .sequencer_address(MockAddress::from(GENESIS_SEQUENCER_DA_ADDRESS), working_set) - .unwrap(); - assert_eq!(Some(sequencer_address), registry_response.address); - } - - // Check normal lifecycle - - let da_address = MockAddress::from(ANOTHER_SEQUENCER_DA_ADDRESS); - - let sequencer_address = generate_address(ANOTHER_SEQUENCER_KEY); - let reward_address = generate_address(REWARD_SEQUENCER_KEY); - let sender_context = C::new(sequencer_address, reward_address, 1, SpecId::Genesis, 0); - - let balance_before = test_sequencer - .query_balance(sequencer_address, working_set) - .unwrap() - .amount - .unwrap(); - - let registry_response_before = test_sequencer - .registry - .sequencer_address(da_address, working_set) - .unwrap(); - assert!(registry_response_before.address.is_none()); - - let register_message = CallMessage::Register { - da_address: da_address.as_ref().to_vec(), - }; - test_sequencer - .registry - .call(register_message, &sender_context, working_set) - .expect("Sequencer registration has failed"); - - let balance_after_registration = test_sequencer - .query_balance(sequencer_address, working_set) - .unwrap() - .amount - .unwrap(); - assert_eq!(balance_before - LOCKED_AMOUNT, balance_after_registration); - - let registry_response_after_registration = test_sequencer - .registry - .sequencer_address(da_address, working_set) - .unwrap(); - assert_eq!( - Some(sequencer_address), - registry_response_after_registration.address - ); - - let exit_message = CallMessage::Exit { - da_address: da_address.as_ref().to_vec(), - }; - test_sequencer - .registry - .call(exit_message, &sender_context, working_set) - .expect("Sequencer exit has failed"); - - let balance_after_exit = test_sequencer - .query_balance(sequencer_address, working_set) - .unwrap() - .amount - .unwrap(); - assert_eq!(balance_before, balance_after_exit); - - let registry_response_after_exit = test_sequencer - .registry - .sequencer_address(da_address, working_set) - .unwrap(); - assert!(registry_response_after_exit.address.is_none()); -} - -#[test] -fn test_registration_not_enough_funds() { - let mut test_sequencer = create_test_sequencer(); - let tmpdir = tempfile::tempdir().unwrap(); - let working_set = &mut WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - test_sequencer.genesis(working_set); - - let da_address = MockAddress::from(ANOTHER_SEQUENCER_DA_ADDRESS); - - let sequencer_address = generate_address(LOW_FUND_KEY); - let reward_address = generate_address(REWARD_SEQUENCER_KEY); - let sender_context = C::new(sequencer_address, reward_address, 1, SpecId::Genesis, 0); - - let register_message = CallMessage::Register { - da_address: da_address.as_ref().to_vec(), - }; - let response = test_sequencer - .registry - .call(register_message, &sender_context, working_set); - - assert!( - response.is_err(), - "insufficient funds registration should fail" - ); - let Error::ModuleError(err) = response.err().unwrap(); - let mut chain = err.chain(); - let message_1 = chain.next().unwrap().to_string(); - let message_2 = chain.next().unwrap().to_string(); - let message_3 = chain.next().unwrap().to_string(); - assert!(chain.next().is_none()); - - assert_eq!( - format!( - "Failed transfer from={} to={} of coins(token_address={} amount={})", - sequencer_address, - test_sequencer.registry.address(), - test_sequencer.sequencer_config.coins_to_lock.token_address, - LOCKED_AMOUNT, - ), - message_1 - ); - assert_eq!( - format!( - "Incorrect balance on={} for token=InitialToken", - sequencer_address - ), - message_2, - ); - assert_eq!( - format!("Insufficient funds for {}", sequencer_address), - message_3, - ); -} - -#[test] -fn test_registration_second_time() { - let mut test_sequencer = create_test_sequencer(); - let tmpdir = tempfile::tempdir().unwrap(); - let working_set = &mut WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - test_sequencer.genesis(working_set); - - let da_address = MockAddress::from(GENESIS_SEQUENCER_DA_ADDRESS); - - let sequencer_address = generate_address(GENESIS_SEQUENCER_KEY); - let reward_address = generate_address(REWARD_SEQUENCER_KEY); - let sender_context = C::new(sequencer_address, reward_address, 1, SpecId::Genesis, 0); - - let register_message = CallMessage::Register { - da_address: da_address.as_ref().to_vec(), - }; - let response = test_sequencer - .registry - .call(register_message, &sender_context, working_set); - - assert!(response.is_err(), "duplicate registration should fail"); - let expected_error_message = format!("sequencer {} already registered", sequencer_address); - let actual_error_message = response.err().unwrap().to_string(); - - assert_eq!(expected_error_message, actual_error_message); -} - -#[test] -fn test_exit_different_sender() { - let mut test_sequencer = create_test_sequencer(); - let tmpdir = tempfile::tempdir().unwrap(); - let working_set = &mut WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - test_sequencer.genesis(working_set); - - let sequencer_address = generate_address(ANOTHER_SEQUENCER_KEY); - let reward_address = generate_address(REWARD_SEQUENCER_KEY); - let sender_context = C::new(sequencer_address, reward_address, 1, SpecId::Genesis, 0); - let attacker_address = generate_address("some_random_key"); - let attacker_context = C::new(attacker_address, reward_address, 1, SpecId::Genesis, 0); - - let register_message = CallMessage::Register { - da_address: ANOTHER_SEQUENCER_DA_ADDRESS.to_vec(), - }; - test_sequencer - .registry - .call(register_message, &sender_context, working_set) - .expect("Sequencer registration has failed"); - - let exit_message = CallMessage::Exit { - da_address: ANOTHER_SEQUENCER_DA_ADDRESS.to_vec(), - }; - let response = test_sequencer - .registry - .call(exit_message, &attacker_context, working_set); - - assert!( - response.is_err(), - "exit by non authorized sender should fail" - ); - let actual_error_message = response.err().unwrap().to_string(); - - assert_eq!("Unauthorized exit attempt", actual_error_message); -} - -#[test] -fn test_allow_exit_last_sequencer() { - let mut test_sequencer = create_test_sequencer(); - let tmpdir = tempfile::tempdir().unwrap(); - let working_set = &mut WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - test_sequencer.genesis(working_set); - - let sequencer_address = generate_address(GENESIS_SEQUENCER_KEY); - let rewards_address = generate_address(REWARD_SEQUENCER_KEY); - let sender_context = C::new(sequencer_address, rewards_address, 1, SpecId::Genesis, 0); - let exit_message = CallMessage::Exit { - da_address: GENESIS_SEQUENCER_DA_ADDRESS.to_vec(), - }; - test_sequencer - .registry - .call(exit_message, &sender_context, working_set) - .expect("Last sequencer exit has failed"); -} - -#[test] -fn test_preferred_sequencer_returned_and_removed() { - let bank = sov_bank::Bank::::default(); - let (bank_config, seq_rollup_address) = create_bank_config(); - - let token_address = sov_bank::get_genesis_token_address::( - &bank_config.tokens[0].token_name, - bank_config.tokens[0].salt, - ); - - let registry = SequencerRegistry::::default(); - let mut sequencer_config = create_sequencer_config(seq_rollup_address, token_address); - - sequencer_config.is_preferred_sequencer = true; - - let mut test_sequencer = TestSequencer { - bank, - bank_config, - registry, - sequencer_config, - }; - - let tmpdir = tempfile::tempdir().unwrap(); - let working_set = &mut WorkingSet::new(new_orphan_storage(tmpdir.path()).unwrap()); - test_sequencer.genesis(working_set); - - assert_eq!( - Some(test_sequencer.sequencer_config.seq_da_address), - test_sequencer.registry.get_preferred_sequencer(working_set) - ); - - let sequencer_address = generate_address(GENESIS_SEQUENCER_KEY); - let reward_address = generate_address(REWARD_SEQUENCER_KEY); - let sender_context = C::new(sequencer_address, reward_address, 1, SpecId::Genesis, 0); - let exit_message = CallMessage::Exit { - da_address: GENESIS_SEQUENCER_DA_ADDRESS.to_vec(), - }; - test_sequencer - .registry - .call(exit_message, &sender_context, working_set) - .expect("Last sequencer exit has failed"); - - // Preferred sequencer exited, so result is none - assert!(test_sequencer - .registry - .get_preferred_sequencer(working_set) - .is_none()); -} diff --git a/crates/sovereign-sdk/module-system/module-schemas/Cargo.toml b/crates/sovereign-sdk/module-system/module-schemas/Cargo.toml deleted file mode 100644 index 7e206948b..000000000 --- a/crates/sovereign-sdk/module-system/module-schemas/Cargo.toml +++ /dev/null @@ -1,35 +0,0 @@ -[package] -name = "sov-module-schemas" -description = "A dummy crate that stores as files the JSON Schemas for all Sovereign modules" -authors = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -repository = { workspace = true } - -version = { workspace = true } -readme = "README.md" -resolver = "2" -publish = false - -[build-dependencies] -sov-modules-api = { path = "../sov-modules-api" } -sov-mock-da = { path = "../../adapters/mock-da", features = ["native"] } -sov-mock-zkvm = { path = "../../adapters/mock-zkvm" } - -# Modules -sov-accounts = { path = "../module-implementations/sov-accounts", features = [ - "native", -] } -sov-bank = { path = "../module-implementations/sov-bank", features = [ - "native", -] } -sov-prover-incentives = { path = "../module-implementations/sov-prover-incentives", features = [ - "native", -] } -sov-sequencer-registry = { path = "../module-implementations/sov-sequencer-registry", features = [ - "native", -] } -sov-value-setter = { path = "../module-implementations/examples/sov-value-setter", features = [ - "native", -] } diff --git a/crates/sovereign-sdk/module-system/module-schemas/README.md b/crates/sovereign-sdk/module-system/module-schemas/README.md deleted file mode 100644 index 2781bfc5a..000000000 --- a/crates/sovereign-sdk/module-system/module-schemas/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# `sov-module-schemas` - -This crate is not intended to be used directly, but serves as generated documentation in the form of JSON Schemas for modules built-in into the SDK. The schemas are tracked by `git` to make them linkable and searchable on GitHub. diff --git a/crates/sovereign-sdk/module-system/module-schemas/build.rs b/crates/sovereign-sdk/module-system/module-schemas/build.rs deleted file mode 100644 index 6263ac243..000000000 --- a/crates/sovereign-sdk/module-system/module-schemas/build.rs +++ /dev/null @@ -1,28 +0,0 @@ -use std::fs::File; -use std::io::{self, Write}; - -use sov_mock_da::verifier::MockDaSpec; -use sov_mock_da::MockValidityCond; -use sov_mock_zkvm::MockZkvm; -use sov_modules_api::default_context::DefaultContext as C; -use sov_modules_api::ModuleCallJsonSchema; - -fn main() -> io::Result<()> { - store_json_schema::>("sov-bank.json")?; - store_json_schema::>("sov-accounts.json")?; - store_json_schema::>("sov-value-setter.json")?; - store_json_schema::>>( - "sov-prover-incentives.json", - )?; - store_json_schema::>( - "sov-sequencer-registry.json", - )?; - Ok(()) -} - -fn store_json_schema(filename: &str) -> io::Result<()> { - let mut file = File::create(format!("schemas/{}", filename))?; - file.write_all(M::json_schema().as_bytes())?; - file.write_all(b"\n")?; - Ok(()) -} diff --git a/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-accounts.json b/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-accounts.json deleted file mode 100644 index 49a8df219..000000000 --- a/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-accounts.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Null", - "type": "null" -} diff --git a/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-bank.json b/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-bank.json deleted file mode 100644 index 31565bf22..000000000 --- a/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-bank.json +++ /dev/null @@ -1,227 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "CallMessage", - "description": "This enumeration represents the available call messages for interacting with the sov-bank module.", - "oneOf": [ - { - "description": "Creates a new token with the specified name and initial balance.", - "type": "object", - "required": [ - "CreateToken" - ], - "properties": { - "CreateToken": { - "type": "object", - "required": [ - "authorized_minters", - "initial_balance", - "minter_address", - "salt", - "token_name" - ], - "properties": { - "authorized_minters": { - "description": "Authorized minter list.", - "type": "array", - "items": { - "$ref": "#/definitions/Address" - } - }, - "initial_balance": { - "description": "The initial balance of the new token.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "minter_address": { - "description": "The address of the account that the new tokens are minted to.", - "allOf": [ - { - "$ref": "#/definitions/Address" - } - ] - }, - "salt": { - "description": "Random value use to create a unique token address.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "token_name": { - "description": "The name of the new token.", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Transfers a specified amount of tokens to the specified address.", - "type": "object", - "required": [ - "Transfer" - ], - "properties": { - "Transfer": { - "type": "object", - "required": [ - "coins", - "to" - ], - "properties": { - "coins": { - "description": "The amount of tokens to transfer.", - "allOf": [ - { - "$ref": "#/definitions/Coins" - } - ] - }, - "to": { - "description": "The address to which the tokens will be transferred.", - "allOf": [ - { - "$ref": "#/definitions/Address" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Burns a specified amount of tokens.", - "type": "object", - "required": [ - "Burn" - ], - "properties": { - "Burn": { - "type": "object", - "required": [ - "coins" - ], - "properties": { - "coins": { - "description": "The amount of tokens to burn.", - "allOf": [ - { - "$ref": "#/definitions/Coins" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Mints a specified amount of tokens.", - "type": "object", - "required": [ - "Mint" - ], - "properties": { - "Mint": { - "type": "object", - "required": [ - "coins", - "minter_address" - ], - "properties": { - "coins": { - "description": "The amount of tokens to mint.", - "allOf": [ - { - "$ref": "#/definitions/Coins" - } - ] - }, - "minter_address": { - "description": "Address to mint tokens to", - "allOf": [ - { - "$ref": "#/definitions/Address" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Freezes a token so that the supply is frozen", - "type": "object", - "required": [ - "Freeze" - ], - "properties": { - "Freeze": { - "type": "object", - "required": [ - "token_address" - ], - "properties": { - "token_address": { - "description": "Address of the token to be frozen", - "allOf": [ - { - "$ref": "#/definitions/Address" - } - ] - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Address": { - "description": "Module address representation", - "type": "object", - "required": [ - "addr" - ], - "properties": { - "addr": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32 - } - } - }, - "Coins": { - "description": "Structure that stores information specifying a given `amount` (type [`Amount`]) of coins stored at a `token_address` (type [`sov_modules_api::Spec::Address`]).", - "type": "object", - "required": [ - "amount", - "token_address" - ], - "properties": { - "amount": { - "description": "An `amount` of coins stored.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "token_address": { - "description": "The address where the tokens are stored.", - "allOf": [ - { - "$ref": "#/definitions/Address" - } - ] - } - } - } - } -} diff --git a/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-election.json b/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-election.json deleted file mode 100644 index 43f7076dc..000000000 --- a/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-election.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "CallMessage", - "description": "Call actions supported byte the module.", - "oneOf": [ - { - "type": "string", - "enum": [ - "ClearElection", - "FreezeElection" - ] - }, - { - "type": "object", - "required": [ - "SetCandidates" - ], - "properties": { - "SetCandidates": { - "type": "object", - "required": [ - "names" - ], - "properties": { - "names": { - "type": "array", - "items": { - "type": "string" - } - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "AddVoter" - ], - "properties": { - "AddVoter": { - "$ref": "#/definitions/Address" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "Vote" - ], - "properties": { - "Vote": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Address": { - "type": "object", - "required": [ - "addr" - ], - "properties": { - "addr": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32 - } - } - } - } -} diff --git a/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-evm-experimental.json b/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-evm-experimental.json deleted file mode 100644 index bc96b5b23..000000000 --- a/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-evm-experimental.json +++ /dev/null @@ -1,193 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "CallMessage", - "type": "object", - "required": [ - "tx" - ], - "properties": { - "tx": { - "$ref": "#/definitions/EvmTransaction" - } - }, - "definitions": { - "AccessListItem": { - "type": "object", - "required": [ - "address", - "storage_keys" - ], - "properties": { - "address": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 20, - "minItems": 20 - }, - "storage_keys": { - "type": "array", - "items": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32 - } - } - } - }, - "EvmTransaction": { - "type": "object", - "required": [ - "access_lists", - "chain_id", - "data", - "gas_limit", - "gas_price", - "hash", - "max_fee_per_gas", - "max_priority_fee_per_gas", - "nonce", - "odd_y_parity", - "r", - "s", - "sender", - "value" - ], - "properties": { - "access_lists": { - "type": "array", - "items": { - "$ref": "#/definitions/AccessListItem" - } - }, - "chain_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "data": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - }, - "gas_limit": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "gas_price": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32 - }, - "hash": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32 - }, - "max_fee_per_gas": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32 - }, - "max_priority_fee_per_gas": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32 - }, - "nonce": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "odd_y_parity": { - "type": "boolean" - }, - "r": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32 - }, - "s": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32 - }, - "sender": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 20, - "minItems": 20 - }, - "to": { - "type": [ - "array", - "null" - ], - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 20, - "minItems": 20 - }, - "value": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "maxItems": 32, - "minItems": 32 - } - } - } - } -} \ No newline at end of file diff --git a/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-evm.json b/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-evm.json deleted file mode 100644 index 88f25a0f8..000000000 --- a/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-evm.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "CallMessage", - "type": "object", - "required": [ - "tx" - ], - "properties": { - "tx": { - "$ref": "#/definitions/RlpEvmTransaction" - } - }, - "definitions": { - "RlpEvmTransaction": { - "description": "Rlp encoded evm transaction.", - "type": "object", - "required": [ - "rlp" - ], - "properties": { - "rlp": { - "description": "Rlp data.", - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - } - } - } - } -} diff --git a/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-prover-incentives.json b/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-prover-incentives.json deleted file mode 100644 index 38d6e504a..000000000 --- a/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-prover-incentives.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "CallMessage", - "description": "This enumeration represents the available call messages for interacting with the `ExampleModule` module.", - "oneOf": [ - { - "description": "Bonds the prover with provided bond.", - "type": "object", - "required": [ - "BondProver" - ], - "properties": { - "BondProver": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "Unbonds the prover.", - "type": "string", - "enum": [ - "UnbondProver" - ] - }, - { - "description": "Verifies the provided proof (of format `Vec`)", - "type": "object", - "required": [ - "VerifyProof" - ], - "properties": { - "VerifyProof": { - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - } - }, - "additionalProperties": false - } - ] -} diff --git a/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-sequencer-registry.json b/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-sequencer-registry.json deleted file mode 100644 index b03dbe5ec..000000000 --- a/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-sequencer-registry.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "CallMessage", - "description": "This enumeration represents the available call messages for interacting with the `sov-sequencer-registry` module.", - "oneOf": [ - { - "description": "Add a new sequencer to the sequencer registry.", - "type": "object", - "required": [ - "Register" - ], - "properties": { - "Register": { - "type": "object", - "required": [ - "da_address" - ], - "properties": { - "da_address": { - "description": "The raw Da address of the sequencer you're registering.", - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Remove a sequencer from the sequencer registry.", - "type": "object", - "required": [ - "Exit" - ], - "properties": { - "Exit": { - "type": "object", - "required": [ - "da_address" - ], - "properties": { - "da_address": { - "description": "The raw Da address of the sequencer you're removing.", - "type": "array", - "items": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - } - } - } - }, - "additionalProperties": false - } - ] -} diff --git a/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-value-setter.json b/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-value-setter.json deleted file mode 100644 index 915c3e4c0..000000000 --- a/crates/sovereign-sdk/module-system/module-schemas/schemas/sov-value-setter.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "CallMessage", - "description": "This enumeration represents the available call messages for interacting with the `sov-value-setter` module.", - "oneOf": [ - { - "description": "value to set", - "type": "object", - "required": [ - "SetValue" - ], - "properties": { - "SetValue": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - ] -} diff --git a/crates/sovereign-sdk/module-system/module-schemas/src/lib.rs b/crates/sovereign-sdk/module-system/module-schemas/src/lib.rs deleted file mode 100644 index 8b1378917..000000000 --- a/crates/sovereign-sdk/module-system/module-schemas/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/crates/sovereign-sdk/module-system/sov-cli/Cargo.toml b/crates/sovereign-sdk/module-system/sov-cli/Cargo.toml deleted file mode 100644 index 8930043bd..000000000 --- a/crates/sovereign-sdk/module-system/sov-cli/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -name = "sov-cli" -version.workspace = true -edition.workspace = true -license.workspace = true -authors.workspace = true -homepage.workspace = true -publish.workspace = true -repository.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -name = "sov_cli" -path = "src/lib.rs" - - -[dependencies] -sov-modules-api = { path = "../sov-modules-api", features = ["native"] } -sov-bank = { path = "../module-implementations/sov-bank", features = [ - "native", -] } -sov-accounts = { path = "../module-implementations/sov-accounts", features = [ - "native", -] } -directories = "5.0.1" -anyhow = { workspace = true } -hex = { workspace = true, features = ["serde"] } -borsh = { workspace = true } -serde = { workspace = true, features = ["derive"] } -serde_json = { workspace = true } -jsonrpsee = { workspace = true, features = ["client"] } - -[dev-dependencies] -tempfile = { workspace = true } -demo-stf = { path = "../../examples/demo-stf", features = ["native"] } -sov-mock-da = { path = "../../adapters/mock-da", features = ["native"] } diff --git a/crates/sovereign-sdk/module-system/sov-cli/README.md b/crates/sovereign-sdk/module-system/sov-cli/README.md deleted file mode 100644 index d82b2384c..000000000 --- a/crates/sovereign-sdk/module-system/sov-cli/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# CLI Wallet - -This package defines a CLI wallet to be used with the Sovereign SDK - -## Storage -By default, this wallet persists data in a directory called `.sov_cli_wallet`, under your home directory. Home is defined as follows: -- Linux: `/home/alice/` -- Windows: `C:\Users\Alice\AppData\Roaming` -- macOS: `/Users/Alice/Library/Application Support` - -To override this behavior, set the `SOV_WALLET_DIR` environment variable to the desired directory. Note that this directory is treated as a complete path, so the `.sov_cli_wallet` suffix is not automatically appended. diff --git a/crates/sovereign-sdk/module-system/sov-cli/src/lib.rs b/crates/sovereign-sdk/module-system/sov-cli/src/lib.rs deleted file mode 100644 index 00fec703d..000000000 --- a/crates/sovereign-sdk/module-system/sov-cli/src/lib.rs +++ /dev/null @@ -1,29 +0,0 @@ -#![deny(missing_docs)] -#![doc = include_str!("../README.md")] -use std::env; -use std::path::Path; - -use directories::BaseDirs; -pub use sov_modules_api::clap; - -/// Types and functionality storing and loading the persistent state of the wallet -pub mod wallet_state; -pub mod workflows; - -const SOV_WALLET_DIR_ENV_VAR: &str = "SOV_WALLET_DIR"; - -/// The directory where the wallet is stored. -pub fn wallet_dir() -> Result, anyhow::Error> { - // First try to parse from the env variable - if let Ok(val) = env::var(SOV_WALLET_DIR_ENV_VAR) { - return Ok(val.into()); - } - - // Fall back to the user's home directory - let dir = BaseDirs::new() - .ok_or_else(|| anyhow::anyhow!("Could not find home directory. You can set a wallet directory using the {} environment variable", SOV_WALLET_DIR_ENV_VAR))? - .home_dir() - .join(".sov_cli_wallet"); - - Ok(dir) -} diff --git a/crates/sovereign-sdk/module-system/sov-cli/src/wallet_state.rs b/crates/sovereign-sdk/module-system/sov-cli/src/wallet_state.rs deleted file mode 100644 index 153e8e270..000000000 --- a/crates/sovereign-sdk/module-system/sov-cli/src/wallet_state.rs +++ /dev/null @@ -1,344 +0,0 @@ -use std::fs; -use std::path::{Path, PathBuf}; -use std::str::FromStr; - -use borsh::{BorshDeserialize, BorshSerialize}; -use serde::de::DeserializeOwned; -use serde::{Deserialize, Serialize}; -use sov_modules_api::transaction::UnsignedTransaction; -use sov_modules_api::{clap, Context, PrivateKey}; - -/// A struct representing the current state of the CLI wallet -#[derive(Debug, Serialize, Deserialize)] -#[serde(bound = "Ctx::Address: Serialize + DeserializeOwned, Tx: Serialize + DeserializeOwned")] -pub struct WalletState -where - Tx: BorshSerialize + BorshDeserialize, -{ - /// The accumulated transactions to be submitted to the DA layer - pub unsent_transactions: Vec>, - /// The addresses in the wallet - pub addresses: AddressList, - /// The addresses in the wallet - pub rpc_url: Option, -} - -impl Default for WalletState -where - Tx: Serialize + DeserializeOwned + BorshSerialize + BorshDeserialize, - Ctx: Context, -{ - fn default() -> Self { - Self { - unsent_transactions: Vec::new(), - addresses: AddressList { - addresses: Vec::new(), - }, - rpc_url: None, - } - } -} - -impl WalletState -where - Tx: Serialize + DeserializeOwned + BorshSerialize + BorshDeserialize, - Ctx: Context, -{ - /// Load the wallet state from the given path on disk - pub fn load(path: impl AsRef) -> Result { - let path = path.as_ref(); - if path.exists() { - let data = fs::read(path)?; - let state = serde_json::from_slice(data.as_slice())?; - Ok(state) - } else { - Ok(Default::default()) - } - } - - /// Save the wallet state to the given path on disk - pub fn save(&self, path: impl AsRef) -> Result<(), anyhow::Error> { - let data = serde_json::to_string_pretty(self)?; - fs::write(path, data)?; - Ok(()) - } -} - -/// A struct representing private key and associated address -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(bound = "Ctx::Address: Serialize + DeserializeOwned")] -pub struct PrivateKeyAndAddress { - /// Private key of the address - pub private_key: Ctx::PrivateKey, - /// Address associated from the private key - pub address: Ctx::Address, -} - -impl PrivateKeyAndAddress { - /// Returns boolean if the private key matches default address - pub fn is_matching_to_default(&self) -> bool { - self.private_key.to_address::() == self.address - } - - /// Randomly generates a new private key and address - pub fn generate() -> Self { - let private_key = Ctx::PrivateKey::generate(); - let address = private_key.to_address::(); - Self { - private_key, - address, - } - } - - /// Generates valid private key and address from given private key - pub fn from_key(private_key: Ctx::PrivateKey) -> Self { - let address = private_key.to_address::(); - Self { - private_key, - address, - } - } -} - -/// A simplified struct representing private key and associated address -/// where the private key is represented as a hex string and address as canonical string -/// TODO: Remove it . -#[derive(Debug, serde::Serialize, serde::Deserialize)] -pub struct HexPrivateAndAddress { - /// Private key is hex encoded bytes, without leading 0x - pub hex_priv_key: String, - /// Address is in canonical string format - pub address: String, -} - -impl TryFrom for PrivateKeyAndAddress { - type Error = anyhow::Error; - - fn try_from(value: HexPrivateAndAddress) -> Result { - let private_key_bytes = hex::decode(value.hex_priv_key)?; - let private_key = Ctx::PrivateKey::try_from(&private_key_bytes)?; - let address = Ctx::Address::from_str(&value.address)?; - Ok(PrivateKeyAndAddress { - private_key, - address, - }) - } -} - -/// A list of addresses associated with this wallet -#[derive(Debug, Serialize, Deserialize)] -#[serde(bound = "Ctx::Address: Serialize + DeserializeOwned")] -pub struct AddressList { - /// All addresses which are known by the wallet. The active address is stored - /// first in this array - addresses: Vec>, -} - -impl AddressList { - /// Get the active address - pub fn default_address(&self) -> Option<&AddressEntry> { - self.addresses.first() - } - - /// Get an address by identifier - pub fn get_address( - &mut self, - identifier: &KeyIdentifier, - ) -> Option<&mut AddressEntry> { - self.addresses - .iter_mut() - .find(|entry| entry.matches(identifier)) - } - - /// Activate a key by identifier - pub fn activate(&mut self, identifier: &KeyIdentifier) -> Option<&AddressEntry> { - let (idx, _) = self - .addresses - .iter() - .enumerate() - .find(|(_idx, entry)| entry.matches(identifier))?; - self.addresses.swap(0, idx); - self.default_address() - } - - /// Remove an address from the wallet by identifier - pub fn remove(&mut self, identifier: &KeyIdentifier) { - self.addresses.retain(|entry| !entry.matches(identifier)); - } - - /// Add an address to the wallet - pub fn add( - &mut self, - address: Ctx::Address, - nickname: Option, - public_key: Ctx::PublicKey, - location: PathBuf, - ) { - let entry = AddressEntry { - address, - nickname, - location, - pub_key: public_key, - }; - self.addresses.push(entry); - } -} - -/// An entry in the address list -#[derive(Debug, Serialize, Deserialize)] -#[serde(bound = "Ctx::Address: Serialize + DeserializeOwned")] -pub struct AddressEntry { - /// The address - pub address: Ctx::Address, - /// A user-provided nickname - pub nickname: Option, - /// The location of the private key on disk - pub location: PathBuf, - /// The public key associated with the address - #[serde(with = "pubkey_hex")] - pub pub_key: Ctx::PublicKey, -} - -impl AddressEntry { - /// Check if the address entry matches the given nickname - pub fn is_nicknamed(&self, nickname: &str) -> bool { - self.nickname.as_deref() == Some(nickname) - } - - /// Check if the address entry matches the given identifier - pub fn matches(&self, identifier: &KeyIdentifier) -> bool { - match identifier { - KeyIdentifier::ByNickname { nickname } => self.is_nicknamed(nickname), - KeyIdentifier::ByAddress { address } => &self.address == address, - } - } -} - -/// An identifier for a key in the wallet -#[derive(Debug, clap::Subcommand, Clone)] -pub enum KeyIdentifier { - /// Select a key by nickname - ByNickname { - /// The nickname - nickname: String, - }, - /// Select a key by its associated address - ByAddress { - /// The address - address: C::Address, - }, -} -impl std::fmt::Display for KeyIdentifier { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - KeyIdentifier::ByNickname { nickname } => nickname.fmt(f), - KeyIdentifier::ByAddress { address } => address.fmt(f), - } - } -} - -mod pubkey_hex { - use core::fmt; - use std::marker::PhantomData; - - use borsh::{BorshDeserialize, BorshSerialize}; - use hex::{FromHex, ToHex}; - use serde::de::{Error, Visitor}; - use serde::{Deserializer, Serializer}; - use sov_modules_api::PublicKey; - pub fn serialize( - data: &P, - serializer: S, - ) -> Result - where - S: Serializer, - { - let bytes = borsh::to_vec(data).expect("serialization to vec is infallible"); - let formatted_string = format!("0x{}", bytes.encode_hex::()); - serializer.serialize_str(&formatted_string) - } - - /// Deserializes a hex string into raw bytes. - /// - /// Both, upper and lower case characters are valid in the input string and can - /// even be mixed (e.g. `f9b4ca`, `F9B4CA` and `f9B4Ca` are all valid strings). - pub fn deserialize<'de, D, C>(deserializer: D) -> Result - where - D: Deserializer<'de>, - C: PublicKey + BorshDeserialize, - { - struct HexPubkeyVisitor(PhantomData); - - impl<'de, C: PublicKey + BorshDeserialize> Visitor<'de> for HexPubkeyVisitor { - type Value = C; - - fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "a hex encoded string") - } - - fn visit_str(self, data: &str) -> Result - where - E: Error, - { - let data = data.trim_start_matches("0x"); - let bytes: Vec = FromHex::from_hex(data).map_err(Error::custom)?; - BorshDeserialize::try_from_slice(&bytes).map_err(Error::custom) - } - - fn visit_borrowed_str(self, data: &'de str) -> Result - where - E: Error, - { - let data = data.trim_start_matches("0x"); - let bytes: Vec = FromHex::from_hex(data).map_err(Error::custom)?; - BorshDeserialize::try_from_slice(&bytes).map_err(Error::custom) - } - } - - deserializer.deserialize_str(HexPubkeyVisitor(PhantomData::)) - } -} - -#[cfg(test)] -mod tests { - use sov_modules_api::default_context::DefaultContext; - - use super::*; - - type C = DefaultContext; - #[test] - fn test_private_key_and_address() { - let private_key_and_address = PrivateKeyAndAddress::::generate(); - - let json = serde_json::to_string_pretty(&private_key_and_address).unwrap(); - - let decoded: PrivateKeyAndAddress = serde_json::from_str(&json).unwrap(); - - assert_eq!( - private_key_and_address.private_key.pub_key(), - decoded.private_key.pub_key() - ); - assert_eq!(private_key_and_address.address, decoded.address); - } - - #[test] - fn test_hex_private_key_conversion() { - let private_key_and_address = PrivateKeyAndAddress::::generate(); - - let hex_private_key = private_key_and_address.private_key.as_hex(); - let address_string = private_key_and_address.address.to_string(); - - let hex_private_key_and_address = HexPrivateAndAddress { - hex_priv_key: hex_private_key, - address: address_string, - }; - - let converted = PrivateKeyAndAddress::::try_from(hex_private_key_and_address).unwrap(); - - assert_eq!( - private_key_and_address.private_key.pub_key(), - converted.private_key.pub_key() - ); - assert_eq!(private_key_and_address.address, converted.address); - } -} diff --git a/crates/sovereign-sdk/module-system/sov-cli/src/workflows/keys.rs b/crates/sovereign-sdk/module-system/sov-cli/src/workflows/keys.rs deleted file mode 100644 index efe1b2a97..000000000 --- a/crates/sovereign-sdk/module-system/sov-cli/src/workflows/keys.rs +++ /dev/null @@ -1,147 +0,0 @@ -//! Key management workflows for the sov CLI wallet -use std::path::{Path, PathBuf}; - -use borsh::{BorshDeserialize, BorshSerialize}; -use serde::de::DeserializeOwned; -use serde::Serialize; -use sov_modules_api::{clap, PrivateKey, PublicKey, Spec}; - -use crate::wallet_state::{KeyIdentifier, PrivateKeyAndAddress, WalletState}; - -#[derive(clap::Subcommand)] -/// View and manage keys associated with this wallet -pub enum KeyWorkflow { - /// Generate a new key pair - Generate { - #[clap(short, long)] - /// A nickname for this key pair - nickname: Option, - }, - /// Generate a new key pair if none exist - GenerateIfMissing { - #[clap(short, long)] - /// A nickname for this key pair - nickname: Option, - }, - /// Import an existing key pair - Import { - #[clap(short, long)] - /// A nickname for this key pair - nickname: Option, - #[clap(short, long)] - /// Register a different address than the one that would be derived from the private key. - address_override: Option, - #[clap(short, long)] - /// The path to the key file - path: PathBuf, - }, - /// List the keys in this wallet - List, - /// Set the active key - Activate { - /// The identifier of the key to activate - #[clap(subcommand)] - identifier: KeyIdentifier, - }, - /// Unlink a key from the wallet - Remove { - /// The identifier of the key to activate - #[clap(subcommand)] - identifier: KeyIdentifier, - }, -} - -impl KeyWorkflow { - /// Run the key workflow to import, generate, activate, or list keys - pub fn run( - self, - wallet_state: &mut WalletState, - app_dir: impl AsRef, - ) -> Result<(), anyhow::Error> - where - Tx: Serialize + DeserializeOwned + BorshSerialize + BorshDeserialize, - { - match self { - KeyWorkflow::Generate { nickname } => { - generate_and_save_key(nickname, app_dir, wallet_state)?; - } - KeyWorkflow::Import { - nickname, - address_override, - path, - } => { - // Try to load the key as a sanity check. - let private_key = load_key::(&path)?; - let public_key = private_key.pub_key(); - let address = - address_override.unwrap_or_else(|| public_key.to_address::()); - println!("Imported key pair. address: {}", address); - wallet_state - .addresses - .add(address, nickname, public_key, path); - } - KeyWorkflow::List => { - println!("{}", serde_json::to_string_pretty(&wallet_state.addresses)?) - } - KeyWorkflow::Activate { identifier } => { - if let Some(active) = wallet_state.addresses.default_address() { - if active.matches(&identifier) { - println!("Key '{}' is already active", identifier); - return Ok(()); - } - } - wallet_state - .addresses - .activate(&identifier) - .ok_or_else(|| { - anyhow::anyhow!("Could not find key with identifier {}", identifier) - })?; - println!("Activated key {}", identifier); - } - KeyWorkflow::GenerateIfMissing { nickname } => { - if wallet_state.addresses.default_address().is_none() { - generate_and_save_key(nickname, app_dir, wallet_state)?; - } - } - KeyWorkflow::Remove { identifier } => { - wallet_state.addresses.remove(&identifier); - } - } - Ok(()) - } -} - -/// Load a key from the given path -pub fn load_key( - path: impl AsRef, -) -> Result { - let data = std::fs::read_to_string(path)?; - let key_and_address: PrivateKeyAndAddress = serde_json::from_str(&data)?; - Ok(key_and_address.private_key) -} - -/// Generate a new key pair and save it to the wallet -pub fn generate_and_save_key( - nickname: Option, - app_dir: impl AsRef, - wallet_state: &mut WalletState, -) -> Result<(), anyhow::Error> -where - Tx: Serialize + DeserializeOwned + BorshSerialize + BorshDeserialize, -{ - let keys = ::PrivateKey::generate(); - let key_and_address = PrivateKeyAndAddress::::from_key(keys); - let public_key = key_and_address.private_key.pub_key(); - let address = key_and_address.address.clone(); - let key_path = app_dir.as_ref().join(format!("{}.json", address)); - println!( - "Generated key pair with address: {}. Saving to {}", - address, - key_path.display() - ); - std::fs::write(&key_path, serde_json::to_string(&key_and_address)?)?; - wallet_state - .addresses - .add(address, nickname, public_key, key_path); - Ok(()) -} diff --git a/crates/sovereign-sdk/module-system/sov-cli/src/workflows/mod.rs b/crates/sovereign-sdk/module-system/sov-cli/src/workflows/mod.rs deleted file mode 100644 index 21fadad1a..000000000 --- a/crates/sovereign-sdk/module-system/sov-cli/src/workflows/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! Workflows for the CLI wallet -pub mod keys; -pub mod rpc; -pub mod transactions; diff --git a/crates/sovereign-sdk/module-system/sov-cli/src/workflows/rpc.rs b/crates/sovereign-sdk/module-system/sov-cli/src/workflows/rpc.rs deleted file mode 100644 index d4afedb2a..000000000 --- a/crates/sovereign-sdk/module-system/sov-cli/src/workflows/rpc.rs +++ /dev/null @@ -1,197 +0,0 @@ -//! Query the current state of the rollup and send transactions - -use core::mem; -use std::path::Path; - -use anyhow::Context; -use borsh::{BorshDeserialize, BorshSerialize}; -use jsonrpsee::core::client::ClientT; -use jsonrpsee::http_client::HttpClientBuilder; -use serde::de::DeserializeOwned; -use serde::Serialize; -use sov_accounts::AccountsRpcClient; -use sov_bank::{BalanceResponse, BankRpcClient}; -use sov_modules_api::clap; -use sov_modules_api::transaction::Transaction; - -use crate::wallet_state::{AddressEntry, KeyIdentifier, WalletState}; -use crate::workflows::keys::load_key; -const NO_ACCOUNTS_FOUND: &str = - "No accounts found. You can generate one with the `keys generate` subcommand"; -const BAD_RPC_URL: &str = "Unable to connect to provided rpc. You can change to a different rpc url with the `rpc set-url` subcommand "; - -/// Query the current state of the rollup and send transactions -#[derive(clap::Subcommand)] -pub enum RpcWorkflows { - /// Set the url of the rpc server to use - SetUrl { - /// A url like http://localhost:8545 - rpc_url: String, - }, - /// Query the rpc server for the nonce of the provided account. If no account is provided, the active account is used - GetNonce { - /// (Optional) The account to query the nonce for (default: the active account) - #[clap(subcommand)] - account: Option>, - }, - /// Query the rpc server for the token balance of an account - GetBalance { - /// (Optional) The account to query the balance of (default: the active account) - #[clap(subcommand)] - account: Option>, - /// The address of the token to query for - token_address: C::Address, - }, - /// Sign all transactions from the current batch and submit them to the rollup. - /// Nonces will be set automatically. - SubmitBatch { - /// (Optional) The account to sign transactions for this batch (default: the active account) - #[clap(subcommand)] - account: Option>, - /// (Optional) The nonce to use for the first transaction in the batch (default: the current nonce for the account). Any other transactions will - /// be signed with sequential nonces starting from this value. - nonce_override: Option, - }, -} - -impl RpcWorkflows { - fn resolve_account<'wallet, Tx>( - &self, - wallet_state: &'wallet mut WalletState, - ) -> Result<&'wallet AddressEntry, anyhow::Error> - where - Tx: Serialize + DeserializeOwned + BorshSerialize + BorshDeserialize, - { - let account_id = match self { - RpcWorkflows::SetUrl { .. } => None, - RpcWorkflows::GetNonce { account } => account.as_ref(), - RpcWorkflows::GetBalance { account, .. } => account.as_ref(), - RpcWorkflows::SubmitBatch { account, .. } => account.as_ref(), - }; - - let account = if let Some(id) = account_id { - let addr = wallet_state.addresses.get_address(id); - - addr.ok_or_else(|| anyhow::format_err!("No account found matching identifier: {}", id))? - } else { - wallet_state - .addresses - .default_address() - .ok_or_else(|| anyhow::format_err!(NO_ACCOUNTS_FOUND))? - }; - Ok(account) - } -} - -impl RpcWorkflows { - /// Run the rpc workflow - pub async fn run( - &self, - wallet_state: &mut WalletState, - _app_dir: impl AsRef, - ) -> Result<(), anyhow::Error> - where - Tx: Serialize + DeserializeOwned + BorshSerialize + BorshDeserialize, - { - // If the user is just setting the RPC url, we can skip the usual setup - if let RpcWorkflows::SetUrl { rpc_url } = self { - let _client = HttpClientBuilder::default() - .build(rpc_url) - .context("Invalid RPC url: ")?; - wallet_state.rpc_url = Some(rpc_url.clone()); - println!("Set RPC url to {}", rpc_url); - return Ok(()); - } - - // Otherwise, we need to initialize an RPC and resolve the active account - let rpc_url = wallet_state - .rpc_url - .as_ref() - .ok_or(anyhow::format_err!( - "No rpc url set. Use the `rpc set-url` subcommand to set one" - ))? - .clone(); - let client = HttpClientBuilder::default().build(rpc_url)?; - let account = self.resolve_account(wallet_state)?; - - // Finally, run the workflow - match self { - RpcWorkflows::SetUrl { .. } => { - unreachable!("This case was handled above") - } - RpcWorkflows::GetNonce { .. } => { - let nonce = get_nonce_for_account(&client, account).await?; - println!("Nonce for account {} is {}", account.address, nonce); - } - RpcWorkflows::GetBalance { - account: _, - token_address, - } => { - let BalanceResponse { amount } = BankRpcClient::::balance_of( - &client, - account.address.clone(), - token_address.clone(), - ) - .await - .context(BAD_RPC_URL)?; - - println!( - "Balance for account {} is {}", - account.address, - amount.unwrap_or_default() - ); - } - RpcWorkflows::SubmitBatch { nonce_override, .. } => { - let private_key = load_key::(&account.location)?; - - let nonce = match nonce_override { - Some(nonce) => *nonce, - None => get_nonce_for_account(&client, account).await?, - }; - - let txs = mem::take(&mut wallet_state.unsent_transactions) - .into_iter() - .enumerate() - .map(|(offset, tx)| { - let transaction = Transaction::::new_signed_tx( - &private_key, - borsh::to_vec(&tx).unwrap(), - tx.chain_id, - nonce + offset as u64, - ); - borsh::to_vec(&transaction).unwrap() - }) - .collect::>(); - - let response: String = client - .request("sequencer_publishBatch", txs) - .await - .context("Unable to publish batch")?; - - // Print the result - println!( - "Your batch was submitted to the sequencer for publication. Response: {:?}", - response - ); - } - } - Ok(()) - } -} - -async fn get_nonce_for_account( - client: &(impl ClientT + Send + Sync), - account: &AddressEntry, -) -> Result { - Ok(match AccountsRpcClient::::get_account( - client, - account.pub_key.clone(), - ) - .await - .context( - "Unable to connect to provided RPC. You can change to a different RPC url with the `rpc set-url` subcommand ", - )? { - sov_accounts::Response::AccountExists { addr: _, nonce } => nonce, - _ => 0, - }) -} diff --git a/crates/sovereign-sdk/module-system/sov-cli/src/workflows/transactions.rs b/crates/sovereign-sdk/module-system/sov-cli/src/workflows/transactions.rs deleted file mode 100644 index f80f0539b..000000000 --- a/crates/sovereign-sdk/module-system/sov-cli/src/workflows/transactions.rs +++ /dev/null @@ -1,141 +0,0 @@ -//! Workflows for transaction management - -use std::path::Path; - -use borsh::{BorshDeserialize, BorshSerialize}; -use serde::de::DeserializeOwned; -use serde::Serialize; -use sov_modules_api::clap::{self, Subcommand}; -use sov_modules_api::cli::{CliFrontEnd, CliTxImportArg}; -use sov_modules_api::transaction::UnsignedTransaction; -use sov_modules_api::CliWallet; - -use crate::wallet_state::WalletState; - -#[derive(clap::Parser)] -/// Generate, sign, and send transactions -pub enum TransactionWorkflow { - /// Import a transaction - #[clap(subcommand)] - Import(ImportTransaction), - /// Delete the current batch of transactions - Clean, - /// Remove a single transaction from the current batch - Remove { - /// The index of the transaction to remove, starting from 0 - index: usize, - }, - /// List the current batch of transactions - List, -} - -impl TransactionWorkflow { - /// Run the transaction workflow - pub fn run( - self, - wallet_state: &mut WalletState, - _app_dir: impl AsRef, - ) -> Result<(), anyhow::Error> - where - File: CliFrontEnd + CliTxImportArg, - Json: CliFrontEnd + CliTxImportArg, - File: TryInto, Error = E1>, - Json: TryInto, Error = E2>, - RT::CliStringRepr: TryInto, - RT::Decodable: BorshSerialize + BorshDeserialize + Serialize + DeserializeOwned, - E1: Into + Send + Sync, - E2: Into + Send + Sync, - E3: Into + Send + Sync, - { - match self { - TransactionWorkflow::Import(import_workflow) => import_workflow.run(wallet_state), - TransactionWorkflow::List => { - println!("Current batch:"); - println!( - "{}", - serde_json::to_string_pretty(&wallet_state.unsent_transactions)? - ); - Ok(()) - } - TransactionWorkflow::Clean => { - wallet_state.unsent_transactions.clear(); - Ok(()) - } - TransactionWorkflow::Remove { index } => { - wallet_state.unsent_transactions.remove(index); - Ok(()) - } - } - } -} -/// An argument passed as path to a file -#[derive(clap::Parser)] -pub struct FileArg { - /// The path to the file - #[arg(long, short)] - pub path: String, -} - -#[derive(clap::Subcommand)] -/// Import a pre-formatted transaction from a JSON file or as a JSON string -pub enum ImportTransaction { - /// Import a transaction from a JSON file at the provided path - #[clap(subcommand)] - FromFile(Json), - /// Provide a JSON serialized transaction directly as input - #[clap(subcommand)] - FromString( - /// The JSON serialized transaction as a string. - /// The expected format is: {"module_name": {"call_name": {"field_name": "field_value"}}} - File, - ), -} - -impl ImportTransaction -where - Json: Subcommand, - File: Subcommand, -{ - /// Parse from a file or a json string - pub fn run( - self, - wallet_state: &mut WalletState, - ) -> Result<(), anyhow::Error> - where - Json: CliFrontEnd + CliTxImportArg, - File: CliFrontEnd + CliTxImportArg, - Json: TryInto, Error = E1>, - File: TryInto, Error = E2>, - RT::CliStringRepr: TryInto, - RT::Decodable: BorshSerialize + BorshDeserialize + Serialize + DeserializeOwned, - E1: Into + Send + Sync, - E2: Into + Send + Sync, - E3: Into + Send + Sync, - { - let chain_id; - - let intermediate_repr: RT::CliStringRepr = match self { - ImportTransaction::FromFile(file) => { - chain_id = file.chain_id(); - file.try_into().map_err(Into::::into)? - } - ImportTransaction::FromString(json) => { - chain_id = json.chain_id(); - json.try_into().map_err(Into::::into)? - } - }; - - let tx: RT::Decodable = intermediate_repr - .try_into() - .map_err(Into::::into)?; - - let tx = UnsignedTransaction::new(tx, chain_id); - - println!("Adding the following transaction to batch:"); - println!("{}", serde_json::to_string_pretty(&tx)?); - - wallet_state.unsent_transactions.push(tx); - - Ok(()) - } -} diff --git a/crates/sovereign-sdk/module-system/sov-cli/test-data/requests/burn.json b/crates/sovereign-sdk/module-system/sov-cli/test-data/requests/burn.json deleted file mode 100644 index 991b5aaa0..000000000 --- a/crates/sovereign-sdk/module-system/sov-cli/test-data/requests/burn.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Burn": { - "coins": { - "amount": 300, - "token_address": "sov16m8fxq0x5wc5aw75fx9rus2p7g2l22zf4re72c3m058g77cdjemsavg2ft" - } - } -} diff --git a/crates/sovereign-sdk/module-system/sov-cli/test-data/requests/create_token.json b/crates/sovereign-sdk/module-system/sov-cli/test-data/requests/create_token.json deleted file mode 100644 index 16c27afd1..000000000 --- a/crates/sovereign-sdk/module-system/sov-cli/test-data/requests/create_token.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "CreateToken": { - "salt": 11, - "token_name": "sov-test-token", - "initial_balance": 1000, - "minter_address": "sov1x3jtvq0zwhj2ucsc4hqugskvralrulxvf53vwtkred93s2x9gmzs04jvyr", - "authorized_minters": [ - "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94", - "sov1x3jtvq0zwhj2ucsc4hqugskvralrulxvf53vwtkred93s2x9gmzs04jvyr", - "sov15vspj48hpttzyvxu8kzq5klhvaczcpyxn6z6k0hwpwtzs4a6wkvqwr57gc" - ] - } -} diff --git a/crates/sovereign-sdk/module-system/sov-cli/test-data/requests/mint.json b/crates/sovereign-sdk/module-system/sov-cli/test-data/requests/mint.json deleted file mode 100644 index 10436e602..000000000 --- a/crates/sovereign-sdk/module-system/sov-cli/test-data/requests/mint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Mint": { - "coins": { - "amount": 3000, - "token_address": "sov16m8fxq0x5wc5aw75fx9rus2p7g2l22zf4re72c3m058g77cdjemsavg2ft" - }, - "minter_address": "sov15vspj48hpttzyvxu8kzq5klhvaczcpyxn6z6k0hwpwtzs4a6wkvqwr57gc" - } -} diff --git a/crates/sovereign-sdk/module-system/sov-cli/test-data/requests/transfer.json b/crates/sovereign-sdk/module-system/sov-cli/test-data/requests/transfer.json deleted file mode 100644 index 92411d14c..000000000 --- a/crates/sovereign-sdk/module-system/sov-cli/test-data/requests/transfer.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Transfer": { - "to": "sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqklh0qh", - "coins": { - "amount": 200, - "token_address": "sov16m8fxq0x5wc5aw75fx9rus2p7g2l22zf4re72c3m058g77cdjemsavg2ft" - } - } -} diff --git a/crates/sovereign-sdk/module-system/sov-cli/tests/keys.rs b/crates/sovereign-sdk/module-system/sov-cli/tests/keys.rs deleted file mode 100644 index e340c9e86..000000000 --- a/crates/sovereign-sdk/module-system/sov-cli/tests/keys.rs +++ /dev/null @@ -1,98 +0,0 @@ -use demo_stf::runtime::RuntimeCall; -use sov_cli::wallet_state::{KeyIdentifier, PrivateKeyAndAddress, WalletState}; -use sov_cli::workflows::keys::KeyWorkflow; -use sov_mock_da::MockDaSpec; -use sov_modules_api::default_context::DefaultContext; -use sov_modules_api::{PrivateKey, PublicKey, Spec}; - -type Da = MockDaSpec; - -#[test] -fn test_key_gen() { - let app_dir = tempfile::tempdir().unwrap(); - let mut wallet_state = - WalletState::, DefaultContext>::default(); - let workflow = KeyWorkflow::Generate { nickname: None }; - workflow.run(&mut wallet_state, app_dir).unwrap(); - - assert!(wallet_state.addresses.default_address().is_some()); -} - -#[test] -fn test_key_import() { - let app_dir = tempfile::tempdir().unwrap(); - // Generate a key and write it to a file - let generated_key = ::PrivateKey::generate(); - let key_path = app_dir.path().join("test_key"); - let key_and_address = PrivateKeyAndAddress::::from_key(generated_key.clone()); - std::fs::write(&key_path, serde_json::to_string(&key_and_address).unwrap()) - .expect("Failed to write key to tempdir"); - - // Initialize an empty wallet - let mut wallet_state = - WalletState::, DefaultContext>::default(); - let workflow = KeyWorkflow::Import { - nickname: Some("my-test-key".to_string()), - address_override: None, - path: key_path, - }; - // Import the key - workflow.run(&mut wallet_state, app_dir).unwrap(); - - // Ensure that the wallet has at least one key - let entry = wallet_state - .addresses - .default_address() - .expect("Key import must succeed"); - - assert_eq!(entry.nickname.as_ref().unwrap(), "my-test-key"); - assert_eq!( - entry.address, - generated_key - .pub_key() - .to_address::<::Address>() - ); -} - -#[test] -fn test_activate() { - // Setup a wallet with two keys - let app_dir = tempfile::tempdir().unwrap(); - let mut wallet_state = - WalletState::, DefaultContext>::default(); - let workflow = KeyWorkflow::Generate { - nickname: Some("key1".into()), - }; - workflow.run(&mut wallet_state, &app_dir).unwrap(); - let workflow = KeyWorkflow::Generate { - nickname: Some("key2".into()), - }; - workflow.run(&mut wallet_state, &app_dir).unwrap(); - - // Ensure that key1 is active - let current_active_wallet = wallet_state.addresses.default_address().unwrap(); - assert!(current_active_wallet.is_nicknamed("key1")); - let address_1 = current_active_wallet.address; - - // Activate key2 by nickname - let workflow = KeyWorkflow::Activate { - identifier: KeyIdentifier::ByNickname { - nickname: "key2".to_string(), - }, - }; - workflow.run(&mut wallet_state, &app_dir).unwrap(); - - // Ensure that key2 is active - let current_active_wallet = wallet_state.addresses.default_address().unwrap(); - assert!(current_active_wallet.is_nicknamed("key2")); - - // Activate key1 by address - let workflow = KeyWorkflow::Activate { - identifier: KeyIdentifier::ByAddress { address: address_1 }, - }; - workflow.run(&mut wallet_state, &app_dir).unwrap(); - - // Ensure that key1 is active - let current_active_wallet = wallet_state.addresses.default_address().unwrap(); - assert!(current_active_wallet.is_nicknamed("key1")); -} diff --git a/crates/sovereign-sdk/module-system/sov-cli/tests/transactions.rs b/crates/sovereign-sdk/module-system/sov-cli/tests/transactions.rs deleted file mode 100644 index 94b6f4448..000000000 --- a/crates/sovereign-sdk/module-system/sov-cli/tests/transactions.rs +++ /dev/null @@ -1,69 +0,0 @@ -use std::path::{Path, PathBuf}; - -use demo_stf::runtime::{Runtime, RuntimeCall, RuntimeSubcommand}; -use sov_cli::wallet_state::WalletState; -use sov_cli::workflows::transactions::{ImportTransaction, TransactionWorkflow}; -use sov_mock_da::MockDaSpec; -use sov_modules_api::cli::{FileNameArg, JsonStringArg}; -use sov_modules_api::default_context::DefaultContext; - -type Da = MockDaSpec; - -#[test] -fn test_import_transaction_from_string() { - let app_dir = tempfile::tempdir().unwrap(); - let mut wallet_state = - WalletState::, DefaultContext>::default(); - - let test_token_path = make_test_path("requests/create_token.json"); - let subcommand = RuntimeSubcommand::::bank { - contents: JsonStringArg { - json: std::fs::read_to_string(test_token_path).unwrap(), - chain_id: 0, - }, - }; - - let workflow = TransactionWorkflow::Import(ImportTransaction::< - _, - RuntimeSubcommand, - >::FromFile(subcommand)); - workflow - .run::, _, _, _, _, _>(&mut wallet_state, app_dir) - .unwrap(); - - assert_eq!(wallet_state.unsent_transactions.len(), 1); -} - -#[test] -fn test_import_transaction_from_file() { - let app_dir = tempfile::tempdir().unwrap(); - let mut wallet_state = - WalletState::, DefaultContext>::default(); - - let test_token_path = make_test_path("requests/create_token.json"); - let subcommand = RuntimeSubcommand::::bank { - contents: FileNameArg { - path: test_token_path.to_str().unwrap().into(), - chain_id: 0, - }, - }; - - let workflow = TransactionWorkflow::Import(ImportTransaction::< - _, - RuntimeSubcommand, - >::FromFile(subcommand)); - workflow - .run::, _, _, _, _, _>(&mut wallet_state, app_dir) - .unwrap(); - - assert_eq!(wallet_state.unsent_transactions.len(), 1); -} - -fn make_test_path>(path: P) -> PathBuf { - let mut sender_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - sender_path.push("test-data"); - - sender_path.push(path); - - sender_path -} diff --git a/crates/sovereign-sdk/module-system/sov-modules-api/src/reexport_macros.rs b/crates/sovereign-sdk/module-system/sov-modules-api/src/reexport_macros.rs index 1ab481027..561c37ca5 100644 --- a/crates/sovereign-sdk/module-system/sov-modules-api/src/reexport_macros.rs +++ b/crates/sovereign-sdk/module-system/sov-modules-api/src/reexport_macros.rs @@ -2,9 +2,6 @@ /// type. #[cfg(feature = "macros")] pub use sov_modules_macros::DispatchCall; -/// Derives the Event enum for a given runtime. -#[cfg(feature = "macros")] -pub use sov_modules_macros::Event; /// Derives the [`Genesis`](trait.Genesis.html) trait for the underlying runtime /// `struct`. #[cfg(feature = "macros")] diff --git a/crates/sovereign-sdk/module-system/sov-modules-api/src/transaction.rs b/crates/sovereign-sdk/module-system/sov-modules-api/src/transaction.rs index f0f0f4d26..39c4a0de2 100644 --- a/crates/sovereign-sdk/module-system/sov-modules-api/src/transaction.rs +++ b/crates/sovereign-sdk/module-system/sov-modules-api/src/transaction.rs @@ -1,6 +1,3 @@ -use borsh::{BorshDeserialize, BorshSerialize}; -use serde::de::DeserializeOwned; -use serde::{Deserialize, Serialize}; #[cfg(feature = "native")] use sov_modules_core::PrivateKey; use sov_modules_core::{Context, Signature}; @@ -21,19 +18,6 @@ pub struct Transaction { nonce: u64, } -/// An unsent transaction with the required data to be submitted to the DA layer -#[derive(Debug, Serialize, Deserialize, BorshSerialize, BorshDeserialize)] -#[serde(bound = "Tx: serde::Serialize + serde::de::DeserializeOwned")] -pub struct UnsignedTransaction -where - Tx: BorshSerialize + BorshDeserialize, -{ - /// The underlying transaction - pub tx: Tx, - /// The ID of the target chain - pub chain_id: u64, -} - impl Transaction { pub fn signature(&self) -> &C::Signature { &self.signature @@ -121,12 +105,3 @@ impl Transaction { } } } - -impl UnsignedTransaction -where - Tx: Serialize + DeserializeOwned + BorshSerialize + BorshDeserialize, -{ - pub const fn new(tx: Tx, chain_id: u64) -> Self { - Self { tx, chain_id } - } -} diff --git a/crates/sovereign-sdk/module-system/sov-modules-macros/src/event.rs b/crates/sovereign-sdk/module-system/sov-modules-macros/src/event.rs deleted file mode 100644 index d47613804..000000000 --- a/crates/sovereign-sdk/module-system/sov-modules-macros/src/event.rs +++ /dev/null @@ -1,74 +0,0 @@ -use proc_macro2::Span; -use syn::DeriveInput; - -use super::common::{ - get_generics_type_param, get_serialization_attrs, StructDef, StructFieldExtractor, -}; - -pub(crate) const EVENT: &str = "Event"; - -pub(crate) struct EventMacro { - field_extractor: StructFieldExtractor, -} - -impl<'a> StructDef<'a> { - fn create_event_enum_legs(&self) -> Vec { - self.fields - .iter() - .map(|field| { - let name = &field.ident; - let ty = &field.ty; - - quote::quote!( - #[doc = "Module event."] - #name(<#ty as ::sov_modules_api::Module>::Event), - ) - }) - .collect() - } -} - -impl EventMacro { - pub(crate) fn new(name: &'static str) -> Self { - Self { - field_extractor: StructFieldExtractor::new(name), - } - } - - pub(crate) fn derive_event_enum( - &self, - input: DeriveInput, - ) -> Result { - let serialization_methods = get_serialization_attrs(&input)?; - - let DeriveInput { - data, - ident, - generics, - .. - } = input; - - let generic_param = get_generics_type_param(&generics, Span::call_site())?; - - let (impl_generics, type_generics, where_clause) = generics.split_for_impl(); - let fields = self.field_extractor.get_fields_from_struct(&data)?; - - let struct_def = StructDef::new( - ident, - fields, - impl_generics, - type_generics, - &generic_param, - where_clause, - ); - - let event_enum_legs = struct_def.create_event_enum_legs(); - let event_enum = struct_def.create_enum(&event_enum_legs, EVENT, &serialization_methods); - - Ok(quote::quote! { - #[doc="This enum is generated from the underlying Runtime, the variants correspond to events from the relevant modules"] - #event_enum - } - .into()) - } -} diff --git a/crates/sovereign-sdk/module-system/sov-modules-macros/src/lib.rs b/crates/sovereign-sdk/module-system/sov-modules-macros/src/lib.rs index 32456301e..37575ef73 100644 --- a/crates/sovereign-sdk/module-system/sov-modules-macros/src/lib.rs +++ b/crates/sovereign-sdk/module-system/sov-modules-macros/src/lib.rs @@ -14,13 +14,10 @@ mod cli_parser; mod common; mod default_runtime; mod dispatch; -mod event; mod make_constants; mod manifest; mod module_call_json_schema; mod module_info; -mod new_types; -mod offchain; #[cfg(feature = "native")] mod rpc; @@ -30,16 +27,13 @@ use default_runtime::DefaultRuntimeMacro; use dispatch::dispatch_call::DispatchCallMacro; use dispatch::genesis::GenesisMacro; use dispatch::message_codec::MessageCodec; -use event::EventMacro; use make_constants::{make_const, PartialItemConst}; use module_call_json_schema::derive_module_call_json_schema; use module_info::ModuleType; -use new_types::address_type_helper; -use offchain::offchain_generator; use proc_macro::TokenStream; #[cfg(feature = "native")] use rpc::ExposeRpcMacro; -use syn::{parse_macro_input, DeriveInput, ItemFn}; +use syn::parse_macro_input; #[proc_macro_derive(ModuleInfo, attributes(state, module, address, gas, memory))] pub fn module_info(input: TokenStream) -> TokenStream { @@ -82,14 +76,6 @@ pub fn dispatch_call(input: TokenStream) -> TokenStream { handle_macro_error(call_macro.derive_dispatch_call(input)) } -#[proc_macro_derive(Event, attributes(serialization))] -pub fn event(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input); - let event_macro = EventMacro::new("Event"); - - handle_macro_error(event_macro.derive_event_enum(input)) -} - #[proc_macro_derive(ModuleCallJsonSchema)] pub fn module_call_json_schema(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input); @@ -232,103 +218,3 @@ pub fn custom_enum_clap(input: TokenStream) -> TokenStream { let input: syn::DeriveInput = parse_macro_input!(input); handle_macro_error(derive_cli_wallet_arg(input)) } - -/// Simple convenience macro for adding some common derive macros and -/// impls specifically for a NewType wrapping an Address. -/// The reason for having this is that we assumes NewTypes for address as a common use case -/// -/// ## Example -/// ``` -///use sov_modules_macros::address_type; -///use std::fmt; -///use sov_modules_api::Context; -///#[address_type] -///pub struct UserAddress; -/// ``` -/// -/// This is exactly equivalent to hand-writing -/// -/// ``` -/// use std::fmt; -/// use sov_modules_api::Context; -///#[cfg(feature = "native")] -///#[derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema)] -///#[schemars(bound = "C::Address: ::schemars::JsonSchema", rename = "UserAddress")] -///#[serde(transparent)] -///#[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Clone, Debug, PartialEq, Eq, Hash)] -///pub struct UserAddress(C::Address); -/// -///#[cfg(not(feature = "native"))] -///#[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Clone, Debug, PartialEq, Eq, Hash)] -///pub struct UserAddress(C::Address); -/// -///impl UserAddress { -/// /// Public constructor -/// pub fn new(address: &C::Address) -> Self { -/// UserAddress(address.clone()) -/// } -/// -/// /// Public getter -/// pub fn get_address(&self) -> &C::Address { -/// &self.0 -/// } -///} -/// -///impl fmt::Display for UserAddress -///where -/// C::Address: fmt::Display, -///{ -/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -/// write!(f, "{}", self.0) -/// } -///} -/// -///impl AsRef<[u8]> for UserAddress -///where -/// C::Address: AsRef<[u8]>, -///{ -/// fn as_ref(&self) -> &[u8] { -/// self.0.as_ref() -/// } -///} -/// ``` -#[proc_macro_attribute] -pub fn address_type(_attr: TokenStream, item: TokenStream) -> TokenStream { - let input = parse_macro_input!(item as DeriveInput); - handle_macro_error(address_type_helper(input)) -} - -/// The offchain macro is used to annotate functions that should only be executed by the rollup -/// when the "offchain" feature flag is passed. The macro produces one of two functions depending on -/// the presence flag. -/// "offchain" feature enabled: function is present as defined -/// "offchain" feature absent: function body is replaced with an empty definition -/// -/// The idea here is that offchain computation is optionally enabled for a full node and is not -/// part of chain state and does not impact consensus, prover or anything else. -/// -/// ## Example -/// ``` -/// use sov_modules_macros::offchain; -/// #[offchain] -/// fn redis_insert(count: u64){ -/// println!("Inserting {} to redis", count); -/// } -/// ``` -/// -/// This is exactly equivalent to hand-writing -///``` -/// #[cfg(feature = "offchain")] -/// fn redis_insert(count: u64){ -/// println!("Inserting {} to redis", count); -/// } -/// -/// #[cfg(not(feature = "offchain"))] -/// fn redis_insert(count: u64){ -/// } -///``` -#[proc_macro_attribute] -pub fn offchain(_attr: TokenStream, item: TokenStream) -> TokenStream { - let input = parse_macro_input!(item as ItemFn); - handle_macro_error(offchain_generator(input)) -} diff --git a/crates/sovereign-sdk/module-system/sov-modules-macros/src/new_types.rs b/crates/sovereign-sdk/module-system/sov-modules-macros/src/new_types.rs deleted file mode 100644 index ea49a43e0..000000000 --- a/crates/sovereign-sdk/module-system/sov-modules-macros/src/new_types.rs +++ /dev/null @@ -1,57 +0,0 @@ -use proc_macro::TokenStream; -use quote::quote; -use syn::{Attribute, DeriveInput}; - -pub fn address_type_helper(input: DeriveInput) -> Result { - let name = &input.ident; - let name_str = format!("{}", name); - let attrs: Vec = input.attrs; - - let expanded = quote! { - #[cfg(feature = "native")] - #[derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema)] - #[schemars(bound = "C::Address: ::schemars::JsonSchema", rename = #name_str)] - #[serde(transparent)] - #[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Clone, Debug, PartialEq, Eq, Hash)] - #(#attrs)* - pub struct #name(C::Address); - - #[cfg(not(feature = "native"))] - #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] - #[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Clone, Debug, PartialEq, Eq, Hash)] - #(#attrs)* - pub struct #name(C::Address); - - impl #name { - /// Public constructor - pub fn new(address: &C::Address) -> Self { - #name(address.clone()) - } - - /// Public getter - pub fn get_address(&self) -> &C::Address { - &self.0 - } - } - - impl fmt::Display for #name - where - C::Address: fmt::Display, - { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.0) - } - } - - impl AsRef<[u8]> for #name - where - C::Address: AsRef<[u8]>, - { - fn as_ref(&self) -> &[u8] { - self.0.as_ref() - } - } - }; - - Ok(expanded.into()) -} diff --git a/crates/sovereign-sdk/module-system/sov-modules-macros/src/offchain.rs b/crates/sovereign-sdk/module-system/sov-modules-macros/src/offchain.rs deleted file mode 100644 index 274021ad9..000000000 --- a/crates/sovereign-sdk/module-system/sov-modules-macros/src/offchain.rs +++ /dev/null @@ -1,31 +0,0 @@ -use proc_macro::TokenStream; -use quote::quote; -use syn::ItemFn; - -pub fn offchain_generator(function: ItemFn) -> Result { - let visibility = &function.vis; - let name = &function.sig.ident; - let inputs = &function.sig.inputs; - let output = &function.sig.output; - let block = &function.block; - let generics = &function.sig.generics; - let where_clause = &function.sig.generics.where_clause; - let asyncness = &function.sig.asyncness; - - let output = quote! { - // The "real" function - #[cfg(feature = "offchain")] - #visibility #asyncness fn #name #generics(#inputs) #output #where_clause { - #block - } - - // The no-op function - #[cfg(not(feature = "offchain"))] - #[allow(unused_variables)] - #visibility #asyncness fn #name #generics(#inputs) #output #where_clause { - // Do nothing. Should be optimized away - } - }; - - Ok(output.into()) -} diff --git a/crates/sovereign-sdk/module-system/sov-modules-macros/tests/all_tests.rs b/crates/sovereign-sdk/module-system/sov-modules-macros/tests/all_tests.rs index a2c53ed3a..500cc5e70 100644 --- a/crates/sovereign-sdk/module-system/sov-modules-macros/tests/all_tests.rs +++ b/crates/sovereign-sdk/module-system/sov-modules-macros/tests/all_tests.rs @@ -33,7 +33,6 @@ fn module_dispatch_tests() { let t = trybuild::TestCases::new(); t.pass("tests/dispatch/derive_genesis.rs"); t.pass("tests/dispatch/derive_dispatch.rs"); - t.pass("tests/dispatch/derive_event.rs"); t.compile_fail("tests/dispatch/missing_serialization.rs"); } diff --git a/crates/sovereign-sdk/module-system/sov-modules-macros/tests/dispatch/derive_event.rs b/crates/sovereign-sdk/module-system/sov-modules-macros/tests/dispatch/derive_event.rs deleted file mode 100644 index 31b33a1dd..000000000 --- a/crates/sovereign-sdk/module-system/sov-modules-macros/tests/dispatch/derive_event.rs +++ /dev/null @@ -1,26 +0,0 @@ -mod modules; -use modules::{first_test_module, second_test_module}; -use sov_modules_api::default_context::DefaultContext; -use sov_modules_api::macros::DefaultRuntime; -use sov_modules_api::{Context, DispatchCall, Event, Genesis, MessageCodec}; - -#[derive(Genesis, DispatchCall, Event, MessageCodec, DefaultRuntime)] -#[serialization(borsh::BorshDeserialize, borsh::BorshSerialize)] -struct Runtime { - pub first: first_test_module::FirstTestStruct, - pub second: second_test_module::SecondTestStruct, -} - -fn main() { - // Check to see if the runtime events are getting initialized correctly - let _event = - RuntimeEvent::::first(first_test_module::Event::FirstModuleEnum1(10)); - let _event = RuntimeEvent::::first(first_test_module::Event::FirstModuleEnum2); - let _event = - RuntimeEvent::::first(first_test_module::Event::FirstModuleEnum3(vec![ - 1; - 3 - ])); - let _event = - RuntimeEvent::::second(second_test_module::Event::SecondModuleEnum); -} diff --git a/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/Cargo.toml b/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/Cargo.toml index 8bee6e5de..35a4029ac 100644 --- a/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/Cargo.toml +++ b/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/Cargo.toml @@ -13,23 +13,15 @@ description = "This crate contains abstractions needed to create a new rollup" [dependencies] citrea-common = { path = "../../../common" } -sov-cli = { path = "../../module-system/sov-cli" } +sov-db = { path = "../../full-node/db/sov-db" } +sov-ledger-rpc = { path = "../../full-node/sov-ledger-rpc", features = ["server"] } sov-modules-api = { path = "../../module-system/sov-modules-api", features = ["native"] } +sov-modules-stf-blueprint = { path = "../../module-system/sov-modules-stf-blueprint", features = ["native"] } sov-rollup-interface = { path = "../../rollup-interface", features = ["native"] } -sov-state = { path = "../sov-state" } sov-stf-runner = { path = "../../full-node/sov-stf-runner", features = ["native"] } -sov-db = { path = "../../full-node/db/sov-db" } -sov-modules-stf-blueprint = { path = "../../module-system/sov-modules-stf-blueprint", features = ["native"] } - -sov-ledger-rpc = { path = "../../full-node/sov-ledger-rpc", features = ["server"] } - anyhow = { workspace = true } async-trait = { workspace = true } -borsh = { workspace = true } -hex = { workspace = true } jsonrpsee = { workspace = true, features = ["http-client", "server"] } -serde = { workspace = true } -serde_json = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } diff --git a/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/src/lib.rs b/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/src/lib.rs index 89d4ca8ea..7f9af3b0a 100644 --- a/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/src/lib.rs +++ b/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/src/lib.rs @@ -2,7 +2,6 @@ #![doc = include_str!("../README.md")] mod runtime_rpc; -mod wallet; use std::collections::HashMap; use std::sync::Arc; @@ -20,7 +19,6 @@ use sov_rollup_interface::storage::HierarchicalStorageManager; use sov_rollup_interface::zk::{Zkvm, ZkvmHost}; use sov_stf_runner::ProverService; use tokio::sync::broadcast; -pub use wallet::*; /// This trait defines how to crate all the necessary dependencies required by a rollup. #[async_trait] diff --git a/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/src/wallet.rs b/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/src/wallet.rs deleted file mode 100644 index f49e16e9e..000000000 --- a/crates/sovereign-sdk/module-system/sov-modules-rollup-blueprint/src/wallet.rs +++ /dev/null @@ -1,99 +0,0 @@ -use async_trait::async_trait; -use borsh::{BorshDeserialize, BorshSerialize}; -use serde::de::DeserializeOwned; -use serde::Serialize; -use sov_cli::wallet_state::WalletState; -use sov_cli::workflows::keys::KeyWorkflow; -use sov_cli::workflows::rpc::RpcWorkflows; -use sov_cli::workflows::transactions::TransactionWorkflow; -use sov_cli::{clap, wallet_dir}; -use sov_modules_api::clap::Parser; -use sov_modules_api::cli::{CliFrontEnd, CliTxImportArg, JsonStringArg}; -use sov_modules_api::{CliWallet, Context, DispatchCall}; - -use crate::RollupBlueprint; - -#[derive(clap::Subcommand)] -#[command(author, version, about, long_about = None)] -enum Workflows { - #[clap(subcommand)] - Transactions(TransactionWorkflow), - #[clap(subcommand)] - Keys(KeyWorkflow), - #[clap(subcommand)] - Rpc(RpcWorkflows), -} - -#[derive(clap::Parser)] -#[command(author, version, about = None, long_about = None)] -struct CliApp { - #[clap(subcommand)] - workflow: Workflows, -} - -/// Generic wallet for any type that implements RollupBlueprint. -#[async_trait] -pub trait WalletBlueprint: RollupBlueprint -where - // The types here a quite complicated but they are never exposed to the user - // as the WalletTemplate is implemented for any types that implements RollupBlueprint. - ::NativeContext: - serde::Serialize + serde::de::DeserializeOwned + Send + Sync, - - ::NativeRuntime: CliWallet, - - ::DaSpec: serde::Serialize + serde::de::DeserializeOwned, - - <::NativeRuntime as DispatchCall>::Decodable: - serde::Serialize + serde::de::DeserializeOwned + BorshSerialize + Send + Sync, - - <::NativeRuntime as CliWallet>::CliStringRepr: TryInto< - <::NativeRuntime as DispatchCall>::Decodable, - Error = serde_json::Error, - >, -{ - /// Generates wallet cli for the runtime. - async fn run_wallet( - ) -> Result<(), anyhow::Error> - where - <::NativeRuntime as DispatchCall>::Decodable: - BorshSerialize + BorshDeserialize + Serialize + DeserializeOwned, - File: CliFrontEnd<::NativeRuntime> + CliTxImportArg + Send + Sync, - Json: CliFrontEnd<::NativeRuntime> + CliTxImportArg + Send + Sync, - - File: TryInto< - <::NativeRuntime as CliWallet>::CliStringRepr, - Error = std::io::Error, - >, - Json: TryInto< - <::NativeRuntime as CliWallet>::CliStringRepr, - Error = std::convert::Infallible, - >, - { - let app_dir = wallet_dir()?; - - std::fs::create_dir_all(app_dir.as_ref())?; - let wallet_state_path = app_dir.as_ref().join("wallet_state.json"); - - let mut wallet_state: WalletState< - <::NativeRuntime as DispatchCall>::Decodable, - ::NativeContext, - > = WalletState::load(&wallet_state_path)?; - - let invocation = CliApp::::NativeContext>::parse(); - - match invocation.workflow { - Workflows::Transactions(tx) => tx - .run::<::NativeRuntime, ::NativeContext, JsonStringArg, _, _, _>( - &mut wallet_state, - app_dir, - )?, - Workflows::Keys(inner) => inner.run(&mut wallet_state, app_dir)?, - Workflows::Rpc(inner) => { - inner.run(&mut wallet_state, app_dir).await?; - } - } - - wallet_state.save(wallet_state_path) - } -} diff --git a/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/Cargo.toml b/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/Cargo.toml index 6c0dd2da8..cb251b7a6 100644 --- a/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/Cargo.toml +++ b/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/Cargo.toml @@ -20,22 +20,14 @@ jmt = { workspace = true } jsonrpsee = { workspace = true, features = ["server"], optional = true } rs_merkle = { workspace = true } serde = { workspace = true, features = ["derive"] } -thiserror = { workspace = true } tracing = { workspace = true, optional = true } -# Risc0 deps -risc0-zkvm = { workspace = true, default-features = false, features = ["std"], optional = true } -risc0-zkvm-platform = { workspace = true, optional = true } - # Sovereign-SDK deps sov-modules-api = { path = "../sov-modules-api", default-features = false } sov-rollup-interface = { path = "../../rollup-interface" } sov-state = { path = "../sov-state" } -sov-zk-cycle-macros = { path = "../../utils/zk-cycle-macros", optional = true } -sov-zk-cycle-utils = { path = "../../utils/zk-cycle-utils", optional = true } [features] -bench = ["sov-zk-cycle-macros", "risc0-zkvm", "risc0-zkvm-platform"] default = [] native = [ "sov-state/native", @@ -44,11 +36,3 @@ native = [ "dep:tracing", "jsonrpsee", ] - -[package.metadata.cargo-udeps.ignore] -normal = [ - "risc0-zkvm", - "risc0-zkvm-platform", - "sov-zk-cycle-macros", - "sov-zk-cycle-utils", -] diff --git a/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/src/batch.rs b/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/src/batch.rs deleted file mode 100644 index c5ffd7a56..000000000 --- a/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/src/batch.rs +++ /dev/null @@ -1,11 +0,0 @@ -use borsh::{BorshDeserialize, BorshSerialize}; -use serde::{Deserialize, Serialize}; - -use crate::tx_verifier::RawTx; - -/// Contains raw transactions obtained from the DA blob. -#[derive(Debug, PartialEq, Clone, BorshDeserialize, BorshSerialize, Serialize, Deserialize)] -pub struct Batch { - /// Raw transactions. - pub txs: Vec, -} diff --git a/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/src/lib.rs b/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/src/lib.rs index cc3904498..ce498ed0a 100644 --- a/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/src/lib.rs +++ b/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/src/lib.rs @@ -27,13 +27,9 @@ use sov_rollup_interface::stf::{ use sov_rollup_interface::zk::CumulativeStateDiff; use sov_state::Storage; -mod batch; mod stf_blueprint; -mod tx_verifier; -pub use batch::Batch; pub use stf_blueprint::StfBlueprint; -pub use tx_verifier::RawTx; /// The tx hook for a blueprint runtime pub struct RuntimeTxHook { diff --git a/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/src/tx_verifier.rs b/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/src/tx_verifier.rs deleted file mode 100644 index 85eeee836..000000000 --- a/crates/sovereign-sdk/module-system/sov-modules-stf-blueprint/src/tx_verifier.rs +++ /dev/null @@ -1,9 +0,0 @@ -use borsh::{BorshDeserialize, BorshSerialize}; -use serde::{Deserialize, Serialize}; - -/// RawTx represents a serialized rollup transaction received from the DA. -#[derive(Debug, PartialEq, Clone, BorshDeserialize, BorshSerialize, Serialize, Deserialize, Eq)] -pub struct RawTx { - /// Serialized transaction. - pub data: Vec, -} diff --git a/crates/sovereign-sdk/module-system/sov-state/.gitignore b/crates/sovereign-sdk/module-system/sov-state/.gitignore deleted file mode 100644 index 4fffb2f89..000000000 --- a/crates/sovereign-sdk/module-system/sov-state/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target -/Cargo.lock diff --git a/crates/sovereign-sdk/module-system/sov-state/Cargo.toml b/crates/sovereign-sdk/module-system/sov-state/Cargo.toml index 742cb8de0..80487274a 100644 --- a/crates/sovereign-sdk/module-system/sov-state/Cargo.toml +++ b/crates/sovereign-sdk/module-system/sov-state/Cargo.toml @@ -19,21 +19,12 @@ bcs = { workspace = true } proptest = { workspace = true, optional = true } proptest-derive = { workspace = true, optional = true } serde = { workspace = true, features = ["rc"] } -serde_json = { workspace = true } -thiserror = { workspace = true } sov-rollup-interface = { path = "../../rollup-interface" } sov-modules-core = { path = "../sov-modules-core" } sov-db = { path = "../../full-node/db/sov-db", optional = true } jmt = { workspace = true } -hex = { workspace = true } sha2 = { workspace = true } -sov-zk-cycle-macros = { path = "../../utils/zk-cycle-macros", optional = true } -risc0-zkvm = { workspace = true, default-features = false, features = [ - "std", -], optional = true } -risc0-zkvm-platform = { workspace = true, optional = true } - [dev-dependencies] tempfile = { workspace = true } proptest = { workspace = true } @@ -45,9 +36,5 @@ arbitrary = [ "dep:proptest-derive", "sov-modules-core/arbitrary", ] -bench = ["sov-zk-cycle-macros", "risc0-zkvm", "risc0-zkvm-platform"] default = [] native = ["sov-db"] - -[package.metadata.cargo-udeps.ignore] -normal = ["risc0-zkvm", "risc0-zkvm-platform", "sov-zk-cycle-macros"] diff --git a/crates/sovereign-sdk/module-system/sov-state/src/codec/json_codec.rs b/crates/sovereign-sdk/module-system/sov-state/src/codec/json_codec.rs deleted file mode 100644 index 4aed63349..000000000 --- a/crates/sovereign-sdk/module-system/sov-state/src/codec/json_codec.rs +++ /dev/null @@ -1,45 +0,0 @@ -use serde_json; - -use super::{StateCodec, StateKeyCodec}; -use crate::codec::StateValueCodec; - -/// A [`StateCodec`] that uses [`serde_json`] for all keys and values. -#[derive(Debug, Default, PartialEq, Eq, Clone, serde::Serialize, serde::Deserialize)] -pub struct JsonCodec; - -impl StateKeyCodec for JsonCodec -where - K: serde::Serialize, -{ - fn encode_key(&self, key: &K) -> Vec { - serde_json::to_vec(key).expect("Failed to serialize key") - } -} - -impl StateValueCodec for JsonCodec -where - V: serde::Serialize + for<'a> serde::Deserialize<'a>, -{ - type Error = serde_json::Error; - - fn encode_value(&self, value: &V) -> Vec { - serde_json::to_vec(value).expect("Failed to serialize value") - } - - fn try_decode_value(&self, bytes: &[u8]) -> Result { - serde_json::from_slice(bytes) - } -} - -impl StateCodec for JsonCodec { - type KeyCodec = Self; - type ValueCodec = Self; - - fn key_codec(&self) -> &Self::KeyCodec { - self - } - - fn value_codec(&self) -> &Self::ValueCodec { - self - } -} diff --git a/crates/sovereign-sdk/module-system/sov-state/src/codec/mod.rs b/crates/sovereign-sdk/module-system/sov-state/src/codec/mod.rs index 3c3ce3984..fb1cc9946 100644 --- a/crates/sovereign-sdk/module-system/sov-state/src/codec/mod.rs +++ b/crates/sovereign-sdk/module-system/sov-state/src/codec/mod.rs @@ -4,12 +4,9 @@ use sov_modules_core::{StateCodec, StateKeyCodec, StateValueCodec}; mod bcs_codec; mod borsh_codec; -mod json_codec; -mod split_codec; pub use bcs_codec::BcsCodec; pub use borsh_codec::BorshCodec; -pub use json_codec::JsonCodec; #[cfg(test)] mod tests { diff --git a/crates/sovereign-sdk/module-system/sov-state/src/codec/split_codec.rs b/crates/sovereign-sdk/module-system/sov-state/src/codec/split_codec.rs deleted file mode 100644 index 2c19b667f..000000000 --- a/crates/sovereign-sdk/module-system/sov-state/src/codec/split_codec.rs +++ /dev/null @@ -1,49 +0,0 @@ -//! This module defines a codec which delegates to one codec for keys and one codec for values. - -use super::{StateCodec, StateKeyCodec, StateValueCodec}; - -/// A [`StateValueCodec`] that uses one pre-existing codec for keys and a different one values. -#[derive(Debug, Default, PartialEq, Eq, Clone)] -pub struct SplitCodec { - /// The codec to use for keys. - pub key_codec: KC, - /// The codec to use for values. - pub value_codec: VC, -} - -impl StateKeyCodec for SplitCodec -where - KC: StateKeyCodec, -{ - fn encode_key(&self, key: &K) -> Vec { - self.key_codec.encode_key(key) - } -} - -impl StateValueCodec for SplitCodec -where - VC: StateValueCodec, -{ - type Error = VC::Error; - - fn encode_value(&self, value: &V) -> Vec { - self.value_codec.encode_value(value) - } - - fn try_decode_value(&self, bytes: &[u8]) -> Result { - self.value_codec.try_decode_value(bytes) - } -} - -impl StateCodec for SplitCodec { - type KeyCodec = KC; - type ValueCodec = VC; - - fn key_codec(&self) -> &Self::KeyCodec { - &self.key_codec - } - - fn value_codec(&self) -> &Self::ValueCodec { - &self.value_codec - } -} diff --git a/crates/sovereign-sdk/module-system/sov-state/src/zk_storage.rs b/crates/sovereign-sdk/module-system/sov-state/src/zk_storage.rs index 8110bb705..0fc7e1ed1 100644 --- a/crates/sovereign-sdk/module-system/sov-state/src/zk_storage.rs +++ b/crates/sovereign-sdk/module-system/sov-state/src/zk_storage.rs @@ -7,11 +7,6 @@ use sov_modules_core::{ OrderedReadsAndWrites, Storage, StorageKey, StorageProof, StorageValue, Witness, }; use sov_rollup_interface::stf::StateDiff; -#[cfg(all(target_os = "zkvm", feature = "bench"))] -use sov_zk_cycle_macros::cycle_tracker; - -#[cfg(all(target_os = "zkvm", feature = "bench"))] -extern crate risc0_zkvm; /// A [`Storage`] implementation designed to be used inside the zkVM. #[derive(Default)] diff --git a/crates/sovereign-sdk/module-system/utils/sov-data-generators/Cargo.toml b/crates/sovereign-sdk/module-system/utils/sov-data-generators/Cargo.toml deleted file mode 100644 index 8f30aba8a..000000000 --- a/crates/sovereign-sdk/module-system/utils/sov-data-generators/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "sov-data-generators" -description = "A set of generator utils used to automatically produce and serialize transaction data" -authors = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -repository = { workspace = true } - -version = { workspace = true } -resolver = "2" -publish = false - - -[dependencies] -sov-modules-api = { path = "../../sov-modules-api", features = ["native"] } -sov-modules-stf-blueprint = { path = "../../sov-modules-stf-blueprint", features = ["native"] } -sov-value-setter = { path = "../../module-implementations/examples/sov-value-setter", features = ["native"] } -sov-bank = { path = "../../module-implementations/sov-bank", features = ["native"] } -sov-state = { path = "../../sov-state" } -sov-mock-da = { path = "../../../adapters/mock-da", features = ["native"] } - -borsh = { workspace = true } - -[dev-dependencies] -proptest = { workspace = true } diff --git a/crates/sovereign-sdk/module-system/utils/sov-data-generators/src/bank_data.rs b/crates/sovereign-sdk/module-system/utils/sov-data-generators/src/bank_data.rs deleted file mode 100644 index 1de62e138..000000000 --- a/crates/sovereign-sdk/module-system/utils/sov-data-generators/src/bank_data.rs +++ /dev/null @@ -1,378 +0,0 @@ -use std::rc::Rc; - -use sov_bank::{get_token_address, Bank, CallMessage, Coins}; -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::utils::generate_address; -use sov_modules_api::{Context, EncodeCall, Module, PrivateKey, Spec}; - -use crate::{Message, MessageGenerator}; - -pub struct TransferData { - pub sender_pkey: Rc, - pub receiver_address: ::Address, - pub token_address: ::Address, - pub transfer_amount: u64, -} - -pub struct MintData { - pub token_name: String, - pub salt: u64, - pub initial_balance: u64, - pub minter_address: ::Address, - pub minter_pkey: Rc, - pub authorized_minters: Vec<::Address>, -} - -pub struct BankMessageGenerator { - pub token_mint_txs: Vec>, - pub transfer_txs: Vec>, -} - -const DEFAULT_TOKEN_NAME: &str = "Token1"; -const DEFAULT_SALT: u64 = 10; -const DEFAULT_PVT_KEY: &str = "236e80cb222c4ed0431b093b3ac53e6aa7a2273fe1f4351cd354989a823432a27b758bf2e7670fafaf6bf0015ce0ff5aa802306fc7e3f45762853ffc37180fe6"; -const DEFAULT_CHAIN_ID: u64 = 0; - -pub fn get_default_token_address() -> ::Address { - let minter_key = DefaultPrivateKey::from_hex(DEFAULT_PVT_KEY).unwrap(); - let minter_address = minter_key.default_address(); - let salt = DEFAULT_SALT; - let token_name = DEFAULT_TOKEN_NAME.to_owned(); - get_token_address::(&token_name, minter_address.as_ref(), salt) -} - -pub fn get_default_private_key() -> DefaultPrivateKey { - DefaultPrivateKey::from_hex(DEFAULT_PVT_KEY).unwrap() -} - -impl Default for BankMessageGenerator { - fn default() -> Self { - let minter_key = DefaultPrivateKey::from_hex(DEFAULT_PVT_KEY).unwrap(); - let minter_address = minter_key.default_address(); - let salt = DEFAULT_SALT; - let token_name = DEFAULT_TOKEN_NAME.to_owned(); - let mint_data = MintData { - token_name: token_name.clone(), - salt, - initial_balance: 1000, - minter_address, - minter_pkey: Rc::new(minter_key), - authorized_minters: Vec::from([minter_address]), - }; - Self { - token_mint_txs: Vec::from([mint_data]), - transfer_txs: Vec::from([TransferData { - sender_pkey: Rc::new(DefaultPrivateKey::from_hex(DEFAULT_PVT_KEY).unwrap()), - transfer_amount: 15, - receiver_address: generate_address::("just_receiver"), - token_address: get_token_address::( - &token_name, - minter_address.as_ref(), - salt, - ), - }]), - } - } -} - -impl BankMessageGenerator { - pub fn create_invalid_transfer() -> Self { - let minter_key = DefaultPrivateKey::from_hex(DEFAULT_PVT_KEY).unwrap(); - let minter_address = minter_key.default_address(); - let salt = DEFAULT_SALT; - let token_name = DEFAULT_TOKEN_NAME.to_owned(); - let mint_data = MintData { - token_name: token_name.clone(), - salt, - initial_balance: 1000, - minter_address, - minter_pkey: Rc::new(minter_key), - authorized_minters: Vec::from([minter_address]), - }; - Self { - token_mint_txs: Vec::from([mint_data]), - transfer_txs: Vec::from([ - TransferData { - sender_pkey: Rc::new(DefaultPrivateKey::from_hex(DEFAULT_PVT_KEY).unwrap()), - transfer_amount: 15, - receiver_address: generate_address::("just_receiver"), - token_address: get_token_address::( - &token_name, - minter_address.as_ref(), - salt, - ), - }, - TransferData { - sender_pkey: Rc::new(DefaultPrivateKey::from_hex(DEFAULT_PVT_KEY).unwrap()), - // invalid transfer because transfer_amount > minted supply - transfer_amount: 5000, - receiver_address: generate_address::("just_receiver"), - token_address: get_token_address::( - &token_name, - minter_address.as_ref(), - salt, - ), - }, - ]), - } - } -} - -pub(crate) fn mint_token_tx(mint_data: &MintData) -> CallMessage { - CallMessage::CreateToken { - salt: mint_data.salt, - token_name: mint_data.token_name.clone(), - initial_balance: mint_data.initial_balance, - minter_address: mint_data.minter_address.clone(), - authorized_minters: mint_data.authorized_minters.clone(), - } -} - -pub(crate) fn transfer_token_tx(transfer_data: &TransferData) -> CallMessage { - CallMessage::Transfer { - to: transfer_data.receiver_address.clone(), - coins: Coins { - amount: transfer_data.transfer_amount, - token_address: transfer_data.token_address.clone(), - }, - } -} - -impl MessageGenerator for BankMessageGenerator { - type Module = Bank; - type Context = C; - - fn create_messages(&self) -> Vec> { - let mut messages = Vec::>>::new(); - - let mut nonce = 0; - - for mint_message in &self.token_mint_txs { - messages.push(Message::new( - mint_message.minter_pkey.clone(), - mint_token_tx::(mint_message), - DEFAULT_CHAIN_ID, - nonce, - )); - nonce += 1; - } - - for transfer_message in &self.transfer_txs { - messages.push(Message::new( - transfer_message.sender_pkey.clone(), - transfer_token_tx::(transfer_message), - DEFAULT_CHAIN_ID, - nonce, - )); - nonce += 1; - } - - messages - } - - fn create_tx>( - &self, - sender: &::PrivateKey, - message: ::CallMessage, - chain_id: u64, - nonce: u64, - _is_last: bool, - ) -> sov_modules_api::transaction::Transaction { - let message = Encoder::encode_call(message); - Transaction::::new_signed_tx(sender, message, chain_id, nonce) - } -} - -pub struct BadSerializationBankCallMessages; - -impl BadSerializationBankCallMessages { - pub fn new() -> Self { - Self {} - } -} - -impl Default for BadSerializationBankCallMessages { - fn default() -> Self { - Self::new() - } -} - -impl MessageGenerator for BadSerializationBankCallMessages { - type Module = Bank; - type Context = DefaultContext; - - fn create_messages(&self) -> Vec> { - let mut messages = Vec::>>::new(); - let minter_key = DefaultPrivateKey::from_hex(DEFAULT_PVT_KEY).unwrap(); - let minter_address = minter_key.default_address(); - let salt = DEFAULT_SALT; - let token_name = DEFAULT_TOKEN_NAME.to_owned(); - messages.push(Message::new( - Rc::new(DefaultPrivateKey::from_hex(DEFAULT_PVT_KEY).unwrap()), - CallMessage::CreateToken { - salt, - token_name, - initial_balance: 1000, - minter_address, - authorized_minters: Vec::from([minter_address]), - }, - DEFAULT_CHAIN_ID, - 0, - )); - messages.push(Message::new( - Rc::new(DefaultPrivateKey::from_hex(DEFAULT_PVT_KEY).unwrap()), - CallMessage::Transfer { - to: generate_address::("just_receiver"), - coins: Coins { - amount: 50, - token_address: get_default_token_address(), - }, - }, - DEFAULT_CHAIN_ID, - 0, - )); - messages - } - - fn create_tx>( - &self, - sender: &DefaultPrivateKey, - message: as Module>::CallMessage, - chain_id: u64, - nonce: u64, - is_last: bool, - ) -> Transaction { - // just some random bytes that won't deserialize to a valid txn - let call_data = if is_last { - vec![1, 2, 3] - } else { - Encoder::encode_call(message) - }; - - Transaction::::new_signed_tx(sender, call_data, chain_id, nonce) - } -} - -pub struct BadSignatureBankCallMessages; - -impl BadSignatureBankCallMessages { - pub fn new() -> Self { - Self {} - } -} - -impl Default for BadSignatureBankCallMessages { - fn default() -> Self { - Self::new() - } -} - -impl MessageGenerator for BadSignatureBankCallMessages { - type Module = Bank; - type Context = DefaultContext; - - fn create_messages(&self) -> Vec> { - let mut messages = Vec::>>::new(); - let minter_key = DefaultPrivateKey::from_hex(DEFAULT_PVT_KEY).unwrap(); - let minter_address = minter_key.default_address(); - let salt = DEFAULT_SALT; - let token_name = DEFAULT_TOKEN_NAME.to_owned(); - messages.push(Message::new( - Rc::new(DefaultPrivateKey::from_hex(DEFAULT_PVT_KEY).unwrap()), - CallMessage::CreateToken { - salt, - token_name, - initial_balance: 1000, - minter_address, - authorized_minters: Vec::from([minter_address]), - }, - DEFAULT_CHAIN_ID, - 0, - )); - messages - } - - fn create_tx>( - &self, - sender: &DefaultPrivateKey, - message: as Module>::CallMessage, - chain_id: u64, - nonce: u64, - is_last: bool, - ) -> Transaction { - let call_data = Encoder::encode_call(message); - - if is_last { - let tx = Transaction::::new_signed_tx( - sender, - call_data.clone(), - chain_id, - nonce, - ); - Transaction::new( - DefaultPrivateKey::generate().pub_key(), - call_data, - tx.signature().clone(), - chain_id, - nonce, - ) - } else { - Transaction::::new_signed_tx(sender, call_data, chain_id, nonce) - } - } -} - -pub struct BadNonceBankCallMessages; - -impl BadNonceBankCallMessages { - pub fn new() -> Self { - Self {} - } -} - -impl Default for BadNonceBankCallMessages { - fn default() -> Self { - Self::new() - } -} - -impl MessageGenerator for BadNonceBankCallMessages { - type Module = Bank; - type Context = DefaultContext; - - fn create_messages(&self) -> Vec> { - let mut messages = Vec::>>::new(); - let minter_key = DefaultPrivateKey::from_hex(DEFAULT_PVT_KEY).unwrap(); - let minter_address = minter_key.default_address(); - let salt = DEFAULT_SALT; - let token_name = DEFAULT_TOKEN_NAME.to_owned(); - messages.push(Message::new( - Rc::new(DefaultPrivateKey::from_hex(DEFAULT_PVT_KEY).unwrap()), - CallMessage::CreateToken { - salt, - token_name, - initial_balance: 1000, - minter_address, - authorized_minters: Vec::from([minter_address]), - }, - DEFAULT_CHAIN_ID, - 0, - )); - messages - } - - fn create_tx>( - &self, - sender: &DefaultPrivateKey, - message: as Module>::CallMessage, - chain_id: u64, - _nonce: u64, - _is_last: bool, - ) -> Transaction { - let message = Encoder::encode_call(message); - // hard-coding the nonce to 1000 - Transaction::::new_signed_tx(sender, message, chain_id, 1000) - } -} diff --git a/crates/sovereign-sdk/module-system/utils/sov-data-generators/src/lib.rs b/crates/sovereign-sdk/module-system/utils/sov-data-generators/src/lib.rs deleted file mode 100644 index 6b10e5598..000000000 --- a/crates/sovereign-sdk/module-system/utils/sov-data-generators/src/lib.rs +++ /dev/null @@ -1,111 +0,0 @@ -use std::rc::Rc; - -use sov_mock_da::verifier::MockDaSpec; -use sov_mock_da::{MockAddress, MockBlob}; -use sov_modules_api::transaction::Transaction; -pub use sov_modules_api::EncodeCall; -use sov_modules_api::{Context, DaSpec, Module, RollupAddress, Spec}; -use sov_modules_stf_blueprint::{Batch, BatchReceipt, RawTx, TxEffect}; - -pub mod bank_data; -pub mod value_setter_data; - -pub fn new_test_blob_from_batch( - batch: Batch, - address: &[u8], - hash: [u8; 32], -) -> ::BlobTransaction { - let address = MockAddress::try_from(address).unwrap(); - let data = borsh::to_vec(&batch).unwrap(); - MockBlob::new(data, address, hash) -} - -pub fn has_tx_events( - apply_blob_outcome: &BatchReceipt, TxEffect>, -) -> bool { - let events = apply_blob_outcome - .tx_receipts - .iter() - .flat_map(|receipts| receipts.events.iter()); - - events.peekable().peek().is_some() -} - -/// A generic message object used to create transactions. -pub struct Message { - /// The sender's private key. - pub sender_key: Rc<::PrivateKey>, - /// The message content. - pub content: Mod::CallMessage, - /// The ID of the chain. - pub chain_id: u64, - /// The message nonce. - pub nonce: u64, -} - -impl Message { - fn new( - sender_key: Rc<::PrivateKey>, - content: Mod::CallMessage, - chain_id: u64, - nonce: u64, - ) -> Self { - Self { - sender_key, - content, - chain_id, - nonce, - } - } -} - -/// Trait used to generate messages from the DA layer to automate module testing -pub trait MessageGenerator { - /// Module where the messages originate from. - type Module: Module; - - /// Module context - type Context: Context; - - /// Generates a list of messages originating from the module. - fn create_messages(&self) -> Vec>; - - /// Creates a transaction object associated with a call message, for a given module. - #[allow(clippy::too_many_arguments)] - fn create_tx>( - &self, - // Private key of the sender - sender: &::PrivateKey, - // The message itself - message: ::CallMessage, - // The ID of the chain - chain_id: u64, - // The message nonce - nonce: u64, - // A boolean that indicates whether this message is the last one to be sent. - // Useful to perform some operations specifically on the last message. - is_last: bool, - ) -> Transaction; - - /// Creates a vector of raw transactions from the module. - fn create_raw_txs>(&self) -> Vec { - let mut messages_iter = self.create_messages().into_iter().peekable(); - let mut serialized_messages = Vec::default(); - while let Some(message) = messages_iter.next() { - let is_last = messages_iter.peek().is_none(); - - let tx = self.create_tx::( - &message.sender_key, - message.content, - message.chain_id, - message.nonce, - is_last, - ); - - serialized_messages.push(RawTx { - data: borsh::to_vec(&tx).unwrap(), - }) - } - serialized_messages - } -} diff --git a/crates/sovereign-sdk/module-system/utils/sov-data-generators/src/value_setter_data.rs b/crates/sovereign-sdk/module-system/utils/sov-data-generators/src/value_setter_data.rs deleted file mode 100644 index 3dfdfe2ae..000000000 --- a/crates/sovereign-sdk/module-system/utils/sov-data-generators/src/value_setter_data.rs +++ /dev/null @@ -1,75 +0,0 @@ -use std::vec; - -use sov_modules_api::default_context::DefaultContext; -use sov_modules_api::default_signature::private_key::DefaultPrivateKey; -use sov_modules_api::PrivateKey; -use sov_value_setter::ValueSetter; - -use super::*; -use crate::EncodeCall; - -const DEFAULT_CHAIN_ID: u64 = 0; - -pub struct ValueSetterMessage { - pub admin: Rc, - pub messages: Vec, -} - -pub struct ValueSetterMessages { - pub messages: Vec>, -} - -impl ValueSetterMessages { - pub fn new(messages: Vec>) -> Self { - Self { messages } - } -} - -impl Default for ValueSetterMessages { - /// This function will return a dummy value setter message containing one admin and two value setter messages. - fn default() -> Self { - Self::new(vec![ValueSetterMessage { - admin: Rc::new(DefaultPrivateKey::generate()), - messages: vec![99, 33], - }]) - } -} - -impl MessageGenerator for ValueSetterMessages { - type Module = ValueSetter; - type Context = C; - - fn create_messages(&self) -> Vec> { - let mut messages = Vec::default(); - for value_setter_message in &self.messages { - let admin = value_setter_message.admin.clone(); - - for (value_setter_admin_nonce, new_value) in - value_setter_message.messages.iter().enumerate() - { - let set_value_msg: sov_value_setter::CallMessage = - sov_value_setter::CallMessage::SetValue(*new_value); - - messages.push(Message::new( - admin.clone(), - set_value_msg, - DEFAULT_CHAIN_ID, - value_setter_admin_nonce.try_into().unwrap(), - )); - } - } - messages - } - - fn create_tx>( - &self, - sender: &C::PrivateKey, - message: ::CallMessage, - chain_id: u64, - nonce: u64, - _is_last: bool, - ) -> Transaction { - let message = Encoder::encode_call(message); - Transaction::::new_signed_tx(sender, message, chain_id, nonce) - } -} diff --git a/crates/sovereign-sdk/scripts/blockscout/.env b/crates/sovereign-sdk/scripts/blockscout/.env deleted file mode 100644 index 12e1817e8..000000000 --- a/crates/sovereign-sdk/scripts/blockscout/.env +++ /dev/null @@ -1,8 +0,0 @@ -DATABASE_URL="postgresql://postgres:foobar@localhost:5432/blockscout" -ETHEREUM_JSONRPC_HTTP_URL="http://127.0.0.1:12345" -ETHEREUM_JSONRPC_VARIANT="ganache" -COIN="sovereign" -MIX_ENV="dev" -MICROSERVICE_SC_VERIFIER_URL="http://0.0.0.0:8050/" -DISABLE_INDEXER="false" -LOG_LEVEL="trace" diff --git a/crates/sovereign-sdk/scripts/check_missing_dependency_versions.sh b/crates/sovereign-sdk/scripts/check_missing_dependency_versions.sh deleted file mode 100755 index 1cc9f4ac5..000000000 --- a/crates/sovereign-sdk/scripts/check_missing_dependency_versions.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -# `cargo-publish` requires all dependencies to have a version specified (e.g. it -# can't be sourced from `git` of `path` alone). This script checks that all -# packages we intend to publish have a version specified in their `Cargo.toml` for all -# dependencies. - -set -Euo pipefail - -yq '.[]' packages_to_publish.yml | while read -r pkg; do - echo "Checking crate $pkg..." - - output=$(cargo publish --allow-dirty --dry-run -p "$pkg") - - # Check if the output contains the error message we're looking for. - # - # `cargo publish` may fail for many other reasons, but it'd be too - # hard to reason about them all. This is the only one we can expect - # to catch reliably. - echo "$output" | grep -q "all dependencies must have a version specified when publishing." - if [ $? -eq 0 ]; then - echo "Error: Found problematic output for crate $pkg." - exit 1 - fi -done - -echo "All crates processed successfully." diff --git a/crates/sovereign-sdk/scripts/retesteth/README.md b/crates/sovereign-sdk/scripts/retesteth/README.md deleted file mode 100644 index b0f734a77..000000000 --- a/crates/sovereign-sdk/scripts/retesteth/README.md +++ /dev/null @@ -1 +0,0 @@ -`config.json` is the WIP configuration file for using `retesteth` with `citrea-evm`. It's based on the configuration options of `evmone` and must be extensively updated to work with `citrea-evm`, it's broken as of now. Nonetheless, it's committed into version control to share progress across `citrea-evm` maintainers. diff --git a/crates/sovereign-sdk/scripts/retesteth/config.json b/crates/sovereign-sdk/scripts/retesteth/config.json deleted file mode 100644 index 606edb87d..000000000 --- a/crates/sovereign-sdk/scripts/retesteth/config.json +++ /dev/null @@ -1,267 +0,0 @@ -{ - "name": "EVMONE on StateTool", - "socketType": "tranition-tool", - "socketAddress": "start.sh", - "initializeTime": "0", - "checkDifficulty": true, - "calculateDifficulty": false, - "checkBasefee": true, - "calculateBasefee": false, - "checkLogsHash": true, - "support1559": true, - "supportBigint": false, - "transactionsAsJson": true, - "tmpDir": "/dev/shm", - "defaultChainID": 1, - "customCompilers": { - ":yul": "yul.sh" - }, - "forks": [ - "Frontier", - "Homestead", - "EIP150", - "EIP158", - "Byzantium", - "Constantinople", - "ConstantinopleFix", - "Istanbul", - "Berlin", - "London", - "Merge", - "Shanghai" - ], - "additionalForks": [ - "FrontierToHomesteadAt5", - "HomesteadToEIP150At5", - "EIP158ToByzantiumAt5", - "HomesteadToDaoAt5", - "ByzantiumToConstantinopleFixAt5", - "BerlinToLondonAt5", - "ArrowGlacier", - "ArrowGlacierToMergeAtDiffC0000", - "GrayGlacier", - "MergeToShanghaiAtTime15k" - ], - "fillerSkipForks": [], - "exceptions": { - "PYSPECS_EXCEPTIONS": "", - "Transaction without funds": "insufficient funds for gas * price + value", - "AddressTooShort": "input string too short for common.Address", - "AddressTooLong": "rlp: input string too long for common.Address, decoding into (types.Transaction)(types.LegacyTx).To", - "NonceMax": "nonce exceeds 2^64-1", - "NonceTooLong": "rlp: input string too long for uint64, decoding into (types.Transaction)(types.LegacyTx).Nonce", - "InvalidVRS": "invalid transaction v, r, s values", - "InvalidV": "rlp: expected input string or byte for *big.Int, decoding into (types.Transaction)(types.LegacyTx).V", - "InvalidR": "rlp: expected input string or byte for *big.Int, decoding into (types.Transaction)(types.LegacyTx).R", - "InvalidS": "rlp: expected input string or byte for *big.Int, decoding into (types.Transaction)(types.LegacyTx).S", - "InvalidChainID": "invalid chain id for signer", - "ECRecoveryFail": "recovery failed", - "ExtraDataTooBig": "Error importing raw rlp block: Header extraData > 32 bytes", - "InvalidData": "rlp: expected input string or byte for []uint8, decoding into (types.Transaction)(types.LegacyTx).Data", - "InvalidDifficulty": "Invalid difficulty:", - "InvalidDifficulty2": "Error in field: difficulty", - "InvalidWithdrawals": "Error in field: withdrawalsRoot", - "InvalidDifficulty_TooLarge": "Blockheader parse error: VALUE >u256", - "InvalidGasLimit": "Header gasLimit > 0x7fffffffffffffff", - "InvalidGasLimit2": "Invalid gaslimit:", - "InvalidGasLimit3": "GasLimit must be < 0x7fffffffffffffff", - "InvalidGasLimit4": "rlp: input string too long for uint64, decoding into (types.Transaction)(types.LegacyTx).Gas", - "InvalidGasLimit5": "rlp: expected input string or byte for uint64, decoding into (types.Transaction)(types.LegacyTx).Gas", - "InvalidValue": "value exceeds 256 bits", - "InvalidGasPrice": "gasPrice exceeds 256 bits", - "InvalidMaxPriorityFeePerGas": "maxPriorityFeePerGas exceeds 256 bits", - "InvalidMaxFeePerGas": "maxFeePerGas exceeds 256 bits", - "InvalidNonce": "rlp: expected input string or byte for uint64, decoding into (types.Transaction)(types.LegacyTx).Nonce", - "InvalidTo": "rlp: expected input string or byte for common.Address, decoding into (types.Transaction)(types.LegacyTx).To", - "GasLimitPriceProductOverflow": "gas * gasPrice exceeds 256 bits", - "TooMuchGasUsed": "Invalid gasUsed:", - "TooMuchGasUsed2": "Error importing raw rlp block: t8ntool didn't return a transaction with hash", - "LeadingZerosGasLimit": "rlp: non-canonical integer (leading zero bytes) for uint64, decoding into (types.Transaction)(types.LegacyTx).Gas", - "LeadingZerosGasPrice": "rlp: non-canonical integer (leading zero bytes) for *big.Int, decoding into (types.Transaction)(types.LegacyTx).GasPrice", - "LeadingZerosValue": "rlp: non-canonical integer (leading zero bytes) for *big.Int, decoding into (types.Transaction)(types.LegacyTx).Value", - "LeadingZerosNonce": "rlp: non-canonical integer (leading zero bytes) for uint64, decoding into (types.Transaction)(types.LegacyTx).Nonce", - "LeadingZerosR": "rlp: non-canonical integer (leading zero bytes) for *big.Int, decoding into (types.Transaction)(types.LegacyTx).R", - "LeadingZerosS": "rlp: non-canonical integer (leading zero bytes) for *big.Int, decoding into (types.Transaction)(types.LegacyTx).S", - "LeadingZerosV": "rlp: non-canonical integer (leading zero bytes) for *big.Int, decoding into (types.Transaction)(types.LegacyTx).V", - "LeadingZerosDataSize": "rlp: non-canonical size information for []uint8, decoding into (types.Transaction)(types.LegacyTx).Data", - "LeadingZerosNonceSize": "rlp: non-canonical size information for uint64, decoding into (types.Transaction)(types.LegacyTx).Nonce", - "InvalidNumber": "BlockHeader number != parent.number + 1", - "InvalidTimestampEqualParent": "timestamp equals parent's", - "InvalidTimestampOlderParent": "BlockHeader timestamp is less or equal then it's parent block!", - "InvalidLogBloom": "Error in field: bloom", - "InvalidStateRoot": "Error in field: stateRoot", - "InvalidGasUsed": "Error in field: gasUsed", - "InvalidGasUsed2": "t8ntool didn't return a transaction with hash", - "InvalidBlockMixHash": "invalid mix digest", - "InvalidBlockNonce": "", - "UnknownParent": "unknown parent hash", - "UnknownParent2": "unknown parent hash", - "InvalidReceiptsStateRoot": "Error in field: receiptTrie", - "InvalidTransactionsRoot": "Error in field: transactionsTrie", - "InvalidUnclesHash": "Error in field: uncleHash", - "InvalidUncleParentHash": "Parent block hash not found:", - "UncleInChain": "Block is already in chain!", - "UncleIsAncestor": "Block is already in chain!", - "UncleParentIsNotAncestor": "Uncle number is wrong!", - "TooManyUncles": "Too many uncles!", - "UncleIsBrother": "Uncle is brother!", - "OutOfGas": "out of gas", - "SenderNotEOA": "sender not an eoa:", - "IntrinsicGas": "intrinsic gas too low:", - "ExtraDataIncorrectDAO": "BlockHeader require Dao ExtraData!", - "InvalidTransactionVRS": "t8ntool didn't return a transaction with hash", - "BLOCKHEADER_VALUE_TOOLARGE": "Blockheader parse error: VALUE >u256", - "TRANSACTION_VALUE_TOOLARGE": "TransactionLegacy convertion error: VALUE >u256", - "TRANSACTION_VALUE_TOOSHORT": "t8ntool didn't return a transaction with hash", - "TR_NonceHasMaxValue": "nonce has max value:", - "OVERSIZE_RLP": "Error importing raw rlp block: OversizeRLP", - "RLP_BadCast": "BadCast", - "RLP_ExpectedAsList": "expected to be list", - "RLP_TooFewElements": "rlp: too few elements ", - "RLP_TooManyElements": "rlp: input list has too many elements ", - "RLP_InputContainsMoreThanOneValue": "Error importing raw rlp block: OversizeRLP", - "RLP_VALUESIZE_MORE_AVAILABLEINPUTLENGTH": "Error importing raw rlp block: UndersizeRLP", - "RLP_ELEMENT_LARGER_CONTAININGLIST_UNDERSIZE": "Error importing raw rlp block: UndersizeRLP", - "RLP_ELEMENT_LARGER_CONTAININGLIST_OVERSIZE": "Error importing raw rlp block: OversizeRLP", - "RLP_ExpectedInputList_EXTBLOCK": "Error importing raw rlp block: RLP is expected to be list", - "RLP_InvalidArg0_UNMARSHAL_BYTES": "Error importing raw rlp block: BadCast", - "RLP_ExpectedInputList_HEADER_DECODEINTO_BLOCK_EXTBLOCK": "Error importing raw rlp block: BlockHeader RLP is expected to be list", - "RLP_InputList_TooManyElements_HEADER_DECODEINTO_BLOCK_EXTBLOCK_HEADER": "Error importing raw rlp block: Uncleheader RLP is expected to be list", - "RLP_InputList_TooManyElements_TXDATA_DECODEINTO_BLOCK_EXTBLOCK_TXS0": "Error importing raw rlp block: OversizeRLP", - "RLP_InputString_TooShort_ADDRESS_DECODEINTO_BLOCK_EXTBLOCK_HEADER_COINBASE": "Error importing raw rlp block: OversizeRLP", - "RLP_InputString_TooShort_ADDRESS_DECODEINTO_BLOCK_EXTBLOCK_HEADER_COINBASE2": "Blockheader parse error: Key `coinbase` is not hash20", - "RLP_InputString_TooShort_ADDRESS_DECODEINTO_BLOCK_EXTBLOCK_TXS0_RECIPIENT": "TransactionLegacy convertion error: Key `to` is not hash20", - "RLP_InputString_TooLong_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_ROOT": "Error importing raw rlp block: OversizeRLP", - "RLP_InputString_TooLong_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_ROOT2": "Blockheader parse error: Key `stateRoot` is not hash32", - "RLP_InputString_TooLong_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_MIXDIGEST": "Error importing raw rlp block: OversizeRLP", - "RLP_InputString_TooLong_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_MIXDIGEST2": "Blockheader parse error: Key `mixHash` is not hash32", - "RLP_InputString_TooLong_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_PARENTHASH": "Error importing raw rlp block: OversizeRLP", - "RLP_InputString_TooLong_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_PARENTHASH2": "Blockheader parse error: Key `parentHash` is not hash32", - "RLP_InputString_TooLong_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_RECEIPTHASH": "Error importing raw rlp block: OversizeRLP", - "RLP_InputString_TooLong_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_RECEIPTHASH2": "Blockheader parse error: Key `receiptTrie` is not hash32", - "RLP_InputString_TooLong_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_TXHASH": "Blockheader parse error: Key `transactionsTrie` is not hash32", - "RLP_InputString_TooLong_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_UNCLEHASH": "Error importing raw rlp block: OversizeRLP", - "RLP_InputString_TooLong_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_UNCLEHASH2": "Blockheader parse error: Key `uncleHash` is not hash32", - "RLP_InputString_TooLong_UINT64_DECODEINTO_BLOCK_EXTBLOCK_HEADER_GASLIMIT": "Blockheader parse error: VALUE >u256", - "RLP_InputString_TooLong_UINT64_DECODEINTO_BLOCK_EXTBLOCK_HEADER_GASUSED": "Blockheader parse error: VALUE >u256", - "RLP_InputString_TooLong_UINT64_DECODEINTO_BLOCK_EXTBLOCK_HEADER_TIME": "Blockheader parse error: VALUE >u256", - "RLP_InputString_TooLong_UINT64_DECODEINTO_BLOCK_EXTBLOCK_TXS0_GASLIMIT": "TransactionLegacy convertion error: VALUE >u256", - "RLP_InputString_TooShort_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_RECEIPTHASH": "Error importing raw rlp block: OversizeRLP", - "RLP_InputString_TooShort_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_RECEIPTHASH2": "Blockheader parse error: Key `receiptTrie` is not hash32", - "RLP_InputString_TooShort_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_ROOT": "Blockheader parse error: Key `stateRoot` is not hash32", - "RLP_InputString_TooShort_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_MIXDIGEST": "Error importing raw rlp block: OversizeRLP", - "RLP_InputString_TooShort_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_MIXDIGEST2": "Blockheader parse error: Key `mixHash` is not hash32", - "RLP_InputString_TooShort_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_PARENTHASH": "Error importing raw rlp block: OversizeRLP", - "RLP_InputString_TooShort_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_PARENTHASH2": "Blockheader parse error: Key `parentHash` is not hash32", - "RLP_InputString_TooShort_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_UNCLEHASH": "Error importing raw rlp block: OversizeRLP", - "RLP_InputString_TooShort_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_UNCLEHASH2": "Blockheader parse error: Key `uncleHash` is not hash32", - "RLP_InputString_TooShort_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_TXHASH": "Error importing raw rlp block: OversizeRLP", - "RLP_InputString_TooShort_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_TXHASH2": "Blockheader parse error: Key `transactionsTrie` is not hash32", - "RLP_InputString_TooShort_BLOOM_DECODEINTO_BLOCK_EXTBLOCK_HEADER_BLOOM": "Error importing raw rlp block: OversizeRLP", - "RLP_NonCanonicalINT_LeadingZeros_BIGINT_DECODEINTO_BLOCK_EXTBLOCK_HEADER_DIFFICULTY": "Error importing raw rlp block: OversizeRLP", - "RLP_NonCanonicalINT_LeadingZeros_BIGINT_DECODEINTO_BLOCK_EXTBLOCK_HEADER_DIFFICULTY2": "Blockheader parse error: VALUE has leading 0", - "RLP_NonCanonicalINT_LeadingZeros_UINT64_DECODEINTO_BLOCK_EXTBLOCK_HEADER_GASLIMIT": "Error importing raw rlp block: OversizeRLP", - "RLP_NonCanonicalINT_LeadingZeros_UINT64_DECODEINTO_BLOCK_EXTBLOCK_HEADER_GASLIMIT2": "Blockheader parse error: VALUE has leading 0", - "RLP_NonCanonicalINT_LeadingZeros_UINT64_DECODEINTO_BLOCK_EXTBLOCK_HEADER_GASUSED": "Error importing raw rlp block: OversizeRLP", - "RLP_NonCanonicalINT_LeadingZeros_UINT64_DECODEINTO_BLOCK_EXTBLOCK_HEADER_GASUSED2": "Blockheader parse error: VALUE has leading 0", - "RLP_NonCanonicalINT_LeadingZeros_UINT64_DECODEINTO_BLOCK_EXTBLOCK_HEADER_TIME": "Error importing raw rlp block: OversizeRLP", - "RLP_NonCanonicalINT_LeadingZeros_UINT64_DECODEINTO_BLOCK_EXTBLOCK_HEADER_TIME2": "Blockheader parse error: VALUE has leading 0", - "RLP_NonCanonicalINT_LeadingZeros_UINT64_DECODEINTO_BLOCK_EXTBLOCK_TXS0_GASLIMIT": "Error importing raw rlp block: OversizeRLP", - "RLP_NonCanonicalINT_LeadingZeros_UINT64_DECODEINTO_BLOCK_EXTBLOCK_TXS0_GASLIMIT2": "TransactionLegacy convertion error: VALUE has leading 0", - "RLP_NonCanonicalINT_LeadingZeros_BIGINT_DECODEINTO_BLOCK_EXTBLOCK_HEADER_NUMBER": "Error importing raw rlp block: OversizeRLP", - "RLP_NonCanonicalINT_LeadingZeros_BIGINT_DECODEINTO_BLOCK_EXTBLOCK_HEADER_NUMBER2": "Error importing raw rlp block: OversizeRLP", - "RLP_NonCanonicalINT_LeadingZeros_BIGINT_DECODEINTO_BLOCK_EXTBLOCK_TXS0_TXDATA_PRICE": "Error importing raw rlp block: OversizeRLP", - "RLP_NonCanonicalINT_LeadingZeros_BIGINT_DECODEINTO_BLOCK_EXTBLOCK_TXS0_TXDATA_R": "TransactionLegacy convertion error: VALUE has leading 0", - "RLP_NonCanonicalINT_LeadingZeros_BIGINT_DECODEINTO_BLOCK_EXTBLOCK_TXS0_TXDATA_S": "TransactionLegacy convertion error: VALUE has leading 0", - "RLP_InputString_TooLong_BLOOM_DECODEINTO_BLOCK_EXTBLOCK_HEADER_BLOOM": "Blockheader parse error: Key `bloom` is not hash256", - "RLP_ExpectedInputString_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_PARENTHASH": "Error importing raw rlp block: Blockheader RLP field is not data!", - "RLP_ExpectedInputString_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_RECEIPTHASH": "Error importing raw rlp block: Blockheader RLP field is not data!", - "RLP_ExpectedInputString_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_ROOT": "Error importing raw rlp block: Blockheader RLP field is not data!", - "RLP_ExpectedInputString_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_MIXDIGEST": "Error importing raw rlp block: Blockheader RLP field is not data!", - "RLP_ExpectedInputString_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_TXHASH": "Error importing raw rlp block: Blockheader RLP field is not data!", - "RLP_ExpectedInputString_HASH_DECODEINTO_BLOCK_EXTBLOCK_HEADER_UNCLEHASH": "Error importing raw rlp block: Blockheader RLP field is not data!", - "RLP_ExpectedInputString_ADDRESS_DECODEINTO_BLOCK_EXTBLOCK_HEADER_COINBASE": "Error importing raw rlp block: Blockheader RLP field is not data!", - "RLP_ExpectedInputString_ADDRESS_DECODEINTO_BLOCK_EXTBLOCK_TX0_RECIPIENT": "Error importing raw rlp block: Transaction RLP field is not data!", - "RLP_InputString_TooLong_ADDRESS_DECODEINTO_BLOCK_EXTBLOCK_HEADER_COINBASE": "Blockheader parse error: Key `coinbase` is not hash20", - "RLP_InputString_TooLong_ADDRESS_DECODEINTO_BLOCK_EXTBLOCK_TXS0_RECIPIENT": "TransactionLegacy convertion error: Key `to` is not hash20", - "RLP_ExpectedInputString_BIGINT_DECODEINTO_BLOCK_EXTBLOCK_HEADER_DIFFICULTY": "Error importing raw rlp block: Blockheader RLP field is not data!", - "RLP_ExpectedInputString_BIGINT_DECODEINTO_BLOCK_EXTBLOCK_TXS0_TXR": "Error importing raw rlp block: Transaction RLP field is not data!", - "RLP_ExpectedInputString_BIGINT_DECODEINTO_BLOCK_EXTBLOCK_TXS0_TXS": "Error importing raw rlp block: Transaction RLP field is not data!", - "RLP_ExpectedInputString_UINT64_DECODEINTO_BLOCK_EXTBLOCK_HEADER_GASLIMIT": "Error importing raw rlp block: Blockheader RLP field is not data!", - "RLP_ExpectedInputString_UINT64_DECODEINTO_BLOCK_EXTBLOCK_HEADER_GASUSED": "Error importing raw rlp block: Blockheader RLP field is not data!", - "RLP_ExpectedInputString_UINT64_DECODEINTO_BLOCK_EXTBLOCK_HEADER_TIME": "Error importing raw rlp block: Blockheader RLP field is not data!", - "RLP_ExpectedInputString_UINT64_DECODEINTO_BLOCK_EXTBLOCK_TXS0_GASLIMIT": "Error importing raw rlp block: Transaction RLP field is not data!", - "RLP_ExpectedInputString_NONCE_DECODEINTO_BLOCK_EXTBLOCK_HEADER_NONCE": "Error importing raw rlp block: Blockheader RLP field is not data!", - "RLP_ExpectedInputString_UINT8_DECODEINTO_BLOCK_EXTBLOCK_TXS0_PAYLOAD": "Error importing raw rlp block: OversizeRLP", - "RLP_InputString_TooLong_BLOCKNONCE_DECODEINTO_BLOCK_EXTBLOCK_HEADER_NONCE": "Error importing raw rlp block: OversizeRLP", - "RLP_InputString_TooLong_BLOCKNONCE_DECODEINTO_BLOCK_EXTBLOCK_HEADER_NONCE2": "Blockheader parse error: Key `nonce` is not hash8", - "RLP_NonCanonical_SizeInfo_EXTBLOCK": "Error importing raw rlp block: BadRLP", - "RLP_ExpectedInputList_TRANSACTION_DECODEINTO_BLOCK_EXTBLOCK_TXS": "Error importing raw rlp block: BadCast", - "RLP_ExpectedInputList_HEADER_DECODEINTO_BLOCK_EXTBLOCK_UNCLES": "Error importing raw rlp block: OversizeRLP", - "RLP_ExpectedInputList_TXDATA_DECODEINTO_BLOCK_EXTBLOCK_TXS0": "Error importing raw rlp block: Transaction RLP is expected to be list", - "RLP_Error_EOF": "ERROR(11): unexpected EOF", - "RLP_Error_RLP_Size": "ERROR(11): rlp: value size exceeds available input length", - "RLP_Error_Size_Information": "ERROR(11): rlp: non-canonical size information", - "LegacyBlockImportImpossible": "Legacy block import is impossible", - "LegacyBlockImportImpossible2": "Legacy block can only be on top of LegacyBlock", - "LegacyBlockBaseFeeTransaction": "BaseFee transaction in a Legacy blcok", - "1559BlockImportImpossible_HeaderIsLegacy": "1559 block must be on top of 1559", - "1559BlockImportImpossible_BaseFeeWrong": "Error in field: baseFeePerGas", - "1559BlockImportImpossible_InitialBaseFeeWrong": "Initial baseFee must be 1000000000", - "1559BlockImportImpossible_TargetGasLow": "gasTarget decreased too much", - "1559BlockImportImpossible_TargetGasHigh": "gasTarget increased too much", - "1559BlockImportImpossible_InitialGasLimitInvalid": "Invalid block1559: Initial gasLimit must be", - "MergeBlockImportImpossible": "Trying to import Merge block on top of Shanghai block after transition", - "ShanghaiBlockImportImpossible": "Trying to import Shanghai block on top of block that is not Shanghai!!", - "TR_IntrinsicGas": "intrinsic gas too low:", - "TR_NoFunds": "insufficient funds for gas * price + value", - "TR_NoFundsX": "insufficient funds for gas * price + value", - "TR_NoFundsValue": "insufficient funds for transfer", - "TR_NoFundsOrGas": "insufficient funds for gas * price + value", - "TR_FeeCapLessThanBlocks": "max fee per gas less than block base fee", - "TR_GasLimitReached": "gas limit reached", - "TR_FeeCapLessThanBlocksORGasLimitReached": "gas limit reached", - "TR_FeeCapLessThanBlocksORNoFunds": "max fee per gas less than block base fee", - "TR_NonceTooHigh": "nonce too high", - "TR_NonceTooLow": "nonce too low", - "TR_TypeNotSupported": "transaction type not supported", - "TR_TipGtFeeCap": "max priority fee per gas higher than max fee per gas", - "TR_TooShort": "typed transaction too short", - "TR_InitCodeLimitExceeded": "max initcode size exceeded", - "1559BaseFeeTooLarge": "TransactionBaseFee convertion error: VALUE >u256", - "1559PriorityFeeGreaterThanBaseFee": "maxFeePerGas \u003c maxPriorityFeePerGas", - "2930AccessListAddressTooLong": "rlp: input string too long for common.Address, decoding into (types.Transaction)(types.AccessListTx).AccessList[0].Address", - "2930AccessListAddressTooShort": "rlp: input string too short for common.Address, decoding into (types.Transaction)(types.AccessListTx).AccessList[0].Address", - "1559LeadingZerosBaseFee": "rlp: non-canonical integer (leading zero bytes) for *big.Int, decoding into (types.Transaction)(types.DynamicFeeTx).GasFeeCap", - "1559LeadingZerosPriorityFee": "rlp: non-canonical integer (leading zero bytes) for *big.Int, decoding into (types.Transaction)(types.DynamicFeeTx).GasTipCap", - "2930AccessListStorageHashTooShort": "rlp: input string too short for common.Hash, decoding into (types.Transaction)(types.AccessListTx).AccessList[0].StorageKeys[0]", - "2930AccessListStorageHashTooLong": "rlp: input string too long for common.Hash, decoding into (types.Transaction)(types.AccessListTx).AccessList[0].StorageKeys[0]", - "3675PoWBlockRejected": "Invalid block1559: Chain switched to PoS!", - "3675PoSBlockRejected": "Parent (transition) block has not reached TTD", - "3675PreMerge1559BlockRejected": "Trying to import 1559 block on top of PoS block", - "INPUT_UNMARSHAL_ERROR": "cannot unmarshal hex", - "INPUT_UNMARSHAL_SIZE_ERROR": "failed unmarshaling", - "RLP_BODY_UNMARSHAL_ERROR": "Rlp structure is wrong", - "EOF_ConflictingStackHeight": "err: stack_height_mismatch", - "EOF_StackUnderflow": "err: stack_underflow", - "EOF_InvalidCodeTermination": "err: no_terminating_instruction", - "EOF_MaxStackHeightExceeded": "err: max_stack_height_above_limit", - "EOF_UnreachableCode": "err: unreachable_instructions", - "EOF_InvalidCode": "err: invalid_code", - "EOF_TruncatedImmediate": "err: truncated_instruction", - "EOF_InvalidJumpDestination": "err: invalid_rjump_destination", - "EOF_InvalidJumpTableCount": "err: invalid_rjumpv_count", - "EOF_TypeSectionMissing": "err: type_section_missing", - "EOF_CodeSectionMissing": "err: code_section_missing", - "EOF_InvalidTypeSectionSize": "err: invalid_type_section_size", - "EOF_InvalidFirstSectionType": "err: invalid_first_section_type", - "EOF_TooManyCodeSections": "err: too_many_code_sections", - "EOF_InvalidCodeSectionIndex": "err: invalid_code_section_index", - "EOF_UndefinedInstruction": "err: undefined_instruction", - "EOF_ZeroSectionSize": "err: zero_section_size", - "EOF_NonEmptyStackOnTerminatingInstruction": "err: non_empty_stack_on_terminating_instruction", - "EOF_InvalidSectionBodiesSize": "err: invalid_section_bodies_size", - "PostMergeUncleHashIsNotEmpty": "block.uncleHash != empty", - "PostMergeDifficultyIsNot0": "block.difficulty must be 0" - } -} diff --git a/crates/sovereign-sdk/scripts/validate_packages_to_publish_yml.sh b/crates/sovereign-sdk/scripts/validate_packages_to_publish_yml.sh deleted file mode 100755 index 03725f285..000000000 --- a/crates/sovereign-sdk/scripts/validate_packages_to_publish_yml.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env bash - -set -Euo pipefail - -# This script makes sure that all workspace crates that are marked as releasable -# are also listed in packages_to_publish.yml. In addition, it makes sure that -# all packages listed in packages_to_publish.yml have all basic crate metadata and don't -# generate warnings when packaged. -# -# Important: this script is assumed to be cheap to run by our GH Actions -# workflows. Create another script if you need to add checks that are more expensive. - -# Somewhat unintuitively, `cargo metadata` returns `"publish": null` for publishable packages. -# From the docs at https://doc.rust-lang.org/cargo/commands/cargo-metadata.html#output-format: -# /* List of registries to which this package may be published. -# Publishing is unrestricted if null, and forbidden if an empty array. */ -releasable_packages=$(cargo metadata --format-version 1 --no-deps | jq -r '.packages[] | select(.publish == null) | .name') - -echo "Releasable packages according to cargo-metadata:" -echo "$releasable_packages" | sed 's/^/- /' -echo "" - -echo "Releasable packages according to packages_to_publish.yml:" -yq '.[]' packages_to_publish.yml | sed 's/^/- /' -echo "" - -echo "Validating packages_to_publish.yml..." - -status=0 -while read -r pkg; do - if yq -e "[\"$pkg\"] - . | length == 1" packages_to_publish.yml > /dev/null 2>&1; then - printf "%40s | ERR is releasable but NOT found in packages_to_publish.yml\n" "$pkg" - status=1 - fi -done <<< "$releasable_packages" - -echo "" -echo "Validating the present of package metadata for all packages_to_publish.yml entries..." - -while read -r pkg; do - # Capture both stdout and stderr. - output=$(cargo package --allow-dirty -p $pkg --list 2>&1) - if echo "$output" | grep -q "warning:"; then - printf "%40s | ERR warnings found:\n" "$pkg" - echo "$output" | grep "warning:" - status=1 - fi -done < <(yq '.[]' packages_to_publish.yml) - -echo "" -if [ $status -eq 1 ]; then - echo "Validation failed." - exit 1 -fi - -echo "Validation successful, everything okay." -echo "Goodbye!" diff --git a/crates/sovereign-sdk/utils/bashtestmd/Cargo.toml b/crates/sovereign-sdk/utils/bashtestmd/Cargo.toml deleted file mode 100644 index bcf94bc65..000000000 --- a/crates/sovereign-sdk/utils/bashtestmd/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "bashtestmd" -authors = { workspace = true } -edition = { workspace = true } -homepage = { workspace = true } -license = { workspace = true } -repository = { workspace = true } - -version = { workspace = true } -resolver = "2" -publish = false -autotests = false - -[dependencies] -clap = { workspace = true } -indoc = "2" -markdown = "1.0.0-alpha.16" -shell-escape = "0.1.5" diff --git a/crates/sovereign-sdk/utils/bashtestmd/src/main.rs b/crates/sovereign-sdk/utils/bashtestmd/src/main.rs deleted file mode 100644 index 9214f2347..000000000 --- a/crates/sovereign-sdk/utils/bashtestmd/src/main.rs +++ /dev/null @@ -1,268 +0,0 @@ -use std::collections::VecDeque; -use std::io::{self, Write}; - -use clap::Parser; -use indoc::indoc; -use markdown::mdast; - -#[derive(Debug, Parser)] -struct Args { - /// Input Markdown file to parse - #[clap(short, long)] - input: String, - /// Path to output Bash script - #[clap(short, long)] - output: String, - /// Only run code blocks with this tag - #[clap(short, long)] - tag: String, -} - -fn main() { - let args = Args::parse(); - - let file_contents = std::fs::read_to_string(&args.input).unwrap(); - let markdown_parse_options = markdown::ParseOptions::gfm(); - let markdown_ast = markdown::to_mdast(&file_contents, &markdown_parse_options).unwrap(); - - let code_blocks = get_all_code_blocks(markdown_ast); - let commands = convert_code_blocks_into_commands(code_blocks, &args.tag); - let script = compile_commands_into_bash(commands); - - std::fs::write(&args.output, script).unwrap(); -} - -struct Command { - cmd: String, - long_running: bool, - expected_output: Option, - wait_until: Option, - exit_code: Option, -} - -impl Command { - fn new(cmd: &str) -> Self { - Self { - cmd: cmd.to_string(), - long_running: false, - expected_output: None, - wait_until: None, - exit_code: Some(0), - } - } - - fn compile(&self, mut w: impl io::Write) -> io::Result<()> { - writeln!( - w, - "echo {}", - shell_escape::escape(format!("Running: '{}'", self.cmd).into()) - )?; - - if self.long_running { - if let Some(wait_until) = &self.wait_until { - writeln!( - w, - indoc!( - r#" - output=$(mktemp) - {} &> $output & - background_process_pid=$! - echo "Waiting for process with PID: $background_process_pid" - until grep -q -i {} $output - do - if ! ps $background_process_pid > /dev/null - then - echo "The background process died died" >&2 - exit 1 - fi - echo -n "." - sleep 5 - done - "# - ), - self.cmd, - shell_escape::escape(wait_until.into()) - )?; - } else { - // No expected output, just run the command and wait two - // minutes. Very, very hackish. - writeln!(w, "{} &", self.cmd)?; - writeln!(w, "sleep 120")?; - } - return Ok(()); - } - - if let Some(output) = &self.expected_output { - writeln!( - w, - indoc!( - r#" - output=$({}) - expected={} - # Either of the two must be a substring of the other. This kinda protects us - # against whitespace differences, trimming, etc. - if ! [[ $output == *"$expected"* || $expected == *"$output"* ]]; then - echo "'$expected' not found in text:" - echo "'$output'" - exit 1 - fi - "# - ), - self.cmd, - shell_escape::escape(output.into()) - )?; - } else { - writeln!(w, "{}", self.cmd)?; - } - - if let Some(exit_code) = self.exit_code { - writeln!( - w, - indoc!( - r#" - if [ $? -ne {0} ]; then - echo "Expected exit code {0}, got $?" - exit 1 - fi - "#, - ), - exit_code - )?; - } - - Ok(()) - } -} - -fn compile_commands_into_bash(cmds: Vec) -> String { - let mut script = Vec::::new(); - // Shebang. - writeln!(&mut script, "#!/usr/bin/env bash").unwrap(); - writeln!(&mut script, r#"trap 'jobs -p | xargs -r kill' EXIT"#).unwrap(); - - for cmd in cmds { - cmd.compile(&mut script).unwrap(); - } - writeln!(&mut script, r#"echo "All tests passed!"; exit 0"#).unwrap(); - String::from_utf8(script).unwrap() -} - -struct CodeBlockTags { - long_running: bool, - compare_output: bool, - exit_code: Option, - wait_until: Option, -} - -impl CodeBlockTags { - fn parse(code_block: &mdast::Code) -> Self { - let langs: Vec = code_block - .lang - .as_deref() - .unwrap_or_default() - .split(',') - .map(str::to_string) - .collect(); - - let mut tags = Self { - long_running: false, - compare_output: false, - exit_code: Some(0), - wait_until: None, - }; - - for lang in langs { - if lang == "bashtestmd:long-running" { - tags.long_running = true; - } else if lang == "bashtestmd:compare-output" { - tags.compare_output = true; - } else if lang == "bashtestmd:exit-code-ignore" { - tags.exit_code = None; - } else if lang.starts_with("bashtestmd:exit-code=") { - let exit_code = lang.split_once('=').unwrap().1.parse().unwrap(); - tags.exit_code = Some(exit_code); - } else if lang.starts_with("bashtestmd:wait-until=") { - let wait_until = lang.split_once('=').unwrap().1.to_string(); - tags.wait_until = Some(wait_until); - } else { - println!("Unknown bashtestmd tag, ignoring: {}", lang); - } - } - - tags - } -} - -fn convert_code_blocks_into_commands( - code_blocks: Vec, - only_tag: &str, -) -> Vec { - const PROMPT: &str = "$ "; - - let mut commands = Vec::new(); - - for code_block in code_blocks { - if !code_block - .lang - .as_deref() - .unwrap_or_default() - .contains(only_tag) - { - continue; - } - let tags = CodeBlockTags::parse(&code_block); - - let mut cmd: Option = None; - let mut output = String::new(); - - for line in code_block.value.lines() { - if let Some(cmd_string) = line.strip_prefix(PROMPT) { - if let Some(cmd) = cmd { - commands.push(Command::new(&cmd)); - } - cmd = Some(cmd_string.to_string()); - } else { - output.push_str(line); - output.push('\n'); - } - } - if let Some(cmd) = cmd { - let mut cmd = Command::new(&cmd); - cmd.long_running = tags.long_running; - cmd.wait_until = tags.wait_until; - cmd.expected_output = if tags.compare_output { - Some(output) - } else { - None - }; - commands.push(cmd); - } - } - - commands -} - -/// Ordered list of all code blocks in the Markdown file. -fn get_all_code_blocks(markdown_ast: mdast::Node) -> Vec { - let mut code_blocks = Vec::new(); - - let mut nodes: VecDeque = markdown_ast - .children() - .cloned() - .unwrap_or_default() - .into_iter() - .collect(); - - while let Some(next_node) = nodes.pop_front() { - if let mdast::Node::Code(code_node) = next_node { - code_blocks.push(code_node); - } else { - let children = next_node.children().map(Vec::as_slice).unwrap_or_default(); - for child in children.iter() { - nodes.push_front(child.clone()); - } - } - } - - code_blocks -} diff --git a/crates/sovereign-sdk/utils/zk-cycle-macros/Cargo.toml b/crates/sovereign-sdk/utils/zk-cycle-macros/Cargo.toml index 86740566b..75bc8e28b 100644 --- a/crates/sovereign-sdk/utils/zk-cycle-macros/Cargo.toml +++ b/crates/sovereign-sdk/utils/zk-cycle-macros/Cargo.toml @@ -20,7 +20,7 @@ name = "tests" path = "tests/all_tests.rs" [dependencies] -syn = { version = "1.0", features = ["full"] } +syn = { version = "2.0", features = ["full"] } quote = "1.0" proc-macro2 = "1.0" diff --git a/crates/sovereign-sdk/utils/zk-cycle-utils/Cargo.toml b/crates/sovereign-sdk/utils/zk-cycle-utils/Cargo.toml index 4c3b4fd76..ba325e5d4 100644 --- a/crates/sovereign-sdk/utils/zk-cycle-utils/Cargo.toml +++ b/crates/sovereign-sdk/utils/zk-cycle-utils/Cargo.toml @@ -13,9 +13,8 @@ resolver = "2" autotests = false [dependencies] -risc0-zkvm = { workspace = true, default-features = false, features = ['std'] } +risc0-zkvm = { workspace = true, default-features = false, features = ["std"] } risc0-zkvm-platform = { workspace = true } -bytes = "1.5.0" [features] default = [] diff --git a/crates/sovereign-sdk/utils/zk-cycle-utils/tracer/Cargo.lock b/crates/sovereign-sdk/utils/zk-cycle-utils/tracer/Cargo.lock deleted file mode 100644 index c871f0d42..000000000 --- a/crates/sovereign-sdk/utils/zk-cycle-utils/tracer/Cargo.lock +++ /dev/null @@ -1,788 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "aho-corasick" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f2135563fb5c609d2b2b87c1e8ce7bc41b0b45430fa9661f457981503dd5bf0" -dependencies = [ - "memchr", -] - -[[package]] -name = "anstream" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" - -[[package]] -name = "anstyle-parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" -dependencies = [ - "windows-sys 0.48.0", -] - -[[package]] -name = "anstyle-wincon" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" -dependencies = [ - "anstyle", - "windows-sys 0.48.0", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" - -[[package]] -name = "capstone" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1097e608594dad3bad608295567f757742b883606fe150faf7a9740b849730d8" -dependencies = [ - "capstone-sys", - "libc", -] - -[[package]] -name = "capstone-sys" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7f651d5ec4c2a2e6c508f2c8032655003cd728ec85663e9796616990e25b5a" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "cc" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clap" -version = "4.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.37", -] - -[[package]] -name = "clap_lex" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" - -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - -[[package]] -name = "console" -version = "0.15.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" -dependencies = [ - "encode_unicode 0.3.6", - "lazy_static", - "libc", - "unicode-width", - "windows-sys 0.45.0", -] - -[[package]] -name = "csv" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626ae34994d3d8d668f4269922248239db4ae42d538b14c398b74a52208e8086" -dependencies = [ - "csv-core", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "csv-core" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" -dependencies = [ - "memchr", -] - -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if", - "dirs-sys-next", -] - -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "encode_unicode" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" - -[[package]] -name = "encode_unicode" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" - -[[package]] -name = "errno" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "getrandom" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "goblin" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d20fd25aa456527ce4f544271ae4fea65d2eda4a6561ea56f39fb3ee4f7e3884" -dependencies = [ - "log", - "plain", - "scroll", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "hermit-abi" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" - -[[package]] -name = "indicatif" -version = "0.17.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b297dc40733f23a0e52728a58fa9489a5b7638a324932de16b41adc3ef80730" -dependencies = [ - "console", - "instant", - "number_prefix", - "portable-atomic", - "unicode-width", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "is-terminal" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys 0.48.0", -] - -[[package]] -name = "itoa" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.148" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" - -[[package]] -name = "linux-raw-sys" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" - -[[package]] -name = "log" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" - -[[package]] -name = "memchr" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" - -[[package]] -name = "number_prefix" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" - -[[package]] -name = "plain" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" - -[[package]] -name = "portable-atomic" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31114a898e107c51bb1609ffaf55a0e011cf6a4d7f1170d0015a165082c0338b" - -[[package]] -name = "prettytable-rs" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eea25e07510aa6ab6547308ebe3c036016d162b8da920dbb079e3ba8acf3d95a" -dependencies = [ - "csv", - "encode_unicode 1.0.0", - "is-terminal", - "lazy_static", - "term", - "unicode-width", -] - -[[package]] -name = "proc-macro2" -version = "1.0.67" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_users" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" -dependencies = [ - "getrandom", - "redox_syscall", - "thiserror", -] - -[[package]] -name = "regex" -version = "1.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - -[[package]] -name = "rustix" -version = "0.38.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "745ecfa778e66b2b63c88a61cb36e0eea109e803b0b86bf9879fbc77c70e86ed" -dependencies = [ - "bitflags 2.4.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.48.0", -] - -[[package]] -name = "rustversion" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" - -[[package]] -name = "ryu" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" - -[[package]] -name = "scroll" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda28d4b4830b807a8b43f7b0e6b5df875311b3e7621d84577188c175b6ec1ec" -dependencies = [ - "scroll_derive", -] - -[[package]] -name = "scroll_derive" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaaae8f38bb311444cfb7f1979af0bc9240d95795f75f9ceddf6a59b79ceffa0" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "serde" -version = "1.0.188" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.188" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.37", -] - -[[package]] -name = "smawk" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "term" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" -dependencies = [ - "dirs-next", - "rustversion", - "winapi", -] - -[[package]] -name = "textwrap" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" -dependencies = [ - "smawk", - "unicode-linebreak", - "unicode-width", -] - -[[package]] -name = "thiserror" -version = "1.0.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.37", -] - -[[package]] -name = "tracer" -version = "0.3.0" -dependencies = [ - "capstone", - "clap", - "goblin", - "indicatif", - "prettytable-rs", - "regex", - "rustc-demangle", - "textwrap", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-linebreak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" - -[[package]] -name = "unicode-width" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" - -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/crates/sovereign-sdk/utils/zk-cycle-utils/tracer/Cargo.toml b/crates/sovereign-sdk/utils/zk-cycle-utils/tracer/Cargo.toml deleted file mode 100644 index f037369bd..000000000 --- a/crates/sovereign-sdk/utils/zk-cycle-utils/tracer/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "tracer" -version = { workspace = true } -edition = "2018" - -[workspace] - -[dependencies] -rustc-demangle = "0.1.18" -goblin = "0.2" -capstone = "0.11.0" -regex = "1.5.4" -prettytable-rs = "^0.10" -textwrap = "0.16.0" -indicatif = "0.17.6" -clap = { workspace = true } diff --git a/crates/sovereign-sdk/utils/zk-cycle-utils/tracer/src/main.rs b/crates/sovereign-sdk/utils/zk-cycle-utils/tracer/src/main.rs deleted file mode 100644 index 3b4a554cc..000000000 --- a/crates/sovereign-sdk/utils/zk-cycle-utils/tracer/src/main.rs +++ /dev/null @@ -1,425 +0,0 @@ -use clap::Parser; -use goblin::elf::{sym::STT_FUNC, Elf}; -use indicatif::{ProgressBar, ProgressStyle}; -use prettytable::{format, Cell, Row, Table}; -use regex::Regex; -use rustc_demangle::demangle; -use std::cmp::Ordering; -use std::collections::HashMap; -use std::fs::read_to_string; -use std::process::Command; -use std::str; -use textwrap::wrap; - -#[derive(Parser, Debug)] -#[command(author, version, about, long_about = None)] -struct Args { - #[arg(short, long, default_value_t = 30)] - /// Include the "top" number of functions - top: usize, - - #[arg(long)] - /// Don't print stack aware instruction counts - no_stack_counts: bool, - - #[arg(long)] - /// Don't print raw (stack un-aware) instruction counts - no_raw_counts: bool, - - #[arg(long, required = true)] - /// Path to the riscv32 elf - rollup_elf: String, - - #[arg(long, required = true)] - /// Path to the rollup trace. - /// File must be one u64 program counter per line - rollup_trace: String, - - #[arg(short, long)] - /// Strip the hashes from the function name while printing - strip_hashes: bool, - - #[arg(short, long)] - /// Function name to target for getting stack counts - function_name: Option, - - #[arg(short, long)] - /// Exclude functions matching these patterns from display - /// usage: -e func1 -e func2 -e func3 - exclude_view: Vec, -} - -fn strip_hash(name_with_hash: &str) -> String { - let re = Regex::new(r"::h[0-9a-fA-F]+$").unwrap(); - re.replace(name_with_hash, "").to_string() -} - -fn cycle_count(insn: &str) -> Result { - // The opcodes and their cycle counts are taken from - // https://github.com/risc0/risc0/blob/main/risc0/zkvm/src/host/server/opcode.rs - match insn { - "LB" | "LH" | "LW" | "LBU" | "LHU" | "ADDI" | "SLLI" | "SLTI" | "SLTIU" | "AUIPC" - | "SB" | "SH" | "SW" | "ADD" | "SUB" | "SLL" | "SLT" | "SLTU" | "XOR" | "SRL" | "SRA" - | "OR" | "AND" | "MUL" | "MULH" | "MULSU" | "MULU" | "LUI" | "BEQ" | "BNE" | "BLT" - | "BGE" | "BLTU" | "BGEU" | "JALR" | "JAL" | "ECALL" | "EBREAK" => Ok(1), - - // Don't see this in the risc0 code base, but MUL, MULH, MULSU, and MULU all take 1 cycle, - // so going with that for MULHU as well. - "MULHU" => Ok(1), - - "XORI" | "ORI" | "ANDI" | "SRLI" | "SRAI" | "DIV" | "DIVU" | "REM" | "REMU" => Ok(2), - - _ => Err("Decode error"), - } -} - -fn print_intruction_counts( - first_header: &str, - count_vec: Vec<(String, usize)>, - top_n: usize, - strip_hashes: bool, - exclude_list: Option<&[String]>, -) { - let mut table = Table::new(); - table.set_format(*format::consts::FORMAT_DEFAULT); - table.set_titles(Row::new(vec![ - Cell::new(first_header), - Cell::new("Instruction Count"), - ])); - - let wrap_width = 90; - let mut row_count = 0; - for (key, value) in count_vec { - let mut cont = false; - if let Some(ev) = exclude_list { - for e in ev { - if key.contains(e) { - cont = true; - break; - } - } - if cont { - continue; - } - } - let mut stripped_key = key.clone(); - if strip_hashes { - stripped_key = strip_hash(&key); - } - row_count += 1; - if row_count > top_n { - break; - } - let wrapped_key = wrap(&stripped_key, wrap_width); - let key_cell_content = wrapped_key.join("\n"); - table.add_row(Row::new(vec![ - Cell::new(&key_cell_content), - Cell::new(&value.to_string()), - ])); - } - - table.printstd(); -} - -fn focused_stack_counts( - function_stack: &[String], - filtered_stack_counts: &mut HashMap, usize>, - function_name: &str, - instruction: &str, -) { - if let Some(index) = function_stack.iter().position(|s| s == function_name) { - let truncated_stack = &function_stack[0..=index]; - let count = filtered_stack_counts - .entry(truncated_stack.to_vec()) - .or_insert(0); - *count += cycle_count(instruction).unwrap(); - } -} - -fn _build_radare2_lookups( - start_lookup: &mut HashMap, - end_lookup: &mut HashMap, - func_range_lookup: &mut HashMap, - elf_name: &str, -) -> std::io::Result<()> { - let output = Command::new("r2") - .arg("-q") - .arg("-c") - .arg("aa;afl") - .arg(elf_name) - .output()?; - - if output.status.success() { - let result_str = str::from_utf8(&output.stdout).unwrap(); - for line in result_str.lines() { - let parts: Vec<&str> = line.split_whitespace().collect(); - let address = u64::from_str_radix(&parts[0][2..], 16).unwrap(); - let size = parts[2].parse::().unwrap(); - let end_address = address + size - 4; - let function_name = parts[3]; - start_lookup.insert(address, function_name.to_string()); - end_lookup.insert(end_address, function_name.to_string()); - func_range_lookup.insert(function_name.to_string(), (address, end_address)); - } - } else { - eprintln!( - "Error executing command: {}", - str::from_utf8(&output.stderr).unwrap() - ); - } - Ok(()) -} - -fn build_goblin_lookups( - start_lookup: &mut HashMap, - end_lookup: &mut HashMap, - func_range_lookup: &mut HashMap, - elf_name: &str, -) -> std::io::Result<()> { - let buffer = std::fs::read(elf_name).unwrap(); - let elf = Elf::parse(&buffer).unwrap(); - - for sym in &elf.syms { - if sym.st_type() == STT_FUNC { - let name = elf.strtab.get(sym.st_name).unwrap_or(Ok("")).unwrap_or(""); - let demangled_name = demangle(name); - let size = sym.st_size; - let start_address = sym.st_value; - let end_address = start_address + size - 4; - start_lookup.insert(start_address, demangled_name.to_string()); - end_lookup.insert(end_address, demangled_name.to_string()); - func_range_lookup.insert(demangled_name.to_string(), (start_address, end_address)); - } - } - Ok(()) -} - -fn increment_stack_counts( - instruction_counts: &mut HashMap, - function_stack: &[String], - filtered_stack_counts: &mut HashMap, usize>, - function_name: &Option, - instruction: &str, -) { - for f in function_stack { - *instruction_counts.entry(f.clone()).or_insert(0) += cycle_count(instruction).unwrap(); - } - if let Some(f) = function_name { - focused_stack_counts(function_stack, filtered_stack_counts, &f, instruction) - } -} - -fn main() -> std::io::Result<()> { - let args = Args::parse(); - let top_n = args.top; - let rollup_elf_path = args.rollup_elf; - let rollup_trace_path = args.rollup_trace; - let no_stack_counts = args.no_stack_counts; - let no_raw_counts = args.no_raw_counts; - let strip_hashes = args.strip_hashes; - let function_name = args.function_name; - let exclude_view = args.exclude_view; - - let mut start_lookup = HashMap::new(); - let mut end_lookup = HashMap::new(); - let mut func_range_lookup = HashMap::new(); - build_goblin_lookups( - &mut start_lookup, - &mut end_lookup, - &mut func_range_lookup, - &rollup_elf_path, - ) - .unwrap(); - - let mut function_ranges: Vec<(u64, u64, String)> = func_range_lookup - .iter() - .map(|(f, &(start, end))| (start, end, f.clone())) - .collect(); - - function_ranges.sort_by_key(|&(start, _, _)| start); - - let file_content = read_to_string(&rollup_trace_path).unwrap(); - let mut function_stack: Vec = Vec::new(); - let mut instruction_counts: HashMap = HashMap::new(); - let mut counts_without_callgraph: HashMap = HashMap::new(); - let mut filtered_stack_counts: HashMap, usize> = HashMap::new(); - let total_lines = file_content.lines().count() as u64; - let mut current_function_range: (u64, u64) = (0, 0); - - let update_interval = 1000usize; - let pb = ProgressBar::new(total_lines); - pb.set_style( - ProgressStyle::default_bar() - .template( - "{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {pos}/{len} ({eta})", - ) - .unwrap() - .progress_chars("#>-"), - ); - - for (c, line) in file_content.lines().enumerate() { - if c % &update_interval == 0 { - pb.inc(update_interval as u64); - } - let mut parts = line.split("\t"); - let pc = parts.next().unwrap_or_default().parse().unwrap(); - let instruction = parts.next().unwrap_or_default(); - - // Raw counts without considering the callgraph at all - // we're just checking if the PC belongs to a function - // if so we're incrementing. This would ignore the call stack - // so for example "main" would only have a hundred instructions or so - if let Ok(index) = function_ranges.binary_search_by(|&(start, end, _)| { - if pc < start { - Ordering::Greater - } else if pc > end { - Ordering::Less - } else { - Ordering::Equal - } - }) { - let (_, _, fname) = &function_ranges[index]; - *counts_without_callgraph.entry(fname.clone()).or_insert(0) += - cycle_count(instruction).unwrap(); - } else { - *counts_without_callgraph - .entry("anonymous".to_string()) - .or_insert(0) += cycle_count(instruction).unwrap(); - } - - // The next section considers the callstack - // We build a callstack and maintain it based on some rules - // Functions lower in the stack get their counts incremented - - // we are still in the current function - if pc > current_function_range.0 && pc <= current_function_range.1 { - increment_stack_counts( - &mut instruction_counts, - &function_stack, - &mut filtered_stack_counts, - &function_name, - instruction, - ); - continue; - } - - // jump to a new function (or the same one) - if let Some(f) = start_lookup.get(&pc) { - increment_stack_counts( - &mut instruction_counts, - &function_stack, - &mut filtered_stack_counts, - &function_name, - instruction, - ); - // jump to a new function (not recursive) - if !function_stack.contains(&f) { - function_stack.push(f.clone()); - current_function_range = *func_range_lookup.get(f).unwrap(); - } - } else { - // this means pc now points to an instruction that is - // 1. not in the current function's range - // 2. not a new function call - // we now account for a new possibility where we're returning to a function in the stack - // this need not be the immediate parent and can be any of the existing functions in the stack - // due to some optimizations that the compiler can make - let mut unwind_point = 0; - let mut unwind_found = false; - for (c, f) in function_stack.iter().enumerate() { - let (s, e) = func_range_lookup.get(f).unwrap(); - if pc > *s && pc <= *e { - unwind_point = c; - unwind_found = true; - break; - } - } - // unwinding until the parent - if unwind_found { - function_stack.truncate(unwind_point + 1); - increment_stack_counts( - &mut instruction_counts, - &function_stack, - &mut filtered_stack_counts, - &function_name, - instruction, - ); - continue; - } - - // if no unwind point has been found, that means we jumped to some random location - // so we'll just increment the counts for everything in the stack - increment_stack_counts( - &mut instruction_counts, - &function_stack, - &mut filtered_stack_counts, - &function_name, - instruction, - ); - } - } - - pb.finish_with_message("done"); - - let mut raw_counts: Vec<(String, usize)> = instruction_counts - .iter() - .map(|(key, value)| (key.clone(), value.clone())) - .collect(); - raw_counts.sort_by(|a, b| b.1.cmp(&a.1)); - - println!("\n\nTotal instructions in trace: {}", total_lines); - if !no_stack_counts { - println!("\n\n Instruction counts considering call graph"); - print_intruction_counts( - "Function Name", - raw_counts, - top_n, - strip_hashes, - Some(&exclude_view), - ); - } - - let mut raw_counts: Vec<(String, usize)> = counts_without_callgraph - .iter() - .map(|(key, value)| (key.clone(), value.clone())) - .collect(); - raw_counts.sort_by(|a, b| b.1.cmp(&a.1)); - if !no_raw_counts { - println!("\n\n Instruction counts ignoring call graph"); - print_intruction_counts( - "Function Name", - raw_counts, - top_n, - strip_hashes, - Some(&exclude_view), - ); - } - - let mut raw_counts: Vec<(String, usize)> = filtered_stack_counts - .iter() - .map(|(stack, count)| { - let numbered_stack = stack - .iter() - .rev() - .enumerate() - .map(|(index, line)| { - let modified_line = if strip_hashes { - strip_hash(line) - } else { - line.clone() - }; - format!("({}) {}", index + 1, modified_line) - }) - .collect::>() - .join("\n"); - (numbered_stack, *count) - }) - .collect(); - - raw_counts.sort_by(|a, b| b.1.cmp(&a.1)); - if let Some(f) = function_name { - println!("\n\n Stack patterns for function '{f}' "); - print_intruction_counts("Function Stack", raw_counts, top_n, strip_hashes, None); - } - Ok(()) -}