diff --git a/Cargo.toml b/Cargo.toml index bec19f522..5d7c05145 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -81,14 +81,13 @@ schemars = { version = "0.8.12", features = ["derive"] } tempfile = "3.5" tokio = { version = "1", features = ["full"] } -ethers = "2.0.8" -ethers-core = "2.0.8" -ethers-contract = "2.0.8" -ethers-providers = "2.0.8" -ethers-signers = { version = "2.0.8", default-features = false } -ethers-middleware = "2.0.8" +ethers = "=2.0.8" +ethers-core = "=2.0.8" +ethers-contract = "=2.0.8" +ethers-providers = "=2.0.8" +ethers-signers = { version = "=2.0.8", default-features = false } +ethers-middleware = "=2.0.8" # TODO https://github.com/Sovereign-Labs/sovereign-sdk/issues/498 anvil = { git = "https://github.com/foundry-rs/foundry", rev = "684d394db587bef427475a660c72013e97ef71d2" } anvil-core = { git = "https://github.com/foundry-rs/foundry", features = ["fastrlp", "serde"], rev = "684d394db587bef427475a660c72013e97ef71d2" } - diff --git a/adapters/celestia/src/celestia.rs b/adapters/celestia/src/celestia.rs index bf044df99..5137922ec 100644 --- a/adapters/celestia/src/celestia.rs +++ b/adapters/celestia/src/celestia.rs @@ -1,5 +1,6 @@ use std::fmt::{Display, Formatter}; use std::ops::Range; +use std::str::FromStr; use std::sync::{Arc, Mutex}; use base64::engine::general_purpose::STANDARD as B64_ENGINE; @@ -352,6 +353,18 @@ impl From<[u8; 32]> for H160 { } } +impl FromStr for H160 { + type Err = hex::FromHexError; + + fn from_str(s: &str) -> Result { + // Remove the "0x" prefix, if it exists. + let s = s.strip_prefix("0x").unwrap_or(s); + let mut output = [0u8; 20]; + hex::decode_to_slice(s, &mut output)?; + Ok(H160(output)) + } +} + impl Display for H160 { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "0x{}", hex::encode(self.0)) diff --git a/examples/demo-rollup/Cargo.lock b/examples/demo-rollup/Cargo.lock deleted file mode 100644 index 8bf6ff3a7..000000000 --- a/examples/demo-rollup/Cargo.lock +++ /dev/null @@ -1,3481 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "accounts" -version = "0.1.0" -source = "git+https://github.com/Sovereign-Labs/sovereign.git?rev=04d1591b4568cdfbebaa05eeee020c811080a9af#04d1591b4568cdfbebaa05eeee020c811080a9af" -dependencies = [ - "anyhow", - "borsh", - "hex", - "serde", - "serde_json", - "sov-modules-api", - "sov-modules-macros", - "sov-state", - "sovereign-core", - "thiserror", -] - -[[package]] -name = "ahash" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", -] - -[[package]] -name = "aho-corasick" -version = "0.7.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" -dependencies = [ - "memchr", -] - -[[package]] -name = "aho-corasick" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" -dependencies = [ - "memchr", -] - -[[package]] -name = "anyhow" -version = "1.0.71" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" - -[[package]] -name = "arrayvec" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" - -[[package]] -name = "async-trait" -version = "0.1.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.16", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "bank" -version = "0.1.0" -source = "git+https://github.com/Sovereign-Labs/sovereign.git?rev=04d1591b4568cdfbebaa05eeee020c811080a9af#04d1591b4568cdfbebaa05eeee020c811080a9af" -dependencies = [ - "anyhow", - "borsh", - "hex", - "jsonrpsee", - "serde", - "serde_json", - "sov-modules-api", - "sov-modules-macros", - "sov-state", - "sovereign-core", - "thiserror", -] - -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - -[[package]] -name = "base64" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" - -[[package]] -name = "base64ct" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" - -[[package]] -name = "bech32" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" - -[[package]] -name = "beef" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" -dependencies = [ - "serde", -] - -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "bindgen" -version = "0.64.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4" -dependencies = [ - "bitflags", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "peeking_take_while", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 1.0.109", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "blake2" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" -dependencies = [ - "digest 0.10.6", -] - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "borsh" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" -dependencies = [ - "borsh-derive", - "bytes", - "hashbrown 0.13.2", -] - -[[package]] -name = "borsh-derive" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" -dependencies = [ - "borsh-derive-internal", - "borsh-schema-derive-internal", - "proc-macro-crate 0.1.5", - "proc-macro2", - "syn 1.0.109", -] - -[[package]] -name = "borsh-derive-internal" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "borsh-schema-derive-internal" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "bstr" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d4260bcc2e8fc9df1eac4919a720effeb63a3f0952f5bf4944adfa18897f09" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "bumpalo" -version = "3.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c6ed94e98ecff0c12dd1b04c15ec0d7d9458ca8fe806cea6f12954efe74c63b" - -[[package]] -name = "bytemuck" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" -dependencies = [ - "bytemuck_derive", -] - -[[package]] -name = "bytemuck_derive" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.16", -] - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" -dependencies = [ - "serde", -] - -[[package]] -name = "bzip2-sys" -version = "0.1.11+1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" -dependencies = [ - "cc", - "libc", - "pkg-config", -] - -[[package]] -name = "cc" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" -dependencies = [ - "jobserver", -] - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clang-sys" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "const-oid" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "core-foundation" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" - -[[package]] -name = "cpufeatures" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" -dependencies = [ - "libc", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek-ng" -version = "4.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.6.4", - "subtle-ng", - "zeroize", -] - -[[package]] -name = "demo-stf" -version = "0.1.0" -source = "git+https://github.com/Sovereign-Labs/sovereign.git?rev=04d1591b4568cdfbebaa05eeee020c811080a9af#04d1591b4568cdfbebaa05eeee020c811080a9af" -dependencies = [ - "accounts", - "anyhow", - "bank", - "borsh", - "election", - "schemadb", - "sequencer", - "serde", - "serde_json", - "sha2 0.10.6", - "sov-app-template", - "sov-modules-api", - "sov-modules-macros", - "sov-state", - "sovereign-db", - "sovereign-core", - "toml 0.7.3", - "value-setter", -] - -[[package]] -name = "der" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e58dffcdcc8ee7b22f0c1f71a69243d7c2d9ad87b5a14361f2424a1565c219" -dependencies = [ - "const-oid", - "zeroize", -] - -[[package]] -name = "derive_more" -version = "0.99.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn 1.0.109", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "digest" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" -dependencies = [ - "block-buffer 0.10.4", - "crypto-common", - "subtle", -] - -[[package]] -name = "directories" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.48.0", -] - -[[package]] -name = "downcast-rs" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" - -[[package]] -name = "ed25519" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" -dependencies = [ - "signature 1.6.4", -] - -[[package]] -name = "ed25519" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fb04eee5d9d907f29e80ee6b0e78f7e2c82342c63e3580d8c4f69d9d5aad963" -dependencies = [ - "pkcs8", - "signature 2.1.0", -] - -[[package]] -name = "ed25519-consensus" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" -dependencies = [ - "curve25519-dalek-ng", - "hex", - "rand_core 0.6.4", - "sha2 0.9.9", - "zeroize", -] - -[[package]] -name = "ed25519-dalek" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" -dependencies = [ - "curve25519-dalek", - "ed25519 1.5.3", - "rand 0.7.3", - "serde", - "sha2 0.9.9", - "zeroize", -] - -[[package]] -name = "either" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" - -[[package]] -name = "election" -version = "0.1.0" -source = "git+https://github.com/Sovereign-Labs/sovereign.git?rev=04d1591b4568cdfbebaa05eeee020c811080a9af#04d1591b4568cdfbebaa05eeee020c811080a9af" -dependencies = [ - "anyhow", - "borsh", - "hex", - "serde", - "serde_json", - "sov-modules-api", - "sov-modules-macros", - "sov-state", - "sovereign-core", - "thiserror", -] - -[[package]] -name = "elf" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b183d6ce6ca4cf30e3db37abf5b52568b5f9015c97d9fbdd7026aa5dcdd758" - -[[package]] -name = "encoding_rs" -version = "0.8.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "errno" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" -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 = "eyre" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" -dependencies = [ - "indenter", - "once_cell", -] - -[[package]] -name = "fastrand" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] - -[[package]] -name = "sov-first-read-last-write-cache" -version = "0.1.0" -source = "git+https://github.com/Sovereign-Labs/sovereign.git?rev=04d1591b4568cdfbebaa05eeee020c811080a9af#04d1591b4568cdfbebaa05eeee020c811080a9af" -dependencies = [ - "thiserror", -] - -[[package]] -name = "fixedbitset" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" - -[[package]] -name = "flex-error" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c606d892c9de11507fa0dcffc116434f94e105d0bbdc4e405b61519464c49d7b" -dependencies = [ - "eyre", - "paste", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "futures" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" - -[[package]] -name = "futures-io" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" - -[[package]] -name = "futures-macro" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.16", -] - -[[package]] -name = "futures-sink" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" - -[[package]] -name = "futures-task" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" - -[[package]] -name = "futures-util" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", -] - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "globset" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc" -dependencies = [ - "aho-corasick 0.7.20", - "bstr", - "fnv", - "log", - "regex", -] - -[[package]] -name = "h2" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "half" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash", -] - -[[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.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -dependencies = [ - "serde", -] - -[[package]] -name = "hex-literal" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" - -[[package]] -name = "http" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" - -[[package]] -name = "httpdate" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" - -[[package]] -name = "hyper" -version = "0.14.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" -dependencies = [ - "http", - "hyper", - "log", - "rustls", - "rustls-native-certs", - "tokio", - "tokio-rustls", - "webpki-roots", -] - -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper", - "native-tls", - "tokio", - "tokio-native-tls", -] - -[[package]] -name = "idna" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "impl-trait-for-tuples" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "indenter" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" -dependencies = [ - "hermit-abi 0.3.1", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "ipnet" -version = "2.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" - -[[package]] -name = "jmt" -version = "0.5.0" -source = "git+https://github.com/penumbra-zone/jmt.git?rev=3ca60665bee78549b37bab5ec461d108dada874d#3ca60665bee78549b37bab5ec461d108dada874d" -dependencies = [ - "anyhow", - "borsh", - "hashbrown 0.13.2", - "hex", - "itertools", - "mirai-annotations", - "num-derive", - "num-traits", - "serde", - "sha2 0.10.6", - "tracing", -] - -[[package]] -name = "jobserver" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" -dependencies = [ - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "jsonrpsee" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d291e3a5818a2384645fd9756362e6d89cf0541b0b916fa7702ea4a9833608e" -dependencies = [ - "jsonrpsee-core", - "jsonrpsee-http-client", - "jsonrpsee-proc-macros", - "jsonrpsee-server", - "jsonrpsee-types", - "tracing", -] - -[[package]] -name = "jsonrpsee-core" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e70b4439a751a5de7dd5ed55eacff78ebf4ffe0fc009cb1ebb11417f5b536b" -dependencies = [ - "anyhow", - "arrayvec", - "async-trait", - "beef", - "futures-channel", - "futures-util", - "globset", - "hyper", - "jsonrpsee-types", - "parking_lot", - "rand 0.8.5", - "rustc-hash", - "serde", - "serde_json", - "soketto", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "jsonrpsee-http-client" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc345b0a43c6bc49b947ebeb936e886a419ee3d894421790c969cc56040542ad" -dependencies = [ - "async-trait", - "hyper", - "hyper-rustls", - "jsonrpsee-core", - "jsonrpsee-types", - "rustc-hash", - "serde", - "serde_json", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "jsonrpsee-proc-macros" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baa6da1e4199c10d7b1d0a6e5e8bd8e55f351163b6f4b3cbb044672a69bd4c1c" -dependencies = [ - "heck", - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "jsonrpsee-server" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb69dad85df79527c019659a992498d03f8495390496da2f07e6c24c2b356fc" -dependencies = [ - "futures-channel", - "futures-util", - "http", - "hyper", - "jsonrpsee-core", - "jsonrpsee-types", - "serde", - "serde_json", - "soketto", - "tokio", - "tokio-stream", - "tokio-util", - "tower", - "tracing", -] - -[[package]] -name = "jsonrpsee-types" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bd522fe1ce3702fd94812965d7bb7a3364b1c9aba743944c5a00529aae80f8c" -dependencies = [ - "anyhow", - "beef", - "serde", - "serde_json", - "thiserror", - "tracing", -] - -[[package]] -name = "jupiter" -version = "0.1.0" -source = "git+https://github.com/Sovereign-Labs/Jupiter.git?rev=33fba8c86640414f0b31022918dd7e7839fb8e64#33fba8c86640414f0b31022918dd7e7839fb8e64" -dependencies = [ - "anyhow", - "base64 0.13.1", - "borsh", - "hex", - "hex-literal", - "jsonrpsee", - "nmt-rs", - "prost", - "prost-build", - "prost-types", - "reqwest", - "serde", - "serde_cbor", - "serde_json", - "sovereign-core", - "tendermint", - "tendermint-proto", - "tokio", - "tracing", -] - -[[package]] -name = "lazy-regex" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff63c423c68ea6814b7da9e88ce585f793c87ddd9e78f646970891769c8235d4" -dependencies = [ - "lazy-regex-proc_macros", - "once_cell", - "regex", -] - -[[package]] -name = "lazy-regex-proc_macros" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8edfc11b8f56ce85e207e62ea21557cfa09bb24a8f6b04ae181b086ff8611c22" -dependencies = [ - "proc-macro2", - "quote", - "regex", - "syn 1.0.109", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "libc" -version = "0.2.144" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" - -[[package]] -name = "libloading" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] - -[[package]] -name = "librocksdb-sys" -version = "0.8.3+7.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "557b255ff04123fcc176162f56ed0c9cd42d8f357cf55b3fabeb60f7413741b3" -dependencies = [ - "bindgen", - "bzip2-sys", - "cc", - "glob", - "libc", - "libz-sys", - "zstd-sys", -] - -[[package]] -name = "libz-sys" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ee889ecc9568871456d42f603d6a0ce59ff328d291063a45cbdf0036baf6db" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "linux-raw-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" - -[[package]] -name = "lock_api" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "matrixmultiply" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090126dc04f95dc0d1c1c91f61bdd474b3930ca064c1edc8a849da2c6cbe1e77" -dependencies = [ - "autocfg", - "rawpointer", -] - -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "memoffset" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" -dependencies = [ - "autocfg", -] - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "mio" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" -dependencies = [ - "libc", - "log", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.45.0", -] - -[[package]] -name = "mirai-annotations" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" - -[[package]] -name = "multimap" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" - -[[package]] -name = "native-tls" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "ndarray" -version = "0.15.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb12d4e967ec485a5f71c6311fe28158e9d6f4bc4a447b474184d0f91a8fa32" -dependencies = [ - "matrixmultiply", - "num-complex", - "num-integer", - "num-traits", - "rawpointer", - "rayon", -] - -[[package]] -name = "nmt-rs" -version = "0.1.0" -source = "git+https://github.com/Sovereign-Labs/nmt-rs.git?rev=dd37588444fca72825d11fe4a46838f66525c49f#dd37588444fca72825d11fe4a46838f66525c49f" -dependencies = [ - "borsh", - "bytes", - "serde", - "sha2 0.10.6", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - -[[package]] -name = "num-complex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-derive" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" -dependencies = [ - "hermit-abi 0.2.6", - "libc", -] - -[[package]] -name = "once_cell" -version = "1.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "openssl" -version = "0.10.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.16", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "windows-sys 0.45.0", -] - -[[package]] -name = "paste" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" - -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - -[[package]] -name = "percent-encoding" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" - -[[package]] -name = "petgraph" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" -dependencies = [ - "fixedbitset", - "indexmap", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - -[[package]] -name = "pkg-config" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "prettyplease" -version = "0.1.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" -dependencies = [ - "proc-macro2", - "syn 1.0.109", -] - -[[package]] -name = "proc-macro-crate" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" -dependencies = [ - "toml 0.5.11", -] - -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit", -] - -[[package]] -name = "proc-macro2" -version = "1.0.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4ec6d5fe0b140acb27c9a0444118cf55bfbb4e0b259739429abb4521dd67c16" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prometheus" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" -dependencies = [ - "cfg-if", - "fnv", - "lazy_static", - "memchr", - "parking_lot", - "thiserror", -] - -[[package]] -name = "prost" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-build" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" -dependencies = [ - "bytes", - "heck", - "itertools", - "lazy_static", - "log", - "multimap", - "petgraph", - "prettyplease", - "prost", - "prost-types", - "regex", - "syn 1.0.109", - "tempfile", - "which", -] - -[[package]] -name = "prost-derive" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "prost-types" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" -dependencies = [ - "prost", -] - -[[package]] -name = "quote" -version = "1.0.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.9", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rawpointer" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" - -[[package]] -name = "rayon" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags", -] - -[[package]] -name = "redox_users" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" -dependencies = [ - "getrandom 0.2.9", - "redox_syscall 0.2.16", - "thiserror", -] - -[[package]] -name = "regex" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" -dependencies = [ - "aho-corasick 1.0.1", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" - -[[package]] -name = "reqwest" -version = "0.11.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13293b639a097af28fc8a90f22add145a9c954e49d77da06263d58cf44d5fb91" -dependencies = [ - "base64 0.21.0", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-tls", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-native-tls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winreg", -] - -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi", -] - -[[package]] -name = "risc0-adapter" -version = "0.1.0" -source = "git+https://github.com/Sovereign-Labs/sovereign.git?rev=04d1591b4568cdfbebaa05eeee020c811080a9af#04d1591b4568cdfbebaa05eeee020c811080a9af" -dependencies = [ - "anyhow", - "bincode", - "risc0-circuit-rv32im", - "risc0-zkp", - "risc0-zkvm", - "serde", - "sovereign-core", -] - -[[package]] -name = "risc0-build-kernel" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bd8661c341fd7db631406197bf2a93d005c57785fa4fbbda6499abfbf953f09" -dependencies = [ - "cc", - "directories", - "glob", - "hex", - "sha2 0.10.6", - "tempfile", -] - -[[package]] -name = "risc0-circuit-rv32im" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c3f7ee29a8b98dcf087dd6415b87b9c1244a65339eceefa55a0c0307bdab96" -dependencies = [ - "anyhow", - "log", - "rand 0.8.5", - "rayon", - "risc0-circuit-rv32im-sys", - "risc0-core", - "risc0-sys", - "risc0-zkp", - "risc0-zkvm-platform", - "tracing", -] - -[[package]] -name = "risc0-circuit-rv32im-sys" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c76b80fabe90af55ff52676e569610a41f779d965ae25eef8f1651ce3d94764f" -dependencies = [ - "cc", - "glob", - "risc0-build-kernel", - "risc0-core", - "risc0-sys", -] - -[[package]] -name = "risc0-core" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7efca5bf936a826d12db95178027a6a2e956541de0c9eaa55840b0477ae3d1c1" -dependencies = [ - "bytemuck", - "rand_core 0.6.4", -] - -[[package]] -name = "risc0-sys" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b96860727199dad98fb226a3061d0490d64f18e5ed9b85cd9bf20a4543571369" -dependencies = [ - "cc", - "glob", - "risc0-build-kernel", - "risc0-core", -] - -[[package]] -name = "risc0-zeroio" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced65dc4609d9aec0f8f80a78eb083001ecbfd09396405fe11c91346b8f973b9" -dependencies = [ - "bytemuck", - "impl-trait-for-tuples", - "log", - "risc0-zeroio-derive", - "risc0-zkvm-platform", - "tracing", -] - -[[package]] -name = "risc0-zeroio-derive" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9b2ca1f7afed9205fc01391067210d4cd2e37f7e9296feefaa165a6adc35afd" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "risc0-zkp" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673c3238ee623624b411fb4e4b9d8161f5bfe23c9cf93f2e22175090872ca59c" -dependencies = [ - "anyhow", - "blake2", - "bytemuck", - "digest 0.10.6", - "hex", - "lazy_static", - "log", - "ndarray", - "paste", - "rand 0.8.5", - "rand_core 0.6.4", - "rayon", - "risc0-core", - "risc0-sys", - "risc0-zeroio", - "risc0-zkvm-platform", - "serde", - "sha2 0.10.6", - "tracing", -] - -[[package]] -name = "risc0-zkvm" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7128f9945bc96d0d251729f2dee5ceeef301bd638bb67befd328a5d892b14d91" -dependencies = [ - "anyhow", - "bytemuck", - "cfg-if", - "elf", - "generic-array", - "getrandom 0.2.9", - "hex", - "lazy-regex", - "log", - "num-derive", - "num-traits", - "rand 0.8.5", - "rayon", - "risc0-circuit-rv32im", - "risc0-core", - "risc0-zeroio", - "risc0-zkp", - "risc0-zkvm-platform", - "rrs-lib", - "serde", - "sha2 0.10.6", - "tracing", -] - -[[package]] -name = "risc0-zkvm-platform" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e07e6ed86c9f10a2d201aeed0545b933638fa82a5dbf6d141b0b9fe08ad0dd8b" - -[[package]] -name = "rocksdb" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e9562ea1d70c0cc63a34a22d977753b50cca91cc6b6527750463bd5dd8697bc" -dependencies = [ - "libc", - "librocksdb-sys", -] - -[[package]] -name = "rrs-lib" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4382d3af3a4ebdae7f64ba6edd9114fff92c89808004c4943b393377a25d001" -dependencies = [ - "downcast-rs", - "paste", -] - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - -[[package]] -name = "rustix" -version = "0.37.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" -dependencies = [ - "bitflags", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys", - "windows-sys 0.48.0", -] - -[[package]] -name = "rustls" -version = "0.20.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" -dependencies = [ - "log", - "ring", - "sct", - "webpki", -] - -[[package]] -name = "rustls-native-certs" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" -dependencies = [ - "openssl-probe", - "rustls-pemfile", - "schannel", - "security-framework", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" -dependencies = [ - "base64 0.21.0", -] - -[[package]] -name = "ryu" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" - -[[package]] -name = "schannel" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" -dependencies = [ - "windows-sys 0.42.0", -] - -[[package]] -name = "schemadb" -version = "0.1.0" -source = "git+https://github.com/Sovereign-Labs/sovereign.git?rev=04d1591b4568cdfbebaa05eeee020c811080a9af#04d1591b4568cdfbebaa05eeee020c811080a9af" -dependencies = [ - "anyhow", - "byteorder", - "hex", - "once_cell", - "prometheus", - "rand 0.8.5", - "rocksdb", - "sovereign-core", - "tracing", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "sct" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "security-framework" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2855b3715770894e67cbfa3df957790aa0c9edc3bf06efa1a84d77fa0839d1" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" - -[[package]] -name = "sequencer" -version = "0.1.0" -source = "git+https://github.com/Sovereign-Labs/sovereign.git?rev=04d1591b4568cdfbebaa05eeee020c811080a9af#04d1591b4568cdfbebaa05eeee020c811080a9af" -dependencies = [ - "anyhow", - "bank", - "borsh", - "hex", - "serde", - "serde_json", - "sov-modules-api", - "sov-modules-macros", - "sov-state", - "sovereign-core", - "thiserror", -] - -[[package]] -name = "serde" -version = "1.0.163" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_bytes" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_cbor" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" -dependencies = [ - "half", - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.163" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.16", -] - -[[package]] -name = "serde_json" -version = "1.0.96" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_repr" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.16", -] - -[[package]] -name = "serde_spanned" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha-1" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "sha2" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.6", -] - -[[package]] -name = "sharded-slab" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "shlex" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" - -[[package]] -name = "signal-hook-registry" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" -dependencies = [ - "libc", -] - -[[package]] -name = "signature" -version = "1.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" - -[[package]] -name = "signature" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" - -[[package]] -name = "slab" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" - -[[package]] -name = "socket2" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "soketto" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" -dependencies = [ - "base64 0.13.1", - "bytes", - "futures", - "http", - "httparse", - "log", - "rand 0.8.5", - "sha-1", -] - -[[package]] -name = "sov-app-template" -version = "0.1.0" -source = "git+https://github.com/Sovereign-Labs/sovereign.git?rev=04d1591b4568cdfbebaa05eeee020c811080a9af#04d1591b4568cdfbebaa05eeee020c811080a9af" -dependencies = [ - "anyhow", - "borsh", - "serde", - "sov-modules-api", - "sov-state", - "sovereign-core", - "tracing", -] - -[[package]] -name = "sov-demo" -version = "0.1.0" -dependencies = [ - "anyhow", - "borsh", - "demo-stf", - "hex", - "jsonrpsee", - "jupiter", - "risc0-adapter", - "serde", - "serde_json", - "sha2 0.10.6", - "sovereign-db", - "sovereign-core", - "tempfile", - "tendermint", - "tokio", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "sov-modules-api" -version = "0.1.0" -source = "git+https://github.com/Sovereign-Labs/sovereign.git?rev=04d1591b4568cdfbebaa05eeee020c811080a9af#04d1591b4568cdfbebaa05eeee020c811080a9af" -dependencies = [ - "anyhow", - "bech32", - "borsh", - "derive_more", - "ed25519-dalek", - "jmt", - "rand 0.7.3", - "serde", - "sha2 0.10.6", - "sov-state", - "sovereign-core", - "thiserror", -] - -[[package]] -name = "sov-modules-macros" -version = "0.1.0" -source = "git+https://github.com/Sovereign-Labs/sovereign.git?rev=04d1591b4568cdfbebaa05eeee020c811080a9af#04d1591b4568cdfbebaa05eeee020c811080a9af" -dependencies = [ - "anyhow", - "borsh", - "proc-macro2", - "quote", - "sov-modules-api", - "sovereign-core", - "syn 1.0.109", -] - -[[package]] -name = "sov-state" -version = "0.1.0" -source = "git+https://github.com/Sovereign-Labs/sovereign.git?rev=04d1591b4568cdfbebaa05eeee020c811080a9af#04d1591b4568cdfbebaa05eeee020c811080a9af" -dependencies = [ - "anyhow", - "borsh", - "sov-first-read-last-write-cache", - "hex", - "jmt", - "serde", - "sha2 0.10.6", - "sovereign-db", - "thiserror", -] - -[[package]] -name = "sovereign-db" -version = "0.1.0" -source = "git+https://github.com/Sovereign-Labs/sovereign.git?rev=04d1591b4568cdfbebaa05eeee020c811080a9af#04d1591b4568cdfbebaa05eeee020c811080a9af" -dependencies = [ - "anyhow", - "bincode", - "borsh", - "byteorder", - "jmt", - "rocksdb", - "schemadb", - "serde", - "sovereign-core", -] - -[[package]] -name = "sovereign-core" -version = "0.1.0" -source = "git+https://github.com/Sovereign-Labs/sovereign.git?rev=04d1591b4568cdfbebaa05eeee020c811080a9af#04d1591b4568cdfbebaa05eeee020c811080a9af" -dependencies = [ - "anyhow", - "borsh", - "bytes", - "jmt", - "serde", - "sha2 0.10.6", - "thiserror", -] - -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] -name = "spki" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "subtle-encoding" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" -dependencies = [ - "zeroize", -] - -[[package]] -name = "subtle-ng" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" - -[[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.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tempfile" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" -dependencies = [ - "cfg-if", - "fastrand", - "redox_syscall 0.3.5", - "rustix", - "windows-sys 0.45.0", -] - -[[package]] -name = "tendermint" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a46ec6b25b028097ab682ffae11d09d64fe1e2535833b902f26a278a0f88a705" -dependencies = [ - "bytes", - "digest 0.10.6", - "ed25519 2.2.1", - "ed25519-consensus", - "flex-error", - "futures", - "num-traits", - "once_cell", - "prost", - "prost-types", - "serde", - "serde_bytes", - "serde_json", - "serde_repr", - "sha2 0.10.6", - "signature 2.1.0", - "subtle", - "subtle-encoding", - "tendermint-proto", - "time", - "zeroize", -] - -[[package]] -name = "tendermint-proto" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce23c8ff0e6634eb4c3c4aeed45076dc97dac91aac5501a905a67fa222e165b" -dependencies = [ - "bytes", - "flex-error", - "num-derive", - "num-traits", - "prost", - "prost-types", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - -[[package]] -name = "thiserror" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.16", -] - -[[package]] -name = "thread_local" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" -dependencies = [ - "cfg-if", - "once_cell", -] - -[[package]] -name = "time" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc" -dependencies = [ - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" - -[[package]] -name = "time-macros" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" -dependencies = [ - "time-core", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aa32867d44e6f2ce3385e89dceb990188b8bb0fb25b0cf576647a6f98ac5105" -dependencies = [ - "autocfg", - "bytes", - "libc", - "mio", - "num_cpus", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys 0.48.0", -] - -[[package]] -name = "tokio-macros" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.16", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.23.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" -dependencies = [ - "rustls", - "tokio", - "webpki", -] - -[[package]] -name = "tokio-stream" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" -dependencies = [ - "bytes", - "futures-core", - "futures-io", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", -] - -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - -[[package]] -name = "toml" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b403acf6f2bb0859c93c7f0d967cb4a75a7ac552100f9322faf64dc047669b21" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.19.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "winnow", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-layer" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - -[[package]] -name = "tracing" -version = "0.1.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" -dependencies = [ - "cfg-if", - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.16", -] - -[[package]] -name = "tracing-core" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" -dependencies = [ - "lazy_static", - "log", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" -dependencies = [ - "nu-ansi-term", - "sharded-slab", - "smallvec", - "thread_local", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "try-lock" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" - -[[package]] -name = "typenum" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" - -[[package]] -name = "unicode-bidi" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" - -[[package]] -name = "unicode-ident" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" - -[[package]] -name = "unicode-normalization" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "url" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - -[[package]] -name = "value-setter" -version = "0.1.0" -source = "git+https://github.com/Sovereign-Labs/sovereign.git?rev=04d1591b4568cdfbebaa05eeee020c811080a9af#04d1591b4568cdfbebaa05eeee020c811080a9af" -dependencies = [ - "anyhow", - "borsh", - "serde", - "serde_json", - "sov-modules-api", - "sov-modules-macros", - "sov-state", - "sovereign-core", - "thiserror", -] - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "want" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -dependencies = [ - "log", - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.16", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d1985d03709c53167ce907ff394f5316aa22cb4e12761295c5dc57dacb6297e" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.16", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" - -[[package]] -name = "web-sys" -version = "0.3.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "webpki-roots" -version = "0.22.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" -dependencies = [ - "webpki", -] - -[[package]] -name = "which" -version = "4.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" -dependencies = [ - "either", - "libc", - "once_cell", -] - -[[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.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -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-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.0", -] - -[[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.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" -dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", -] - -[[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.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" - -[[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.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" - -[[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.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" - -[[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.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" - -[[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.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" - -[[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.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" - -[[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.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" - -[[package]] -name = "winnow" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" -dependencies = [ - "memchr", -] - -[[package]] -name = "winreg" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" -dependencies = [ - "winapi", -] - -[[package]] -name = "zeroize" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.16", -] - -[[package]] -name = "zstd-sys" -version = "2.0.8+zstd.1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" -dependencies = [ - "cc", - "libc", - "pkg-config", -] diff --git a/examples/demo-rollup/Makefile b/examples/demo-rollup/Makefile index f55b18370..72a387db2 100644 --- a/examples/demo-rollup/Makefile +++ b/examples/demo-rollup/Makefile @@ -93,11 +93,11 @@ endif build-sov-cli: cd ../demo-stf && cargo build --bin sov-cli -test-serialize-create-token: check-container-running build-sov-cli - $(SOV_CLI_REL_PATH) serialize-call ../test-data/keys/token_deployer_private_key.json Bank ../test-data/requests/create_token.json 0 +test-generate-create-token-tx: check-container-running build-sov-cli + $(SOV_CLI_REL_PATH) generate-transaction-from-json ../test-data/keys/token_deployer_private_key.json Bank ../test-data/requests/create_token.json 0 -test-build-blob-from-create-token: test-serialize-create-token - $(SOV_CLI_REL_PATH) make-blob ../test-data/requests/create_token.dat > ../test-data/requests/test_blob.dat +test-build-blob-from-create-token: test-generate-create-token-tx + $(SOV_CLI_REL_PATH) make-batch ../test-data/requests/create_token.dat > ../test-data/requests/test_blob.dat test-create-token: test-build-blob-from-create-token $(MAKE) submit-txn SERIALIZED_BLOB_PATH=../test-data/requests/test_blob.dat diff --git a/examples/demo-rollup/README.md b/examples/demo-rollup/README.md index 749cd9afc..db0b8fcb3 100644 --- a/examples/demo-rollup/README.md +++ b/examples/demo-rollup/README.md @@ -24,7 +24,7 @@ This is a demo full node running a simple Sovereign SDK rollup on [Celestia](htt - [Sanity Check: Creating a Token](#sanity-check-creating-a-token) - [How to Submit Transactions](#how-to-submit-transactions) - [1. Build `sov-cli`](#1-build-sov-cli) - - [2. Serialize the Call](#2-serialize-the-call) + - [2. Generate the Transaction](#2-generate-the-transaction) - [3. Bundle the Serialized Transaction](#3-bundle-the-serialized-transaction) - [4. Submit the Transaction](#4-submit-the-transaction) - [5. Verify the Token Supply](#5-verify-the-token-supply) @@ -67,28 +67,28 @@ understand how to build your own state transition function, check out at the doc 2. Switch to the `examples/demo-rollup` directory (which is where this `README.md` is located!). - ``` - $ cd examples/demo-rollup/ - ``` + ``` + $ cd examples/demo-rollup/ + ``` 3. Spin up a local Celestia instance as your DA layer. We've built a small Makefile to simplify that process: - ``` - $ make clean - $ make start # Make sure to run `make stop` when you're done with this demo! - ``` + ``` + $ make clean + $ make start # Make sure to run `make stop` when you're done with this demo! + ``` - If interested, you can check out what the Makefile does [here](#Makefile). - The above command will also modify some configuration files: + If interested, you can check out what the Makefile does [here](#Makefile). + The above command will also modify some configuration files: - ``` - $ git status - .. - .. - modified: rollup_config.toml - ``` + ``` + $ git status + .. + .. + modified: rollup_config.toml + ``` -### Start the Rollup Full Node +### Start the Rollup Full Node Now run the demo-rollup full node, as shown below. You will see it consuming blocks from the Celestia node running inside Docker: @@ -113,7 +113,7 @@ Leave it running while you proceed with the rest of the demo. After switching to a new terminal tab, let's submit our first transaction by creating a token: ``` -$ make test-create-token +$ make test-create-token ``` ...wait a few seconds and you will see the transaction receipt in the output of the demo-rollup full node: @@ -144,10 +144,13 @@ Main entry point for CLI Usage: sov-cli Commands: - serialize-call Serialize a call to a module. This creates a dat file containing the serialized transaction - make-blob - util Utility commands - help Print this message or the help of the given subcommand(s) + generate-transaction-from-json Serialize a call to a module. This creates a .dat file containing the serialized transaction + submit-transaction Submits transaction to sequencer + publish-batch Tells Sequencer to publish batch + make-batch Combine a list of files generated by GenerateTransaction into a blob for submission to Celestia + util Utility commands + generate-transaction Generate a transaction from the command line + help Print this message or the help of the given subcommand(s) Options: -h, --help Print help @@ -201,7 +204,9 @@ pub enum CallMessage { }, } ``` + In the above snippet, we can see that `CallMessage` in `Bank` support five different types of calls. The `sov-cli` has the ability to parse a JSON file that aligns with any of these calls and subsequently serialize them. The structure of the JSON file, which represents the call, closely mirrors that of the Enum member. Consider the `Transfer` message as an example: + ```rust Transfer { /// The address to which the tokens will be transferred. @@ -215,31 +220,32 @@ Here's an example of a JSON representing the above call: ```json { - "Transfer":{ - "to":"sov1zgfpyysjzgfpyysjzgfpyysjzgfpyysjzgfpyysjzgfpyysjzgfqve8h6h", - "coins":{ - "amount":200, - "token_address":"sov1zdwj8thgev2u3yyrrlekmvtsz4av4tp3m7dm5mx5peejnesga27svq9m72" + "Transfer": { + "to": "sov1zgfpyysjzgfpyysjzgfpyysjzgfpyysjzgfpyysjzgfpyysjzgfqve8h6h", + "coins": { + "amount": 200, + "token_address": "sov1zdwj8thgev2u3yyrrlekmvtsz4av4tp3m7dm5mx5peejnesga27svq9m72" } } } ``` -#### 2. Serialize the Call +#### 2. Generate the Transaction The JSON above is the contents of the file `examples/test-data/requests/transfer.json`. We'll use this transaction as our example for the rest of the tutorial. In order to serialize the transaction JSON to submit to our local Celestia node, we need to perform 2 operations: + - Serialize the JSON representation of the transaction. - Bundle serialized transaction files into a blob (since DA layers accept blobs which can contain multiple transactions). Note: we're able to make a `Transfer` call here because we already created the token as part of the sanity check above, using `make test-create-token`. -To serialize transactions you must use the `sov-cli serialize-call` subcommand, as shown below: +To generate transactions you can use the `sov-cli generate-transaction-from-json` subcommand, as shown below: ``` -$ ./target/debug/sov-cli serialize-call -h -Serialize a call to a module. This creates a dat file containing the serialized transaction +$ ./target/debug/sov-cli generate-transaction-from-json -h +Serialize a call to a module. This creates a .dat file containing the serialized transaction -Usage: sov-cli serialize-call +Usage: sov-cli generate-transaction-from-json Arguments: Path to the json file containing the private key of the sender @@ -247,28 +253,31 @@ Arguments: Path to the json file containing the parameters for a module call Nonce for the transaction ``` + For our test, we'll use the test private key located at `examples/test-data/keys/minter_private_key.json`. This private key also corresponds to the address used in the `minter_address` field of the `create_token.json` file. This was the address that `make test-create-token` minted the new tokens to. Let's go ahead and serialize the transaction: ``` -$ ./target/debug/sov-cli serialize-call ./examples/test-data/keys/minter_private_key.json Bank ./examples/test-data/requests/transfer.json 0 +$ ./target/debug/sov-cli generate-transaction-from-json ./examples/test-data/keys/minter_private_key.json Bank ./examples/test-data/requests/transfer.json 0 ``` + Once the above command executes successfully, there will be a file named `./examples/test-data/requests/transfer.dat`: ``` $ cat ./examples/test-data/requests/transfer.dat 5ef848746e8d2b9c27ee46210e185dc9f3b690d5cef42a13fb9c336bd40c798210bf7af613997f7af57c9681a242f5fe4121a1539ba4f5f32f14c49f978b990a7b758bf2e7670fafaf6bf0015ce0ff5aa802306fc7e3f45762853ffc37180fe64a0000000001fea6ac5b8751120fb62fff67b54d2eac66aef307c7dde1d394dea1e09e43dd44c800000000000000135d23aee8cb15c890831ff36db170157acaac31df9bba6cd40e7329e608eabd0000000000000000 ``` + The above is the hex representation of the serialized transaction. #### 3. Bundle the Serialized Transaction -After serializing your transactions (just one in this case), you must bundle them into a blob. You can use the `sov-cli make-blob` subcommand: +After serializing your transactions (just one in this case), you must bundle them into a blob. You can use the `sov-cli make-batch` subcommand: ``` -$ ./target/debug/sov-cli make-blob -h -Usage: sov-cli make-blob [PATH_LIST]... +$ ./target/debug/sov-cli make-batch -h +Usage: sov-cli make-batch [PATH_LIST]... Arguments: [PATH_LIST]... List of serialized transactions @@ -277,7 +286,7 @@ Arguments: Use the command below to store the serialized blob in `./examples/test-data/requests/tx_blob`: ``` -$ ./target/debug/sov-cli make-blob ./examples/test-data/requests/transfer.dat > ./examples/test-data/requests/tx_blob +$ ./target/debug/sov-cli make-batch ./examples/test-data/requests/transfer.dat > ./examples/test-data/requests/tx_blob $ cat ./examples/test-data/requests/tx_blob 01000000b60000005ef848746e8d2b9c27ee46210e185dc9f3b690d5cef42a13fb9c336bd40c798210bf7af613997f7af57c9681a242f5fe4121a1539ba4f5f32f14c49f978b990a7b758bf2e7670fafaf6bf0015ce0ff5aa802306fc7e3f45762853ffc37180fe64a0000000001fea6ac5b8751120fb62fff67b54d2eac66aef307c7dde1d394dea1e09e43dd44c800000000000000135d23aee8cb15c890831ff36db170157acaac31df9bba6cd40e7329e608eabd0000000000000000 ``` @@ -301,40 +310,41 @@ $ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method" ``` ### Makefile + `demo-rollup/Makefile` automates a number of things for convenience: -* Pull a docker container that runs a single instance of a celestia full node for a local setup -* The docker container is built with celestia 0.7.1 at present and is compatible with Jupiter (sovereign's celestia adapter) -* `make clean`: - * Stops any running containers with the name `sov-celestia-local` and also removes them - * Removes `demo-data` (or the configured path of the rollup database from rollup_config.toml) -* `make start`: - * Pulls the `sov-celestia-local:genesis-v0.7.1` docker image - * Performs a number of checks to ensure container is not already running - * Starts the container with the name `sov-celestia-local` - * Exposes the RPC port `26658` (as configured in the Makefile) - * Waits until the container is started - * It polls the running service inside the container for a specific RPC call, so there will be some errors printed while the container is starting up. This is ok - * Creates a key inside the docker container using `celestia-appd` that is bundled inside the container - the key is named `sequencer-da-address` - * The `sequencer-da-address` key is then funded with `10000000utia` configured by the `AMOUNT` variable in the Makefile - * The validator itself runs with the key name `validator` and is also accessible inside the container but this shouldn't be necessary - * Sets up the config - * `examples/const-rollup-config/src/lib.rs` is modified by the `make` command so that `pub const SEQUENCER_DA_ADDRESS` is set to the address of the key ``sov-celestia-local` that was created and funded in the previous steps - * `examples/demo-rollup/rollup_config.toml` is modified - - * `start_height` is set to `1` since this is a fresh start - * `celestia_rpc_auth_token` is set to the auth token retrieved by running the container bundled `celestia-appd` - * `/celestia bridge auth admin --node.store /bridge` is the command that is run inside the container to get the token - * `celestia_rpc_address` is set to point to `127.0.0.1` and the `RPC_PORT` configured in the Makefile (default 26658) - * The config is stashed and the changes are visible once you do a `git status` after running `make start` -* `make stop`: - * Stops the Celestia Docker image, if running. - * Deletes all contents of the demo-rollup database. -* For submitting transactions, we use `make submit-txn SERIALIZED_BLOB_PATH=....` - * This makes use of `celestia-appd tx blob PayForBlobs` inside the docker container to submit the blob to the full node - * `--from ` is set to `sequencer-da-address` whose address has been updated at `examples/const-rollup-config/src/lib.rs` - * The namespace of celestia that the blob needs to be submitted to is obtained by using `sov-cli util print-namespace` which reads the namespace from `examples/const-rollup-config/src/lib.rs` - * The content of the blob is read directly from the file passed in via the command line using `SERIALIZED_BLOB_PATH` - * `BLOB_TXN_FEE` is set to `300utia` and would likely not need to be modified +- Pull a docker container that runs a single instance of a celestia full node for a local setup +- The docker container is built with celestia 0.7.1 at present and is compatible with Jupiter (sovereign's celestia adapter) +- `make clean`: + - Stops any running containers with the name `sov-celestia-local` and also removes them + - Removes `demo-data` (or the configured path of the rollup database from rollup_config.toml) +- `make start`: + - Pulls the `sov-celestia-local:genesis-v0.7.1` docker image + - Performs a number of checks to ensure container is not already running + - Starts the container with the name `sov-celestia-local` + - Exposes the RPC port `26658` (as configured in the Makefile) + - Waits until the container is started + - It polls the running service inside the container for a specific RPC call, so there will be some errors printed while the container is starting up. This is ok + - Creates a key inside the docker container using `celestia-appd` that is bundled inside the container - the key is named `sequencer-da-address` + - The `sequencer-da-address` key is then funded with `10000000utia` configured by the `AMOUNT` variable in the Makefile + - The validator itself runs with the key name `validator` and is also accessible inside the container but this shouldn't be necessary + - Sets up the config + - `examples/const-rollup-config/src/lib.rs` is modified by the `make` command so that `pub const SEQUENCER_DA_ADDRESS` is set to the address of the key ``sov-celestia-local` that was created and funded in the previous steps + - `examples/demo-rollup/rollup_config.toml` is modified - + - `start_height` is set to `1` since this is a fresh start + - `celestia_rpc_auth_token` is set to the auth token retrieved by running the container bundled `celestia-appd` + - `/celestia bridge auth admin --node.store /bridge` is the command that is run inside the container to get the token + - `celestia_rpc_address` is set to point to `127.0.0.1` and the `RPC_PORT` configured in the Makefile (default 26658) + - The config is stashed and the changes are visible once you do a `git status` after running `make start` +- `make stop`: + - Stops the Celestia Docker image, if running. + - Deletes all contents of the demo-rollup database. +- For submitting transactions, we use `make submit-txn SERIALIZED_BLOB_PATH=....` + - This makes use of `celestia-appd tx blob PayForBlobs` inside the docker container to submit the blob to the full node + - `--from ` is set to `sequencer-da-address` whose address has been updated at `examples/const-rollup-config/src/lib.rs` + - The namespace of celestia that the blob needs to be submitted to is obtained by using `sov-cli util print-namespace` which reads the namespace from `examples/const-rollup-config/src/lib.rs` + - The content of the blob is read directly from the file passed in via the command line using `SERIALIZED_BLOB_PATH` + - `BLOB_TXN_FEE` is set to `300utia` and would likely not need to be modified ### Remote setup diff --git a/examples/demo-rollup/remote_setup.md b/examples/demo-rollup/remote_setup.md index 03b3f2572..c11e05377 100644 --- a/examples/demo-rollup/remote_setup.md +++ b/examples/demo-rollup/remote_setup.md @@ -1,5 +1,7 @@ ## Remote setup + This readme covers the steps necessary to setup the sovereign-sdk to work with a remote DA network which includes + 1. Running a celestia light client locally, on the same machine running the demo-rollup 2. A remote celestia network (Arabica testnet in this case) @@ -47,7 +49,7 @@ For testing, we can submit a transaction to the bank module to create a new toke 2. `cargo build --release --bin sov-cli` 3. `./target/release/sov-cli util create-private-key .` This is the rollup private key that's used to sign rollup transactions. It's important to make the distinction between this key and the sequencer private key. 4. `ls -lahtr | grep sov1` - you should see a new json file created containing the keypair. We will refer to this in later commands as `` -5. `./target/release/sov-cli serialize-call Bank examples/demo-stf/src/sov-cli/test_data/create_token.json 0` +5. `./target/release/sov-cli generate-transaction-from-json Bank examples/demo-stf/src/sov-cli/test_data/create_token.json 0` 6. Get the token address from the above the command (on Step 4) eg: `sov1jzvd95rjx7xpcdun2h8kyqee2z5r988h3wy4gsdn6ukc5ae04dvsrad3jj` 7. The binary serialized transaction is created at : `examples/demo-stf/src/sov-cli/test_data/create_token.dat` @@ -74,4 +76,4 @@ $ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method" {"jsonrpc":"2.0","result":{"amount":5000},"id":1} ``` -- params: should be the token address created in step 6 \ No newline at end of file +- params: should be the token address created in step 6 diff --git a/examples/demo-simple-stf/Cargo.toml b/examples/demo-simple-stf/Cargo.toml index ed332ad55..fbd146cad 100644 --- a/examples/demo-simple-stf/Cargo.toml +++ b/examples/demo-simple-stf/Cargo.toml @@ -12,6 +12,7 @@ publish = false anyhow = { workspace = true} serde = { workspace = true } sha2 = { workspace = true } +hex = { workspace = true } sov-rollup-interface = { path = "../../rollup-interface" } diff --git a/examples/demo-simple-stf/tests/stf_test.rs b/examples/demo-simple-stf/tests/stf_test.rs index 3feb4e0a1..bc4a423c3 100644 --- a/examples/demo-simple-stf/tests/stf_test.rs +++ b/examples/demo-simple-stf/tests/stf_test.rs @@ -1,4 +1,5 @@ use std::fmt::Display; +use std::str::FromStr; use demo_simple_stf::{ApplyBlobResult, CheckHashPreimageStf}; use sov_rollup_interface::mocks::{MockZkvm, TestBlob}; @@ -24,6 +25,18 @@ impl From<[u8; 32]> for DaAddress { } } +impl FromStr for DaAddress { + type Err = hex::FromHexError; + + fn from_str(s: &str) -> Result { + // Remove the "0x" prefix, if it exists. + let s = s.strip_prefix("0x").unwrap_or(s); + let mut addr = [0u8; 32]; + hex::decode_to_slice(s, &mut addr)?; + Ok(DaAddress { addr }) + } +} + impl<'a> TryFrom<&'a [u8]> for DaAddress { type Error = anyhow::Error; diff --git a/examples/demo-stf/Cargo.toml b/examples/demo-stf/Cargo.toml index a7e0ccb0c..950ba0835 100644 --- a/examples/demo-stf/Cargo.toml +++ b/examples/demo-stf/Cargo.toml @@ -11,7 +11,6 @@ publish = false [[bin]] name = "sov-cli" path = "src/sov-cli/main.rs" -required-features = ["native"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/examples/demo-stf/src/runtime.rs b/examples/demo-stf/src/runtime.rs index af7609a07..9b73db8d8 100644 --- a/examples/demo-stf/src/runtime.rs +++ b/examples/demo-stf/src/runtime.rs @@ -11,7 +11,7 @@ use sov_evm::query::{EvmRpcImpl, EvmRpcServer}; pub use sov_modules_api::default_context::DefaultContext; use sov_modules_api::macros::DefaultRuntime; #[cfg(feature = "native")] -use sov_modules_api::macros::{cli_parser, expose_rpc}; +use sov_modules_api::macros::{expose_rpc, CliWallet}; use sov_modules_api::{Context, DispatchCall, Genesis, MessageCodec}; #[cfg(feature = "native")] use sov_sequencer_registry::{SequencerRegistryRpcImpl, SequencerRegistryRpcServer}; @@ -54,11 +54,7 @@ use sov_value_setter::{ValueSetterRpcImpl, ValueSetterRpcServer}; /// instead of going through the DA layer. #[cfg(not(feature = "experimental"))] -#[cfg_attr( - feature = "native", - cli_parser(DefaultContext), - expose_rpc(DefaultContext) -)] +#[cfg_attr(feature = "native", derive(CliWallet), expose_rpc(DefaultContext))] #[derive(Genesis, DispatchCall, MessageCodec, DefaultRuntime)] #[serialization(borsh::BorshDeserialize, borsh::BorshSerialize)] pub struct Runtime { @@ -70,11 +66,7 @@ pub struct Runtime { } #[cfg(feature = "experimental")] -#[cfg_attr( - feature = "native", - cli_parser(DefaultContext), - expose_rpc(DefaultContext) -)] +#[cfg_attr(feature = "native", derive(CliWallet), expose_rpc(DefaultContext))] #[derive(Genesis, DispatchCall, MessageCodec, DefaultRuntime)] #[serialization(borsh::BorshDeserialize, borsh::BorshSerialize)] pub struct Runtime { @@ -83,5 +75,6 @@ pub struct Runtime { pub election: sov_election::Election, pub value_setter: sov_value_setter::ValueSetter, pub accounts: sov_accounts::Accounts, + #[cfg_attr(feature = "native", cli_skip)] pub evm: sov_evm::Evm, } diff --git a/examples/demo-stf/src/sov-cli/README.md b/examples/demo-stf/src/sov-cli/README.md index 750db39cf..24cd0030f 100644 --- a/examples/demo-stf/src/sov-cli/README.md +++ b/examples/demo-stf/src/sov-cli/README.md @@ -1,10 +1,10 @@ # sov-cli -* The sov-cli binary is used to generate serialized transactions that are ready for submitting to celestia (or other DA Layers) -* The sov-cli also has a "utils" subcommand to - * Generate a new private key - * View the public address of a private key - * View the derived token address +- The sov-cli binary is used to generate serialized transactions that are ready for submitting to celestia (or other DA Layers) +- The sov-cli also has a "utils" subcommand to + - Generate a new private key + - View the public address of a private key + - View the derived token address ``` Main entry point for CLI @@ -12,11 +12,13 @@ Main entry point for CLI Usage: sov-cli Commands: - serialize-call Serialize a call to a module. This creates a dat file containing the serialized transaction + generate-transaction-from-json Generate and serialize a call to a module. This creates a .dat file containing the serialized transaction util Utility commands help Print this message or the help of the given subcommand(s) ``` + ## Utils + ``` Usage: sov-cli util @@ -27,35 +29,44 @@ create-private-key Create a new private key help Print this message or the help of the given subcommand(s) ``` -* To submit a transaction, first generate a private key +- To submit a transaction, first generate a private key + ``` % cargo run --bin sov-cli util create-private-key . private key written to path: sov1693hp77wx0kp8um6dumlvtm3jzhckk74l7w4qtd5llhkpdtf0d6sm7my76.json ``` -* By default the file is named with the public key, but the file can be moved/renamed + +- By default the file is named with the public key, but the file can be moved/renamed + ``` % mv sov1693hp77wx0kp8um6dumlvtm3jzhckk74l7w4qtd5llhkpdtf0d6sm7my76.json my_private_key.json ``` -* The show-public-key subcommand can be used to view the public key of the private key + +- The show-public-key subcommand can be used to view the public key of the private key + ``` -% cargo run --bin sov-cli util show-public-key my_private_key.json +% cargo run --bin sov-cli util show-public-key my_private_key.json sov1693hp77wx0kp8um6dumlvtm3jzhckk74l7w4qtd5llhkpdtf0d6sm7my76 ``` -* You can view the token address of a new token that you wish to create using the derive-token-address subcommand. - * token addresses are derived deterministically using the following params - * : a string that you choose - * : the address submitting the transaction to create the token - * : a random number of your choosing + +- You can view the token address of a new token that you wish to create using the derive-token-address subcommand. + - token addresses are derived deterministically using the following params + - : a string that you choose + - : the address submitting the transaction to create the token + - : a random number of your choosing + ``` % cargo run --bin sov-cli util derive-token-address sov-test-token sov1693hp77wx0kp8um6dumlvtm3jzhckk74l7w4qtd5llhkpdtf0d6sm7my76 11 sov1g5htl6zvplygcsjfnt47tk6gmashsj8j9gu5jzg99wtm4ekuazrqaha4nj ``` -## serialize-call -* The `serialize-call` subcommand is used to generate serialized transactions for a module -* The modules that are supported by `sov-cli` are the ones that are part of the `Runtime` struct and the code to create the transaction is generated from the `cli_parser` macro that annotates `Runtime` +## Generate Transaction + +- The `generate-transaction-from-json` subcommand is used to generate serialized transactions for a module +- The modules that are supported by `sov-cli` are the ones that are part of the `Runtime` struct and the code to create the transaction is generated from the `derive(CliWallet)` macro that annotates `Runtime` + ```rust -#[cfg_attr(feature = "native", cli_parser(DefaultContext))] +#[cfg_attr(feature = "native", derive(CliWallet)] #[serialization(borsh::BorshDeserialize, borsh::BorshSerialize)] pub struct Runtime { pub sequencer: sov_sequencer_registry::Sequencer, @@ -65,32 +76,37 @@ pub struct Runtime { pub accounts: sov_accounts::Accounts, } ``` -* From the above code we can see which modules are supported, for an example we will generate transactions for the "Bank" module -* `serialize-call` takes 4 parameters + +- From the above code we can see which modules are supported, for an example we will generate transactions for the "Bank" module +- `generate-transaction-from-json` takes 4 parameters + ``` -Usage: sov-cli serialize-call [OPTIONS] +Usage: sov-cli generate-transaction-from-json [OPTIONS] Arguments: Path to the json file containing the private key of the sender Name of the module to generate the call. Modules defined in your Runtime are supported. (eg: Bank, Accounts) Path to the json file containing the parameters for a module call Nonce for the transaction - + Options: --format Output file format. borsh and hex are supported [default: hex] -h, --help Print help ``` - * `` is the path to the private key generated in utils. can also use an existing private key - * `` is based on the type of the fields in the `Runtime` struct. in the above example, the supported modules are `Bank`, `Sequencer`, `Election`, `Accounts`, `ValueSetter` - * `` this is the path to the json containing the CallMessage for your modules. - * `` Nonce which has to be non-duplicate and in increasing order. -* An example for the `` for the `Bank` module's `CreateToken` instruction is available at `sov-cli/test_data/create_token.json` -* The complete command for generating the create token transaction is +- `` is the path to the private key generated in utils. can also use an existing private key +- `` is based on the type of the fields in the `Runtime` struct. in the above example, the supported modules are `Bank`, `Sequencer`, `Election`, `Accounts`, `ValueSetter` +- `` this is the path to the json containing the CallMessage for your modules. +- `` Nonce which has to be non-duplicate and in increasing order. + +- An example for the `` for the `Bank` module's `CreateToken` instruction is available at `sov-cli/test_data/create_token.json` +- The complete command for generating the create token transaction is + ``` -demo-stf % cargo run --bin sov-cli serialize-call my_private_key.json Bank src/sov-cli/test_data/create_token.json 1 +demo-stf % cargo run --bin sov-cli generate-transaction-from-json my_private_key.json Bank src/sov-cli/test_data/create_token.json 1 ``` -* By default the file is formatted in `hex` and contains a blob ready for submission to celestia - the blob only contains a single transactions for now -* Other formats include `borsh` -* In order to know what the token is the `derive-token-address` command from the `utils` subcommand can be used \ No newline at end of file + +- By default the file is formatted in `hex` and contains a blob ready for submission to celestia - the blob only contains a single transactions for now +- Other formats include `borsh` +- In order to know what the token is the `derive-token-address` command from the `utils` subcommand can be used diff --git a/examples/demo-stf/src/sov-cli/main.rs b/examples/demo-stf/src/sov-cli/main.rs index e95ff7d73..e6d3a07fa 100644 --- a/examples/demo-stf/src/sov-cli/main.rs +++ b/examples/demo-stf/src/sov-cli/main.rs @@ -1,521 +1,12 @@ -use std::fs::File; -use std::io::{Read, Write}; -use std::path::{Path, PathBuf}; -use std::{fs, vec}; +#[cfg(feature = "native")] +mod native; -use anyhow::Context; -use borsh::BorshSerialize; -use clap::Parser; -use const_rollup_config::ROLLUP_NAMESPACE_RAW; -use demo_stf::runtime::cmd_parser; -use jsonrpsee::core::client::ClientT; -use jsonrpsee::http_client::HttpClientBuilder; -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::{AddressBech32, PublicKey, Spec}; -use sov_modules_stf_template::RawTx; -use sov_sequencer::SubmitTransaction; - -type C = DefaultContext; -type Address = ::Address; - -/// Main entry point for CLI -#[derive(Parser)] -#[clap(version = "1.0", author = "Sovereign")] -struct Cli { - #[clap(subcommand)] - /// Commands to perform operations - command: Commands, -} - -/// Main commands -#[derive(Parser)] -enum Commands { - /// Serialize a call to a module. - /// This creates a dat file containing the serialized transaction - SerializeCall { - /// Path to the json file containing the private key of the sender - sender_priv_key_path: String, - /// Name of the module to generate the call. - /// Modules defined in your Runtime are supported. - /// (eg: Bank, Accounts) - module_name: String, - /// Path to the json file containing the parameters for a module call - call_data_path: String, - /// Nonce for the transaction - nonce: u64, - }, - /// Submits transaction to sequencer - SubmitCall { - /// Path to the json file containing the private key of the sender - sender_priv_key_path: String, - /// Name of the module to generate the call. - /// Modules defined in your Runtime are supported. - /// (eg: Bank, Accounts) - module_name: String, - /// Path to the json file containing the parameters for a module call - call_data_path: String, - /// Nonce for the transaction - nonce: u64, - /// RPC endpoint with sequencer RPC - rpc_endpoint: String, - }, - /// Tells Sequencer to publish batch - PublishBatch { - /// RPC endpoint with sequencer RPC - rpc_endpoint: String, - }, - /// Combine a list of files generated by SerializeCall into a blob for submission to Celestia - MakeBlob { - /// List of files containing serialized transactions - path_list: Vec, - }, - /// Utility commands - Util(UtilArgs), -} - -/// Arguments for utility commands -#[derive(Parser)] -struct UtilArgs { - #[clap(subcommand)] - /// Commands under utilities - command: UtilCommands, -} - -/// List of utility commands -#[derive(Parser)] -enum UtilCommands { - /// Compute the address of a derived token. This follows a deterministic algorithm - DeriveTokenAddress { - /// Name of the token - token_name: String, - /// Address of the sender (can be obtained using the show-public-key subcommand) - sender_address: String, - /// A unique random number - salt: u64, - }, - /// Display the public key associated with a private key - ShowPublicKey { - /// Path to the json file containing the private key - private_key_path: String, - }, - /// Create a new private key - CreatePrivateKey { - /// Folder to store the new private key json file. The filename is auto-generated - priv_key_path: String, - }, - PrintNamespace, -} - -struct SerializedTx { - raw: RawTx, - #[allow(dead_code)] - sender: Address, -} - -#[derive(serde::Serialize, serde::Deserialize, Debug)] -struct PrivKeyAndAddress { - hex_priv_key: String, - address: Address, -} - -impl PrivKeyAndAddress { - fn generate() -> Self { - let priv_key = DefaultPrivateKey::generate(); - let address = priv_key.pub_key().to_address(); - Self { - hex_priv_key: priv_key.as_hex(), - address, - } - } - - fn generate_and_save_to_file(priv_key_path: &Path) -> anyhow::Result<()> { - let priv_key = Self::generate(); - let data = serde_json::to_string(&priv_key)?; - fs::create_dir_all(priv_key_path)?; - let path = Path::new(priv_key_path).join(format!("{}.json", priv_key.address)); - fs::write(&path, data)?; - println!( - "private key written to path: {}", - path.into_os_string().into_string().unwrap() - ); - Ok(()) - } -} - -impl SerializedTx { - fn new>( - sender_priv_key_path: P, - module_name: &str, - call_data_path: P, - nonce: u64, - ) -> anyhow::Result { - let sender_priv_key = Self::deserialize_priv_key(sender_priv_key_path)?; - let sender_address = sender_priv_key.pub_key().to_address(); - let message = Self::serialize_call_message(module_name, call_data_path)?; - - let tx = Transaction::::new_signed_tx(&sender_priv_key, message, nonce); - - Ok(SerializedTx { - raw: RawTx { - data: tx.try_to_vec()?, - }, - sender: sender_address, - }) - } - - fn deserialize_priv_key>( - sender_priv_key_path: P, - ) -> anyhow::Result { - let priv_key_data = std::fs::read_to_string(&sender_priv_key_path).with_context(|| { - format!( - "Failed to read private key from {:?}", - sender_priv_key_path.as_ref() - ) - })?; - - let sender_priv_key_data = serde_json::from_str::(&priv_key_data)?; - - Ok(DefaultPrivateKey::from_hex( - &sender_priv_key_data.hex_priv_key, - )?) - } - - fn serialize_call_message>( - module_name: &str, - call_data_path: P, - ) -> anyhow::Result> { - let call_data = std::fs::read_to_string(&call_data_path).with_context(|| { - format!( - "Failed to read call data from {:?}", - call_data_path.as_ref() - ) - })?; - cmd_parser(module_name, &call_data) - } -} - -fn serialize_call(command: &Commands) -> String { - if let Commands::SerializeCall { - sender_priv_key_path, - module_name, - call_data_path, - nonce, - } = command - { - let serialized = - SerializedTx::new(&sender_priv_key_path, module_name, &call_data_path, *nonce) - .unwrap_or_else(|e| panic!("Call message serialization error: {}", e)); - - hex::encode(serialized.raw.data) - } else { - Default::default() - } -} - -fn make_hex_blob(txs: impl Iterator) -> String { - // decode the hex string to bytes - let mut batch = vec![]; - for tx in txs { - let bytes = hex::decode(tx.as_bytes()).expect("Decoding failed"); - batch.push(bytes); - } - hex::encode(batch.try_to_vec().unwrap()) -} - -#[tokio::main] -pub async fn main() { - let cli = Cli::parse(); - - match cli.command { - Commands::SerializeCall { - ref call_data_path, .. - } => { - let raw_contents = serialize_call(&cli.command); - let mut bin_path = PathBuf::from(call_data_path); - bin_path.set_extension("dat"); - - let mut file = File::create(bin_path) - .unwrap_or_else(|e| panic!("Unable to crate .dat file: {}", e)); - file.write_all(raw_contents.as_bytes()) - .unwrap_or_else(|e| panic!("Unable to save .dat file: {}", e)); - } - Commands::SubmitCall { - sender_priv_key_path, - module_name, - call_data_path, - nonce, - rpc_endpoint, - } => { - let serialized = - SerializedTx::new(&sender_priv_key_path, &module_name, &call_data_path, nonce) - .unwrap_or_else(|e| panic!("Call message serialization error: {}", e)); - - let request = SubmitTransaction::new(serialized.raw.data); - let client = HttpClientBuilder::default().build(rpc_endpoint).unwrap(); - let response: Result = client.request("sequencer_acceptTx", [request]).await; - - println!("Transaction submit result: {:?}", response); - } - Commands::PublishBatch { rpc_endpoint } => { - let client = HttpClientBuilder::default().build(rpc_endpoint).unwrap(); - - let response: Result<(), _> = client.request("sequencer_publishBatch", [1u32]).await; - - // Print the result - println!("Publish batch result: {:?}", response); - } - Commands::MakeBlob { path_list } => { - let mut hex_encoded_txs = vec![]; - for path in path_list { - let mut f = File::open(path).expect("Unable to open file"); - let mut hex_string = String::new(); - f.read_to_string(&mut hex_string) - .expect("Unable to read the file"); - // push it into data_list - hex_encoded_txs.push(hex_string); - } - - let blob = make_hex_blob(hex_encoded_txs.into_iter()); - println!("{}", blob) - } - Commands::Util(util_args) => match util_args.command { - UtilCommands::DeriveTokenAddress { - token_name, - sender_address, - salt, - } => { - let sender_address = Address::from( - AddressBech32::try_from(sender_address.clone()).unwrap_or_else(|e| { - panic!( - "Failed to derive pub key from string: {}: {}", - sender_address, e - ) - }), - ); - let token_address = - sov_bank::get_token_address::(&token_name, sender_address.as_ref(), salt); - println!("{}", token_address); - } - - UtilCommands::ShowPublicKey { private_key_path } => { - let sender_priv_key = SerializedTx::deserialize_priv_key(private_key_path) - .expect("Failed to get private key from file"); - let sender_address: Address = sender_priv_key.pub_key().to_address(); - println!("{}", sender_address); - } - - UtilCommands::CreatePrivateKey { priv_key_path } => { - PrivKeyAndAddress::generate_and_save_to_file(priv_key_path.as_ref()) - .unwrap_or_else(|e| panic!("Create private key error: {}", e)); - } - UtilCommands::PrintNamespace => { - println!("{}", hex::encode(ROLLUP_NAMESPACE_RAW)); - } - }, - } +#[cfg(feature = "native")] +fn main() -> Result<(), anyhow::Error> { + native::main() } -#[cfg(test)] -mod test { - use borsh::BorshDeserialize; - use demo_stf::app::{DemoApp, DemoAppRunner}; - use demo_stf::genesis_config::{create_demo_config, DEMO_SEQUENCER_DA_ADDRESS, LOCKED_AMOUNT}; - use demo_stf::runner_config::Config; - use demo_stf::runtime::GenesisConfig; - use sov_modules_api::Address; - use sov_modules_stf_template::{Batch, RawTx, SequencerOutcome}; - use sov_rollup_interface::mocks::MockZkvm; - use sov_rollup_interface::services::stf_runner::StateTransitionRunner; - use sov_rollup_interface::stf::StateTransitionFunction; - use sov_state::WorkingSet; - - use super::*; - - type TestBlob = sov_rollup_interface::mocks::TestBlob
; - - fn new_test_blob(batch: Batch, address: &[u8]) -> TestBlob { - let address = Address::try_from(address).unwrap(); - let data = batch.try_to_vec().unwrap(); - TestBlob::new(data, address, [0; 32]) - } - - #[test] - fn test_sov_cli() { - // Tempdir is created here, so it will be deleted only after test is finished. - let tempdir = tempfile::tempdir().unwrap(); - let mut test_demo = TestDemo::with_path(tempdir.path().to_path_buf()); - let test_data = read_test_data(); - - execute_txs(&mut test_demo.demo, test_demo.config, test_data.data); - - // get minter balance - let balance = get_balance( - &mut test_demo.demo, - &test_data.token_deployer_address, - test_data.minter_address, - ); - - // The minted amount was 1000 and we transferred 200 and burned 300. - assert_eq!(balance, Some(500)) - } - - #[test] - fn test_create_token() { - let tempdir = tempfile::tempdir().unwrap(); - let mut test_demo = TestDemo::with_path(tempdir.path().to_path_buf()); - let test_tx = serialize_call(&Commands::SerializeCall { - sender_priv_key_path: make_test_path("keys/token_deployer_private_key.json") - .to_str() - .unwrap() - .into(), - module_name: "Bank".into(), - call_data_path: make_test_path("requests/create_token.json") - .to_str() - .unwrap() - .into(), - nonce: 0, - }); - - let mut test_data = read_test_data(); - test_data.data.pop(); - test_data.data.pop(); - - let batch = Batch { - txs: test_data.data.clone(), - }; - - println!("batch: {}", hex::encode(batch.try_to_vec().unwrap())); - - let blob = make_hex_blob(vec![test_tx].into_iter()); - println!("generated: {}", &blob); - - // let mut blob = hex::decode(blob.as_bytes()).expect("hex is valid"): - let blob = hex::decode(blob.as_bytes()).unwrap(); - - let batch = Batch::deserialize(&mut &blob[..]).expect("must be valid blob"); - execute_txs(&mut test_demo.demo, test_demo.config, batch.txs); - } - - // Test helpers - struct TestDemo { - config: GenesisConfig, - demo: DemoApp, - } - - impl TestDemo { - fn with_path(path: PathBuf) -> Self { - let value_setter_admin_private_key = DefaultPrivateKey::generate(); - let election_admin_private_key = DefaultPrivateKey::generate(); - - let genesis_config = create_demo_config( - LOCKED_AMOUNT + 1, - &value_setter_admin_private_key, - &election_admin_private_key, - ); - - let runner_config = Config { - storage: sov_state::config::Config { path }, - }; - - Self { - config: genesis_config, - demo: DemoAppRunner::::new(runner_config).stf, - } - } - } - - struct TestData { - token_deployer_address: Address, - minter_address: Address, - data: Vec, - } - - fn make_test_path>(path: P) -> PathBuf { - let mut sender_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - sender_path.push(".."); - sender_path.push("test-data"); - - sender_path.push(path); - - sender_path - } - - fn read_test_data() -> TestData { - let create_token = SerializedTx::new( - make_test_path("keys/token_deployer_private_key.json"), - "Bank", - make_test_path("requests/create_token.json"), - 0, - ) - .unwrap(); - - let transfer = SerializedTx::new( - make_test_path("keys/minter_private_key.json"), - "Bank", - make_test_path("requests/transfer.json"), - 0, - ) - .unwrap(); - - let burn = SerializedTx::new( - make_test_path("keys/minter_private_key.json"), - "Bank", - make_test_path("requests/burn.json"), - 1, - ) - .unwrap(); - - let data = vec![create_token.raw, transfer.raw, burn.raw]; - - TestData { - token_deployer_address: create_token.sender, - minter_address: transfer.sender, - data, - } - } - - fn execute_txs( - demo: &mut DemoApp, - config: GenesisConfig, - txs: Vec, - ) { - StateTransitionFunction::::init_chain(demo, config); - StateTransitionFunction::::begin_slot(demo, Default::default()); - - let apply_blob_outcome = StateTransitionFunction::::apply_blob( - demo, - &mut new_test_blob(Batch { txs }, &DEMO_SEQUENCER_DA_ADDRESS), - None, - ) - .inner; - assert_eq!( - SequencerOutcome::Rewarded(0), - apply_blob_outcome, - "Sequencer execution should have succeeded but failed", - ); - StateTransitionFunction::::end_slot(demo); - } - - fn get_balance( - demo: &mut DemoApp, - token_deployer_address: &Address, - user_address: Address, - ) -> Option { - let token_address = create_token_address(token_deployer_address); - - let mut working_set = WorkingSet::new(demo.current_storage.clone()); - - let balance = demo - .runtime - .bank - .balance_of(user_address, token_address, &mut working_set); - - balance.amount - } - - fn create_token_address(token_deployer_address: &Address) -> Address { - sov_bank::get_token_address::("sov-test-token", token_deployer_address.as_ref(), 11) - } +#[cfg(not(feature = "native"))] +fn main() -> Result<(), anyhow::Error> { + Err(anyhow::format_err!("CLI support is only available when the app is compiled with the 'native' flag. You can recompile with 'cargo build --features=native' to use the CLI")) } diff --git a/examples/demo-stf/src/sov-cli/native.rs b/examples/demo-stf/src/sov-cli/native.rs new file mode 100644 index 000000000..11d0ce446 --- /dev/null +++ b/examples/demo-stf/src/sov-cli/native.rs @@ -0,0 +1,545 @@ +use std::fs::File; +use std::io::{Read, Write}; +use std::path::{Path, PathBuf}; +use std::{fs, vec}; + +use anyhow::Context; +use borsh::BorshSerialize; +use clap::Parser; +use const_rollup_config::ROLLUP_NAMESPACE_RAW; +use demo_stf::runtime::{borsh_encode_cli_tx, parse_call_message_json, CliTransactionParser}; +use jsonrpsee::core::client::ClientT; +use jsonrpsee::http_client::HttpClientBuilder; +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::{AddressBech32, PublicKey, Spec}; +use sov_modules_stf_template::RawTx; +use sov_sequencer::SubmitTransaction; + +type C = DefaultContext; +type Address = ::Address; + +/// Main entry point for CLI +#[derive(Parser)] +#[clap(version = "1.0", author = "Sovereign")] +struct Cli { + #[clap(subcommand)] + /// Commands to perform operations + command: Commands, +} + +/// Main commands +#[derive(Parser)] +enum Commands { + /// Serialize a call to a module. + /// This creates a .dat file containing the serialized transaction + GenerateTransactionFromJson { + /// Path to the json file containing the private key of the sender + sender_priv_key_path: String, + /// Name of the module to generate the call. + /// Modules defined in your Runtime are supported. + /// (eg: Bank, Accounts) + module_name: String, + /// Path to the json file containing the parameters for a module call + call_data_path: String, + /// Nonce for the transaction + nonce: u64, + }, + /// Submits transaction to sequencer + SubmitTransaction { + /// Path to the json file containing the private key of the sender + sender_priv_key_path: String, + /// Name of the module to generate the call. + /// Modules defined in your Runtime are supported. + /// (eg: Bank, Accounts) + module_name: String, + /// Path to the json file containing the parameters for a module call + call_data_path: String, + /// Nonce for the transaction + nonce: u64, + /// RPC endpoint with sequencer RPC + rpc_endpoint: String, + }, + /// Tells Sequencer to publish batch + PublishBatch { + /// RPC endpoint with sequencer RPC + rpc_endpoint: String, + }, + /// Combine a list of files generated by GenerateTransaction into a blob for submission to Celestia + MakeBatch { + /// List of files containing serialized transactions + path_list: Vec, + }, + /// Utility commands + Util(UtilArgs), + /// Generate a transaction from the command line + #[clap(subcommand)] + GenerateTransaction(CliTransactionParser), +} + +#[derive(Parser)] +struct UtilArgs { + #[clap(subcommand)] + /// Commands under utilities + command: UtilCommands, +} + +/// List of utility commands +#[derive(Parser)] +enum UtilCommands { + /// Compute the address of a derived token. This follows a deterministic algorithm + DeriveTokenAddress { + /// Name of the token + token_name: String, + /// Address of the sender (can be obtained using the show-public-key subcommand) + sender_address: String, + /// A random number chosen by the token deployer + salt: u64, + }, + /// Display the public key associated with a private key + ShowPublicKey { + /// Path to the json file containing the private key + private_key_path: String, + }, + /// Create a new private key + CreatePrivateKey { + /// Folder to store the new private key json file. The filename is auto-generated + priv_key_path: String, + }, + PrintNamespace, +} + +struct SerializedTx { + raw: RawTx, + #[allow(dead_code)] + sender: Address, +} + +#[derive(serde::Serialize, serde::Deserialize, Debug)] +struct PrivKeyAndAddress { + hex_priv_key: String, + address: Address, +} + +impl PrivKeyAndAddress { + fn generate() -> Self { + let priv_key = DefaultPrivateKey::generate(); + let address = priv_key.pub_key().to_address(); + Self { + hex_priv_key: priv_key.as_hex(), + address, + } + } + + fn generate_and_save_to_file(priv_key_path: &Path) -> anyhow::Result<()> { + let priv_key = Self::generate(); + let data = serde_json::to_string(&priv_key)?; + fs::create_dir_all(priv_key_path)?; + let path = Path::new(priv_key_path).join(format!("{}.json", priv_key.address)); + fs::write(&path, data)?; + println!( + "private key written to path: {}", + path.into_os_string().into_string().unwrap() + ); + Ok(()) + } +} + +impl SerializedTx { + fn new>( + sender_priv_key_path: P, + module_name: &str, + call_data_path: P, + nonce: u64, + ) -> anyhow::Result { + let sender_priv_key = Self::deserialize_priv_key(sender_priv_key_path)?; + let sender_address = sender_priv_key.pub_key().to_address(); + let message = Self::serialize_call_message(module_name, call_data_path)?; + + let tx = Transaction::::new_signed_tx(&sender_priv_key, message, nonce); + + Ok(SerializedTx { + raw: RawTx { + data: tx.try_to_vec()?, + }, + sender: sender_address, + }) + } + + fn deserialize_priv_key>( + sender_priv_key_path: P, + ) -> anyhow::Result { + let priv_key_data = std::fs::read_to_string(&sender_priv_key_path).with_context(|| { + format!( + "Failed to read private key from {:?}", + sender_priv_key_path.as_ref() + ) + })?; + + let sender_priv_key_data = serde_json::from_str::(&priv_key_data)?; + + Ok(DefaultPrivateKey::from_hex( + &sender_priv_key_data.hex_priv_key, + )?) + } + + fn serialize_call_message>( + module_name: &str, + call_data_path: P, + ) -> anyhow::Result> { + let call_data = std::fs::read_to_string(&call_data_path).with_context(|| { + format!( + "Failed to read call data from {:?}", + call_data_path.as_ref() + ) + })?; + parse_call_message_json::(module_name, &call_data) + } +} + +fn serialize_call(command: &Commands) -> Result { + if let Commands::GenerateTransactionFromJson { + sender_priv_key_path, + module_name, + call_data_path, + nonce, + } = command + { + let serialized = + SerializedTx::new(&sender_priv_key_path, module_name, &call_data_path, *nonce) + .context("Call message serialization error")?; + + Ok(hex::encode(serialized.raw.data)) + } else { + Ok(Default::default()) + } +} + +fn make_hex_blob(txs: impl Iterator) -> Result { + // decode the hex string to bytes + let mut batch = vec![]; + for tx in txs { + let bytes = hex::decode(tx.as_bytes()) + .with_context(|| format!("Unable to decode {} as hex", tx))?; + batch.push(bytes); + } + Ok(hex::encode( + batch + .try_to_vec() + .expect("Serializing to a vector is infallible."), + )) +} + +#[tokio::main] +pub async fn main() -> Result<(), anyhow::Error> { + let cli = Cli::parse(); + + match cli.command { + Commands::GenerateTransactionFromJson { + ref call_data_path, .. + } => { + let raw_contents = serialize_call(&cli.command)?; + let mut bin_path = PathBuf::from(call_data_path); + bin_path.set_extension("dat"); + + let mut file = File::create(&bin_path) + .with_context(|| format!("Unable to create file {}", bin_path.display()))?; + file.write_all(raw_contents.as_bytes()) + .with_context(|| format!("Unable to save file {}", bin_path.display()))?; + } + Commands::SubmitTransaction { + sender_priv_key_path, + module_name, + call_data_path, + nonce, + rpc_endpoint, + } => { + let serialized = + SerializedTx::new(&sender_priv_key_path, &module_name, &call_data_path, nonce) + .context("Unable to serialize call transaction")?; + + let request = SubmitTransaction::new(serialized.raw.data); + let client = HttpClientBuilder::default().build(rpc_endpoint).unwrap(); + let response: String = client + .request("sequencer_acceptTx", [request]) + .await + .context("Unable to submit transaction")?; + + println!( + "Your transaction was submitted to the sequencer. Response: {}", + response + ); + } + Commands::PublishBatch { rpc_endpoint } => { + let client = HttpClientBuilder::default().build(rpc_endpoint).unwrap(); + + let response: String = client + .request("sequencer_publishBatch", [1u32]) + .await + .context("Unable to publish batch")?; + + // Print the result + println!( + "Your batch was submitted to the sequencer for publication. Response: {:?}", + response + ); + } + Commands::MakeBatch { path_list } => { + let mut hex_encoded_txs = vec![]; + for path in path_list { + let mut file = + File::open(&path).with_context(|| format!("Unable to create file {}", path))?; + let mut hex_string = String::new(); + file.read_to_string(&mut hex_string) + .context("Unable to read the file")?; + hex_encoded_txs.push(hex_string); + } + + let blob = make_hex_blob(hex_encoded_txs.into_iter())?; + println!("{}", blob) + } + Commands::Util(util_args) => match util_args.command { + UtilCommands::DeriveTokenAddress { + token_name, + sender_address, + salt, + } => { + let sender_address = Address::from( + AddressBech32::try_from(sender_address.clone()).with_context(|| { + format!( + "Could not parse {} as a valid bech32 address", + sender_address, + ) + })?, + ); + let token_address = + sov_bank::get_token_address::(&token_name, sender_address.as_ref(), salt); + println!("{}", token_address); + } + + UtilCommands::ShowPublicKey { private_key_path } => { + let sender_priv_key = SerializedTx::deserialize_priv_key(private_key_path) + .context("Failed to get private key from file")?; + let sender_address: Address = sender_priv_key.pub_key().to_address(); + println!("{}", sender_address); + } + + UtilCommands::CreatePrivateKey { priv_key_path } => { + PrivKeyAndAddress::generate_and_save_to_file(priv_key_path.as_ref()) + .context("Could not create private key")?; + } + UtilCommands::PrintNamespace => { + println!("{}", hex::encode(ROLLUP_NAMESPACE_RAW)); + } + }, + Commands::GenerateTransaction(cli_tx) => { + println!("{}", hex::encode(borsh_encode_cli_tx(cli_tx))); + } + } + + Ok(()) +} + +#[cfg(test)] +mod test { + use borsh::BorshDeserialize; + use demo_stf::app::{DemoApp, DemoAppRunner}; + use demo_stf::genesis_config::{create_demo_config, DEMO_SEQUENCER_DA_ADDRESS, LOCKED_AMOUNT}; + use demo_stf::runner_config::Config; + use demo_stf::runtime::GenesisConfig; + use sov_modules_api::Address; + use sov_modules_stf_template::{Batch, RawTx, SequencerOutcome}; + use sov_rollup_interface::mocks::MockZkvm; + use sov_rollup_interface::services::stf_runner::StateTransitionRunner; + use sov_rollup_interface::stf::StateTransitionFunction; + use sov_state::WorkingSet; + + use super::*; + + type TestBlob = sov_rollup_interface::mocks::TestBlob
; + + fn new_test_blob(batch: Batch, address: &[u8]) -> TestBlob { + let address = Address::try_from(address).unwrap(); + let data = batch.try_to_vec().unwrap(); + TestBlob::new(data, address, [0; 32]) + } + + #[test] + fn test_sov_cli() { + // Tempdir is created here, so it will be deleted only after test is finished. + let tempdir = tempfile::tempdir().unwrap(); + let mut test_demo = TestDemo::with_path(tempdir.path().to_path_buf()); + let test_data = read_test_data(); + + execute_txs(&mut test_demo.demo, test_demo.config, test_data.data); + + // get minter balance + let balance = get_balance( + &mut test_demo.demo, + &test_data.token_deployer_address, + test_data.minter_address, + ); + + // The minted amount was 1000 and we transferred 200 and burned 300. + assert_eq!(balance, Some(500)) + } + + #[test] + fn test_create_token() { + let tempdir = tempfile::tempdir().unwrap(); + let mut test_demo = TestDemo::with_path(tempdir.path().to_path_buf()); + let test_tx = serialize_call(&Commands::GenerateTransactionFromJson { + sender_priv_key_path: make_test_path("keys/token_deployer_private_key.json") + .to_str() + .unwrap() + .into(), + module_name: "Bank".into(), + call_data_path: make_test_path("requests/create_token.json") + .to_str() + .unwrap() + .into(), + nonce: 0, + }) + .unwrap(); + + let mut test_data = read_test_data(); + test_data.data.pop(); + test_data.data.pop(); + + let batch = Batch { + txs: test_data.data.clone(), + }; + + println!("batch: {}", hex::encode(batch.try_to_vec().unwrap())); + + let blob = make_hex_blob(vec![test_tx].into_iter()).unwrap(); + println!("generated: {}", &blob); + + let blob = hex::decode(blob.as_bytes()).unwrap(); + + let batch = Batch::deserialize(&mut &blob[..]).expect("must be valid blob"); + execute_txs(&mut test_demo.demo, test_demo.config, batch.txs); + } + + // Test helpers + struct TestDemo { + config: GenesisConfig, + demo: DemoApp, + } + + impl TestDemo { + fn with_path(path: PathBuf) -> Self { + let value_setter_admin_private_key = DefaultPrivateKey::generate(); + let election_admin_private_key = DefaultPrivateKey::generate(); + + let genesis_config = create_demo_config( + LOCKED_AMOUNT + 1, + &value_setter_admin_private_key, + &election_admin_private_key, + ); + + let runner_config = Config { + storage: sov_state::config::Config { path }, + }; + + Self { + config: genesis_config, + demo: DemoAppRunner::::new(runner_config).stf, + } + } + } + + struct TestData { + token_deployer_address: Address, + minter_address: Address, + data: Vec, + } + + fn make_test_path>(path: P) -> PathBuf { + let mut sender_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + sender_path.push(".."); + sender_path.push("test-data"); + + sender_path.push(path); + + sender_path + } + + fn read_test_data() -> TestData { + let create_token = SerializedTx::new( + make_test_path("keys/token_deployer_private_key.json"), + "Bank", + make_test_path("requests/create_token.json"), + 0, + ) + .unwrap(); + + let transfer = SerializedTx::new( + make_test_path("keys/minter_private_key.json"), + "Bank", + make_test_path("requests/transfer.json"), + 0, + ) + .unwrap(); + + let burn = SerializedTx::new( + make_test_path("keys/minter_private_key.json"), + "Bank", + make_test_path("requests/burn.json"), + 1, + ) + .unwrap(); + + let data = vec![create_token.raw, transfer.raw, burn.raw]; + + TestData { + token_deployer_address: create_token.sender, + minter_address: transfer.sender, + data, + } + } + + fn execute_txs( + demo: &mut DemoApp, + config: GenesisConfig, + txs: Vec, + ) { + StateTransitionFunction::::init_chain(demo, config); + StateTransitionFunction::::begin_slot(demo, Default::default()); + + let apply_blob_outcome = StateTransitionFunction::::apply_blob( + demo, + &mut new_test_blob(Batch { txs }, &DEMO_SEQUENCER_DA_ADDRESS), + None, + ) + .inner; + assert_eq!( + SequencerOutcome::Rewarded(0), + apply_blob_outcome, + "Sequencer execution should have succeeded but failed", + ); + StateTransitionFunction::::end_slot(demo); + } + + fn get_balance( + demo: &mut DemoApp, + token_deployer_address: &Address, + user_address: Address, + ) -> Option { + let token_address = create_token_address(token_deployer_address); + + let mut working_set = WorkingSet::new(demo.current_storage.clone()); + + let balance = demo + .runtime + .bank + .balance_of(user_address, token_address, &mut working_set); + + balance.amount + } + + fn create_token_address(token_deployer_address: &Address) -> Address { + sov_bank::get_token_address::("sov-test-token", token_deployer_address.as_ref(), 11) + } +} diff --git a/full-node/sov-sequencer/README.md b/full-node/sov-sequencer/README.md index 49ad0d64a..4dd6bd118 100644 --- a/full-node/sov-sequencer/README.md +++ b/full-node/sov-sequencer/README.md @@ -4,7 +4,6 @@ Simple implementation of based sequencer generic over batch builder and DA servi Exposes 2 RPC methods: - 1. `sequencer_acceptTx` where input is suppose to be signed and serialized transaction. This transaction is stored in mempool 2. `sequencer_publishBatch` without any input, which builds the batch using batch builder and publishes it on DA layer. @@ -12,7 +11,6 @@ Exposes 2 RPC methods: `sov-cli` from `demo-stf` crate has support for interacting with sov-sequencer. - Make sure that this tool is build ```bash @@ -30,18 +28,17 @@ When demo-rollup with enabled sequencer starts, it prints on which endpoint it l 2023-07-07T14:53:02.280562Z INFO sov_demo_rollup: Starting RPC server at 127.0.0.1:12345 ``` - Let's submit 3 transactions: `create token`, `mint` and `transfer`: ```bash # create token -./target/debug/sov-cli submit-call examples/demo-stf/src/sov-cli/test_data/token_deployer_private_key.json Bank examples/demo-stf/src/sov-cli/test_data/create_token.json 0 http://127.0.0.1:12345 +./target/debug/sov-cli submit-transaction examples/demo-stf/src/sov-cli/test_data/token_deployer_private_key.json Bank examples/demo-stf/src/sov-cli/test_data/create_token.json 0 http://127.0.0.1:12345 # mint -./target/debug/sov-cli submit-call examples/demo-stf/src/sov-cli/test_data/minter_private_key.json Bank examples/demo-stf/src/sov-cli/test_data/mint.json 0 http://127.0.0.1:12345 +./target/debug/sov-cli submit-transaction examples/demo-stf/src/sov-cli/test_data/minter_private_key.json Bank examples/demo-stf/src/sov-cli/test_data/mint.json 0 http://127.0.0.1:12345 # transfer -./target/debug/sov-cli submit-call examples/demo-stf/src/sov-cli/test_data/minter_private_key.json Bank examples/demo-stf/src/sov-cli/test_data/transfer.json 1 http://127.0.0.1:12345 +./target/debug/sov-cli submit-transaction examples/demo-stf/src/sov-cli/test_data/minter_private_key.json Bank examples/demo-stf/src/sov-cli/test_data/transfer.json 1 http://127.0.0.1:12345 ``` @@ -55,4 +52,4 @@ In order to submit transactions to DA layer, sequencer needs to publish them. Th ./target/debug/sov-cli publish-batch http://127.0.0.1:12345 ``` -After some time, processed transaction should appear in logs of running rollup \ No newline at end of file +After some time, processed transaction should appear in logs of running rollup diff --git a/module-system/module-implementations/examples/sov-election/Cargo.toml b/module-system/module-implementations/examples/sov-election/Cargo.toml index 1c8eef6ba..11692c5a5 100644 --- a/module-system/module-implementations/examples/sov-election/Cargo.toml +++ b/module-system/module-implementations/examples/sov-election/Cargo.toml @@ -15,6 +15,8 @@ publish = false [dependencies] anyhow = { workspace = true } borsh = { workspace = true, features = ["rc"] } +clap = { workspace = true, optional = true, features = ["derive"] } +hex = { workspace = true } jsonrpsee = { workspace = true, features = ["macros", "client-core", "server"], optional = true } schemars = { workspace = true, optional = true } serde = { workspace = true, optional = true } @@ -22,6 +24,7 @@ serde_json = { workspace = true, optional = true } sov-modules-api = { path = "../../../sov-modules-api", default-features = false, features = ["macros"] } sov-state = { path = "../../../sov-state", default-features = false } +sov-rollup-interface = { path = "../../../../rollup-interface" } [dev-dependencies] sov-modules-api = { path = "../../../sov-modules-api" } @@ -30,4 +33,4 @@ tempfile = { workspace = true } [features] default = ["native"] serde = ["dep:serde", "dep:serde_json"] -native = ["serde", "sov-modules-api/native", "dep:jsonrpsee", "dep:schemars"] +native = ["serde", "sov-modules-api/native", "dep:jsonrpsee", "dep:schemars", "dep:clap"] diff --git a/module-system/module-implementations/examples/sov-election/src/call.rs b/module-system/module-implementations/examples/sov-election/src/call.rs index 647a4755c..a5fa6569a 100644 --- a/module-system/module-implementations/examples/sov-election/src/call.rs +++ b/module-system/module-implementations/examples/sov-election/src/call.rs @@ -11,6 +11,7 @@ use super::Election; derive(serde::Serialize), derive(serde::Deserialize), derive(schemars::JsonSchema), + derive(sov_modules_api::macros::CliWalletArg), schemars(bound = "C: sov_modules_api::Context", rename = "CallMessage") )] #[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Debug, PartialEq, Clone)] diff --git a/module-system/module-implementations/examples/sov-value-setter/Cargo.toml b/module-system/module-implementations/examples/sov-value-setter/Cargo.toml index b193462f9..4bd3f006f 100644 --- a/module-system/module-implementations/examples/sov-value-setter/Cargo.toml +++ b/module-system/module-implementations/examples/sov-value-setter/Cargo.toml @@ -27,8 +27,9 @@ 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"] serde = ["dep:serde", "dep:serde_json"] -native = ["serde", "sov-modules-api/native", "dep:jsonrpsee", "dep:schemars"] +native = ["serde", "sov-modules-api/native", "dep:jsonrpsee", "dep:schemars", "dep:clap"] diff --git a/module-system/module-implementations/examples/sov-value-setter/src/call.rs b/module-system/module-implementations/examples/sov-value-setter/src/call.rs index 30497797c..3e7b3e5ee 100644 --- a/module-system/module-implementations/examples/sov-value-setter/src/call.rs +++ b/module-system/module-implementations/examples/sov-value-setter/src/call.rs @@ -1,6 +1,8 @@ use std::fmt::Debug; use anyhow::Result; +#[cfg(feature = "native")] +use sov_modules_api::macros::CliWalletArg; use sov_modules_api::CallResponse; use sov_state::WorkingSet; use thiserror::Error; @@ -12,10 +14,12 @@ use super::ValueSetter; 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 set SetValue(u32), } diff --git a/module-system/module-implementations/sov-accounts/Cargo.toml b/module-system/module-implementations/sov-accounts/Cargo.toml index 1c572081c..e6bf60a73 100644 --- a/module-system/module-implementations/sov-accounts/Cargo.toml +++ b/module-system/module-implementations/sov-accounts/Cargo.toml @@ -17,6 +17,8 @@ borsh = { workspace = true, features = ["rc"] } schemars = { workspace = true, optional = true } serde = { workspace = true, optional = true } serde_json = { workspace = true, optional = true } +thiserror = { workspace = true } +clap = { workspace = true, optional = true } jsonrpsee = { workspace = true, features = ["macros", "client-core", "server"], optional = true } sov-modules-api = { path = "../../sov-modules-api", version = "0.1", default-features = false, features = ["macros"] } @@ -30,4 +32,4 @@ tempfile = { workspace = true } [features] default = ["native"] serde = ["dep:serde", "dep:serde_json"] -native = ["serde", "sov-state/native", "sov-modules-api/native", "dep:jsonrpsee", "dep:schemars"] +native = ["serde", "sov-state/native", "sov-modules-api/native", "dep:jsonrpsee", "dep:schemars", "dep:clap"] diff --git a/module-system/module-implementations/sov-accounts/src/call.rs b/module-system/module-implementations/sov-accounts/src/call.rs index 2d94aa74f..b9027e5fe 100644 --- a/module-system/module-implementations/sov-accounts/src/call.rs +++ b/module-system/module-implementations/sov-accounts/src/call.rs @@ -13,6 +13,7 @@ pub const UPDATE_ACCOUNT_MSG: [u8; 32] = [1; 32]; derive(serde::Serialize), derive(serde::Deserialize), derive(schemars::JsonSchema), + derive(sov_modules_api::macros::CliWalletArg), schemars( bound = "C::PublicKey: ::schemars::JsonSchema, C::Signature: ::schemars::JsonSchema", rename = "CallMessage" diff --git a/module-system/module-implementations/sov-bank/Cargo.toml b/module-system/module-implementations/sov-bank/Cargo.toml index 6dc80f5ce..1b0226b6b 100644 --- a/module-system/module-implementations/sov-bank/Cargo.toml +++ b/module-system/module-implementations/sov-bank/Cargo.toml @@ -14,6 +14,7 @@ resolver = "2" [dependencies] anyhow = { workspace = true } borsh = { workspace = true, features = ["rc"] } +clap = { workspace = true, optional = true, features = ["derive"] } jsonrpsee = { workspace = true, features = ["macros", "client-core", "server"], optional = true } schemars = { workspace = true, optional = true } serde = { workspace = true, optional = true } @@ -21,7 +22,9 @@ serde_json = { workspace = true, optional = true } sov-modules-api = { path = "../../sov-modules-api", version = "0.1", default-features = false, features = ["macros"] } sov-state = { path = "../../sov-state", version = "0.1", default-features = false } - +sov-rollup-interface = { path = "../../../rollup-interface", version = "0.1" } +thiserror = { workspace = true } +hex = { workspace = true } [dev-dependencies] sov-modules-api = { path = "../../sov-modules-api", version = "0.1" } @@ -30,4 +33,5 @@ tempfile = { workspace = true } [features] default = ["native"] serde = ["dep:serde", "dep:serde_json"] -native = ["serde", "sov-state/native", "dep:jsonrpsee", "sov-modules-api/native", "dep:schemars"] +native = ["serde", "sov-state/native", "dep:jsonrpsee", "sov-modules-api/native", "dep:clap", "dep:schemars"] +cli = ["native"] diff --git a/module-system/module-implementations/sov-bank/src/call.rs b/module-system/module-implementations/sov-bank/src/call.rs index 9e8ce2e7b..f0f96d800 100644 --- a/module-system/module-implementations/sov-bank/src/call.rs +++ b/module-system/module-implementations/sov-bank/src/call.rs @@ -1,4 +1,6 @@ use anyhow::{bail, Context, Result}; +#[cfg(feature = "native")] +use sov_modules_api::macros::CliWalletArg; use sov_modules_api::CallResponse; use sov_state::WorkingSet; @@ -9,14 +11,12 @@ use crate::{Amount, Bank, Coins, Token}; feature = "native", derive(serde::Serialize), derive(serde::Deserialize), + derive(CliWalletArg), derive(schemars::JsonSchema), schemars(bound = "C::Address: ::schemars::JsonSchema", rename = "CallMessage") )] #[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Debug, PartialEq, Clone)] -pub enum CallMessage -where - C: sov_modules_api::Context, -{ +pub enum CallMessage { /// Creates a new token with the specified name and initial balance. CreateToken { /// Random value use to create a unique token address. diff --git a/module-system/module-implementations/sov-bank/src/token.rs b/module-system/module-implementations/sov-bank/src/token.rs index 24bf82fcb..1c1b87425 100644 --- a/module-system/module-implementations/sov-bank/src/token.rs +++ b/module-system/module-implementations/sov-bank/src/token.rs @@ -1,8 +1,14 @@ +#[cfg(feature = "native")] +use core::str::FromStr; use std::collections::HashSet; use std::fmt::Formatter; +#[cfg(feature = "native")] +use std::num::ParseIntError; use anyhow::{bail, Context, Result}; use sov_state::{Prefix, WorkingSet}; +#[cfg(feature = "native")] +use thiserror::Error; use crate::call::prefix_from_address_with_parent; @@ -12,6 +18,7 @@ pub type Amount = u64; feature = "native", derive(serde::Serialize), derive(serde::Deserialize), + derive(clap::Parser), derive(schemars::JsonSchema), schemars(bound = "C::Address: ::schemars::JsonSchema", rename = "Coins") )] @@ -21,6 +28,56 @@ pub struct Coins { pub token_address: C::Address, } +/// The errors that might arise when parsing a `Coins` struct from a string. +#[cfg(feature = "native")] +#[derive(Debug, Error)] +pub enum CoinsFromStrError { + /// The amount could not be parsed as a u64. + #[error("Could not parse {input} as a valid amount: {err}")] + InvalidAmount { input: String, err: ParseIntError }, + /// The input string was malformed, so the `amount` substring could not be extracted. + #[error("No amount was provided. Make sure that your input is in the format: amount,token_address. Example: 100,sov15vspj48hpttzyvxu8kzq5klhvaczcpyxn6z6k0hwpwtzs4a6wkvqmlyjd6")] + NoAmountProvided, + /// The token address could not be parsed as a valid address. + #[error("Could not parse {input} as a valid address: {err}")] + InvalidTokenAddress { input: String, err: anyhow::Error }, + /// The input string was malformed, so the `token_address` substring could not be extracted. + #[error("No token address was provided. Make sure that your input is in the format: amount,token_address. Example: 100,sov15vspj48hpttzyvxu8kzq5klhvaczcpyxn6z6k0hwpwtzs4a6wkvqmlyjd6")] + NoTokenAddressProvided, +} + +#[cfg(feature = "native")] +impl FromStr for Coins { + type Err = CoinsFromStrError; + + fn from_str(s: &str) -> Result { + let mut parts = s.splitn(2, ','); + + let amount_str = parts.next().ok_or(CoinsFromStrError::NoAmountProvided)?; + let token_address_str = parts + .next() + .ok_or(CoinsFromStrError::NoTokenAddressProvided)?; + + let amount = + amount_str + .parse::() + .map_err(|err| CoinsFromStrError::InvalidAmount { + input: amount_str.into(), + err, + })?; + let token_address = C::Address::from_str(token_address_str).map_err(|err| { + CoinsFromStrError::InvalidTokenAddress { + input: token_address_str.into(), + err, + } + })?; + + Ok(Self { + amount, + token_address, + }) + } +} impl std::fmt::Display for Coins { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { // implement Display for Coins diff --git a/module-system/module-implementations/sov-evm/Cargo.toml b/module-system/module-implementations/sov-evm/Cargo.toml index 1872d7b65..310043e13 100644 --- a/module-system/module-implementations/sov-evm/Cargo.toml +++ b/module-system/module-implementations/sov-evm/Cargo.toml @@ -20,6 +20,7 @@ sov-state = { path = "../../sov-state", version = "0.1", default-features = fals anyhow = { workspace = true } bytes = { workspace = true } schemars = { workspace = true, optional = true } +clap = { workspace = true, optional = true } serde = { workspace = true, optional = true } serde_json = { workspace = true, optional = true } borsh = { workspace = true, features = ["rc"] } @@ -52,5 +53,5 @@ sov-modules-api = { path = "../../sov-modules-api", version = "0.1", features = [features] default = ["native"] serde = ["dep:serde", "dep:serde_json"] -native = ["serde", "sov-state/native", "dep:jsonrpsee", "dep:schemars", "sov-modules-api/native"] +native = ["serde", "sov-state/native", "dep:jsonrpsee", "dep:schemars", "sov-modules-api/native", "dep:clap"] experimental = ["native"] diff --git a/module-system/module-implementations/sov-sequencer-registry/Cargo.toml b/module-system/module-implementations/sov-sequencer-registry/Cargo.toml index 4f4ea774e..b0e111f4e 100644 --- a/module-system/module-implementations/sov-sequencer-registry/Cargo.toml +++ b/module-system/module-implementations/sov-sequencer-registry/Cargo.toml @@ -19,6 +19,7 @@ tempfile = { workspace = true } [dependencies] anyhow = { workspace = true } +clap = { workspace = true, optional = true } sov-bank = { path = "../sov-bank", version = "0.1", default-features = false } sov-modules-api = { path = "../../sov-modules-api", version = "0.1", default-features = false, features = ["macros"] } sov-state = { path = "../../sov-state", version = "0.1", default-features = false } @@ -32,4 +33,4 @@ jsonrpsee = { workspace = true, features = ["macros", "client-core", "server"], [features] default = ["native"] serde = ["dep:serde", "dep:serde_json"] -native = ["serde", "sov-modules-api/native", "sov-state/native", "sov-bank/native", "dep:jsonrpsee", "dep:schemars"] +native = ["serde", "sov-modules-api/native", "sov-state/native", "sov-bank/native", "dep:jsonrpsee", "dep:schemars", "dep:clap"] diff --git a/module-system/module-implementations/sov-sequencer-registry/src/call.rs b/module-system/module-implementations/sov-sequencer-registry/src/call.rs index f869f9b84..dea63bd01 100644 --- a/module-system/module-implementations/sov-sequencer-registry/src/call.rs +++ b/module-system/module-implementations/sov-sequencer-registry/src/call.rs @@ -1,4 +1,6 @@ use anyhow::{bail, Result}; +#[cfg(feature = "native")] +use sov_modules_api::macros::CliWalletArg; use sov_modules_api::CallResponse; use sov_state::WorkingSet; @@ -9,6 +11,7 @@ use crate::SequencerRegistry; feature = "native", derive(serde::Serialize), derive(serde::Deserialize), + derive(CliWalletArg), derive(schemars::JsonSchema) )] #[derive(borsh::BorshDeserialize, borsh::BorshSerialize, Debug, PartialEq, Clone)] diff --git a/module-system/module-schemas/schemas/sov-value-setter.json b/module-system/module-schemas/schemas/sov-value-setter.json index 7c18d0dcb..915c3e4c0 100644 --- a/module-system/module-schemas/schemas/sov-value-setter.json +++ b/module-system/module-schemas/schemas/sov-value-setter.json @@ -4,6 +4,7 @@ "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" diff --git a/module-system/sov-modules-api/Cargo.toml b/module-system/sov-modules-api/Cargo.toml index 0b351f8ec..246aea51f 100644 --- a/module-system/sov-modules-api/Cargo.toml +++ b/module-system/sov-modules-api/Cargo.toml @@ -23,16 +23,18 @@ sha2 = { workspace = true } bech32 = { workspace = true } derive_more = { workspace = true } serde_json = { workspace = true } +hex = { workspace = true, optional = true } +clap = { workspace = true, optional = true } schemars = { workspace = true, optional = true, features = [] } ed25519-dalek = { version = "1.0.1", default-features = false, features = ["alloc", "u64_backend"] } rand = { version = "0.7", optional = true } -hex = { workspace = true, optional = true } + [dev-dependencies] serde_json = { workspace = true } [features] default = ["native", "macros"] -native = ["sov-state/native", "rand", "hex", "schemars", "ed25519-dalek/default"] +native = ["sov-state/native", "rand", "hex", "schemars", "ed25519-dalek/default", "clap"] macros = ["sov-modules-macros"] diff --git a/module-system/sov-modules-api/src/default_context.rs b/module-system/sov-modules-api/src/default_context.rs index 5fd07fa77..6accfba65 100644 --- a/module-system/sov-modules-api/src/default_context.rs +++ b/module-system/sov-modules-api/src/default_context.rs @@ -37,6 +37,7 @@ impl Context for DefaultContext { } #[derive(Clone, Debug, PartialEq)] +#[cfg_attr(feature = "native", derive(Serialize, Deserialize))] pub struct ZkDefaultContext { pub sender: Address, } diff --git a/module-system/sov-modules-api/src/default_signature.rs b/module-system/sov-modules-api/src/default_signature.rs index 1a6c3c882..538080566 100644 --- a/module-system/sov-modules-api/src/default_signature.rs +++ b/module-system/sov-modules-api/src/default_signature.rs @@ -1,3 +1,6 @@ +#[cfg(feature = "native")] +use std::str::FromStr; + use borsh::{BorshDeserialize, BorshSerialize}; use ed25519_dalek::ed25519::signature::Signature as DalekSignatureTrait; use ed25519_dalek::{ @@ -191,3 +194,27 @@ fn map_error(e: ed25519_dalek::SignatureError) -> std::io::Error { fn map_error(_e: ed25519_dalek::SignatureError) -> std::io::Error { std::io::Error::new(std::io::ErrorKind::Other, "Signature error") } + +#[cfg(feature = "native")] +impl FromStr for DefaultPublicKey { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + let bytes = hex::decode(s)?; + let pub_key = DalekPublicKey::from_bytes(&bytes) + .map_err(|_| anyhow::anyhow!("Invalid public key"))?; + Ok(DefaultPublicKey { pub_key }) + } +} + +#[cfg(feature = "native")] +impl FromStr for DefaultSignature { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + let bytes = hex::decode(s)?; + let msg_sig = + DalekSignature::from_bytes(&bytes).map_err(|_| anyhow::anyhow!("Invalid signature"))?; + Ok(DefaultSignature { msg_sig }) + } +} diff --git a/module-system/sov-modules-api/src/lib.rs b/module-system/sov-modules-api/src/lib.rs index 85c075b85..6e5717dd5 100644 --- a/module-system/sov-modules-api/src/lib.rs +++ b/module-system/sov-modules-api/src/lib.rs @@ -25,12 +25,15 @@ pub use sov_modules_macros::{ /// Procedural macros to assist with creating new modules. #[cfg(feature = "macros")] pub mod macros { - pub use sov_modules_macros::{cli_parser, expose_rpc, rpc_gen, DefaultRuntime, MessageCodec}; + pub use sov_modules_macros::{expose_rpc, rpc_gen, CliWallet, CliWalletArg, DefaultRuntime}; } use core::fmt::{self, Debug, Display}; +use std::str::FromStr; use borsh::{BorshDeserialize, BorshSerialize}; +#[cfg(feature = "native")] +pub use clap; pub use dispatch::{DispatchCall, Genesis}; pub use error::Error; pub use prefix::Prefix; @@ -70,6 +73,16 @@ impl<'a> TryFrom<&'a [u8]> for Address { } } +impl FromStr for Address { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + AddressBech32::from_str(s) + .map_err(|e| anyhow::anyhow!(e)) + .map(|addr_bech32| addr_bech32.into()) + } +} + impl From<[u8; 32]> for Address { fn from(addr: [u8; 32]) -> Self { Self { addr } @@ -137,11 +150,13 @@ pub trait Spec { type Address: AddressTrait + BorshSerialize + BorshDeserialize + + Sync // Do we always need this, even when the module does not have a JSON // Schema? That feels a bit wrong. + ::schemars::JsonSchema + Into - + From; + + From + + FromStr; /// The Address type used on the rollup. Typically calculated as the hash of a public key. #[cfg(not(feature = "native"))] @@ -162,7 +177,8 @@ pub trait Spec { + for<'a> Deserialize<'a> + ::schemars::JsonSchema + Send - + Sync; + + Sync + + FromStr; #[cfg(not(feature = "native"))] type PublicKey: borsh::BorshDeserialize @@ -185,15 +201,21 @@ pub trait Spec { + Eq + Clone + Debug + + Send + + Sync + + FromStr + Signature; + /// The digital signature scheme used by the rollup #[cfg(not(feature = "native"))] type Signature: borsh::BorshDeserialize + borsh::BorshSerialize + Eq + Clone + Debug - + Signature; + + Signature + + Send + + Sync; /// A structure containing the non-deterministic inputs from the prover to the zk-circuit type Witness: Witness; @@ -206,7 +228,7 @@ pub trait Spec { /// Context objects also implement the [`Spec`] trait, which specifies the types to be used in this /// instance of the state transition function. By making modules generic over a `Context`, developers /// can easily update their cryptography to conform to the needs of different zk-proof systems. -pub trait Context: Spec + Clone + Debug + PartialEq { +pub trait Context: Spec + Clone + Debug + PartialEq + 'static { /// Sender of the transaction. fn sender(&self) -> &Self::Address; @@ -290,3 +312,13 @@ pub trait RpcRunner { type Context: Context; fn get_storage(&self) -> ::Storage; } + +/// This trait is implemented by types that can be used as arguments in the sov-cli wallet. +/// The recommended way to implement this trait is using the provided derive macro (`#[derive(CliWalletArg)]`). +/// Currently, this trait is a thin wrapper around [`clap::Parser`] +#[cfg(feature = "native")] +pub trait CliWalletArg: From { + /// The type that is used to represent this type in the CLI. Typically, + /// this type implements the clap::Subcommand trait. + type CliStringRepr; +} diff --git a/module-system/sov-modules-macros/Cargo.toml b/module-system/sov-modules-macros/Cargo.toml index 1e154450a..894b29625 100644 --- a/module-system/sov-modules-macros/Cargo.toml +++ b/module-system/sov-modules-macros/Cargo.toml @@ -26,7 +26,9 @@ trybuild = "1.0" sov-modules-api = { path = "../sov-modules-api", version = "0.1", default-features = false } sov-state = { path = "../sov-state", version = "0.1", default-features = false } -sov-bank = { path = "../module-implementations/sov-bank", version = "0.1" } +sov-bank = { path = "../module-implementations/sov-bank", version = "0.1", features = ["native"] } +clap = { workspace = true } +serde = { workspace = true } [dependencies] anyhow = { workspace = true } diff --git a/module-system/sov-modules-macros/src/cli_parser.rs b/module-system/sov-modules-macros/src/cli_parser.rs index 5a33138f6..24c693d45 100644 --- a/module-system/sov-modules-macros/src/cli_parser.rs +++ b/module-system/sov-modules-macros/src/cli_parser.rs @@ -1,7 +1,9 @@ use quote::{format_ident, quote}; -use syn::{DeriveInput, Path, PathArguments, Type}; +use syn::punctuated::Punctuated; +use syn::spanned::Spanned; +use syn::{Data, DataEnum, DeriveInput, Fields, GenericParam, Ident, PathArguments, Type}; -use crate::common::StructFieldExtractor; +use crate::common::{extract_generic_type_bounds, extract_ident, StructFieldExtractor}; pub(crate) struct CliParserMacro { field_extractor: StructFieldExtractor, @@ -14,83 +16,206 @@ impl CliParserMacro { } } - pub(crate) fn cli_parser( + pub(crate) fn cli_macro( &self, input: DeriveInput, - context_type: Type, ) -> Result { let DeriveInput { - attrs, - vis, ident, generics, data, + .. } = input; - let fields = self.field_extractor.get_fields_from_struct(&data)?; + let generic_bounds = extract_generic_type_bounds(&generics); - let match_arms: Vec<_> = fields - .clone() - .into_iter() - .map(|field| { - let field_name = field.ident.clone(); - let field_name_string = field_name.to_string(); - let encode_function_name = format_ident!("encode_{}_call", field_name_string); - - // TODO: - // For the initial version, before complicating the macro, - // we're assuming that each module type in Runtime only has - // one generic. we're removing that and appending the concrete - // that's passed in from the macro. - // We need to fix this so that: - // 1. Determine which generic has the Context bound - // 2. Identify only that generic from the module type and replace it - // 3. Retain other generics - - // Extract the type name - let type_path = match &field.ty { - Type::Path(type_path) => { - let mut segments = type_path.path.segments.clone(); - let last = segments.last_mut().expect("Impossible happened! A type path has no segments"); - last.arguments = PathArguments::None; - Path { segments, ..type_path.path.clone() } - }, - _ => return Err(syn::Error::new_spanned(field.ident, "expected a type path")), - }; - - let type_name_string = type_path.segments.last().unwrap().ident.to_string(); - - Ok(quote! { - #type_name_string => Ok({ - #ident::<#context_type>::#encode_function_name( - serde_json::from_str::<<#type_path<#context_type> as sov_modules_api::Module>::CallMessage>(&call_data)? - ) - }), - }) - }) - .collect::, _>>()?; - - // Create tokens for original struct fields - let original_struct_fields: Vec<_> = fields - .into_iter() - .map(|field| { - let field_name = field.ident; - let field_type = field.ty; - let field_vis = field.vis; - - quote! { - #field_vis #field_name: #field_type + // We assume that the `Context` type is the first generic type parameter + // Since macro expansion happens before type inference, there is no reliable way + // to extract the `Context` type without making this assumption. (i.e. we can't look for a type + // that implements `sov_modules_api::Context`, because that name might have been aliased) + let context_type = generics + .params + .iter() + .find_map(|item| { + if let GenericParam::Type(type_param) = item { + Some(type_param) + } else { + None } }) - .collect(); + .ok_or(syn::Error::new_spanned( + &generics, + "a runtime must be generic over a sov_modules_api::Context to derive CliWallet", + ))? + .ident + .clone(); + + let mut module_command_arms = vec![]; + let mut module_args = vec![]; + let mut match_arms = vec![]; + let mut parse_match_arms = vec![]; + let mut deserialize_constraints: Vec = vec![]; - let cmd_parser_tokens = quote! { - #(#attrs)* - #vis struct #ident #generics { - #(#original_struct_fields),* + // Loop over the fields + 'outer: for field in &fields { + // Skip fields with the attribute cli_skip + for attr in field.attrs.iter() { + if attr.path.is_ident("cli_skip") { + continue 'outer; + } } - pub fn cmd_parser(module_name: &str, call_data: &str) -> anyhow::Result> { + // For each type path we encounter, we need to extract the generic type parameters for that field + // and construct a `Generics` struct that contains the bounds for each of those generic type parameters. + if let syn::Type::Path(type_path) = &field.ty { + let mut module_path = type_path.path.clone(); + if let Some(segment) = module_path.segments.last_mut() { + let field_generic_types = &segment.arguments; + let field_generics_with_bounds = match field_generic_types { + PathArguments::AngleBracketed(angle_bracketed_data) => { + let mut args_with_bounds = + Punctuated::::new(); + for generic_arg in &angle_bracketed_data.args { + if let syn::GenericArgument::Type(syn::Type::Path(type_path)) = + generic_arg + { + let ident = extract_ident(type_path); + let bounds = + generic_bounds.get(type_path).cloned().unwrap_or_default(); + + // Construct a "type param" with the appropriate bounds. This corresponds to a syntax + // tree like `T: Trait1 + Trait2` + let generic_type_param_with_bounds = syn::TypeParam { + attrs: Vec::new(), + ident: ident.clone(), + colon_token: Some(syn::token::Colon { + spans: [type_path.span()], + }), + bounds: bounds.clone(), + eq_token: None, + default: None, + }; + args_with_bounds + .push(GenericParam::Type(generic_type_param_with_bounds)) + } + } + // Construct a `Generics` struct with the generic type parameters and their bounds. + // This corresponds to a syntax tree like `` + syn::Generics { + lt_token: Some(syn::token::Lt { + spans: [type_path.span()], + }), + params: args_with_bounds, + gt_token: Some(syn::token::Gt { + spans: [type_path.span()], + }), + where_clause: None, + } + } + // We don't need to do anything if the generic type parameters are not angle bracketed + _ => Default::default(), + }; + + let module_ident = segment.ident.clone(); + let module_args_ident = format_ident!("{}Args", module_ident); + module_command_arms.push(quote! { + #module_ident(#module_args_ident #field_generic_types) + }); + module_args.push(quote! { + #[derive(::clap::Parser)] + pub struct #module_args_ident #field_generics_with_bounds { + #[clap(subcommand)] + /// Commands under #module + command: <<#module_path as ::sov_modules_api::Module>::CallMessage as ::sov_modules_api::CliWalletArg>::CliStringRepr, + } + }); + + let field_name = field.ident.clone(); + let field_name_string = field_name.to_string(); + let encode_function_name = format_ident!("encode_{}_call", field_name_string); + + let type_name_string = match &field.ty { + Type::Path(type_path) => extract_ident(type_path).to_string(), + _ => { + return Err(syn::Error::new_spanned( + field.ident.clone(), + "expected a type path", + )) + } + }; + + // Build the `match` arm for the CLI's `clap` parse function + parse_match_arms.push(quote! { + CliTransactionParser::#module_ident(mod_args) => { + let command_as_call_message: <#module_path as ::sov_modules_api::Module>::CallMessage = mod_args.command.into(); + #ident::<#context_type>::#encode_function_name( + command_as_call_message + ) + }, + }); + + // Build a constraint requiring that all call messages support serde deserialization + let deserialization_constraint = { + let type_path: syn::TypePath = syn::parse_quote! {<#module_path as ::sov_modules_api::Module>::CallMessage }; + let bounds: syn::TypeParamBound = + syn::parse_quote! {::serde::de::DeserializeOwned}; + syn::WherePredicate::Type(syn::PredicateType { + lifetimes: None, + bounded_ty: syn::Type::Path(type_path), + colon_token: Default::default(), + bounds: vec![bounds].into_iter().collect(), + }) + }; + deserialize_constraints.push(deserialization_constraint); + + // Build the `match` arms for the CLI's json parser + match_arms.push(quote! { + #type_name_string => Ok({ + #ident::<#context_type>::#encode_function_name( + ::serde_json::from_str::<<#module_path as ::sov_modules_api::Module>::CallMessage>(&call_data)? + ) + }), + }); + } + } + } + + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + let where_clause_with_deserialize_bounds = match where_clause { + Some(where_clause) => { + let mut result = where_clause.clone(); + result + .predicates + .extend(deserialize_constraints.into_iter()); + result + } + None => syn::parse_quote! { + where #(#deserialize_constraints),* + }, + }; + // Merge and generate the new code + let expanded = quote! { + /// A CLI parser for transactions which can be sent to the runtime + #[derive(::clap::Parser)] + pub enum CliTransactionParser #generics { + #( #module_command_arms, )* + } + #( #module_args )* + + /// Borsh encode a transaction parsed from the CLI + pub fn borsh_encode_cli_tx #impl_generics (cmd: CliTransactionParser #ty_generics) -> ::std::vec::Vec + #where_clause { + use ::borsh::BorshSerialize; + match cmd { + #(#parse_match_arms)* + _ => panic!("unknown module name"), + } + } + + /// Attempts to parse the provided call data as a [`sov_modules_api::Module::CallMessage`] for the given module. + pub fn parse_call_message_json #impl_generics (module_name: &str, call_data: &str) -> ::anyhow::Result> + #where_clause_with_deserialize_bounds + { match module_name { #(#match_arms)* _ => panic!("unknown module name"), @@ -98,6 +223,154 @@ impl CliParserMacro { } }; - Ok(cmd_parser_tokens.into()) + Ok(expanded.into()) } } + +pub(crate) fn derive_cli_wallet_arg( + ast: DeriveInput, +) -> Result { + let item_name = &ast.ident; + let generics = &ast.generics; + let item_with_named_fields_ident = Ident::new( + &format!("{}WithNamedFields", item_name), + proc_macro2::Span::call_site(), + ); + let is_generic = !generics.params.is_empty(); + + let (named_type_defn, conversion_logic) = match &ast.data { + // Creating an enum "_WithNamedFields" which is identical to the first enum + // except that all fields are named. + Data::Enum(DataEnum { variants, .. }) => { + // For each variant of the enum, we have to specify two things: + // 1. The structure of the "named" version of the variant + // 2. How to convert from the "named" version of the variant to the original version + let mut variants_with_named_fields = vec![]; + let mut convert_cases = vec![]; + + for variant in variants { + let variant_name = &variant.ident; + let variant_docs = variant + .attrs + .iter() + .filter(|attr| attr.path.is_ident("doc")) + .collect::>(); + + let mut named_variant_fields = + StructFieldExtractor::get_or_generate_named_fields(&variant.fields); + named_variant_fields + .iter_mut() + .for_each(|field| field.filter_attrs(|attr| attr.path.is_ident("doc"))); + let variant_field_names = named_variant_fields + .iter() + .map(|f| &f.ident) + .collect::>(); + + match &variant.fields { + Fields::Unnamed(_) => { + variants_with_named_fields.push(quote! { + #( #variant_docs )* + #variant_name {#(#named_variant_fields),* } + }); + convert_cases.push(quote! { + #item_with_named_fields_ident::#variant_name {#(#variant_field_names),*} => #item_name::#variant_name(#(#variant_field_names),*), + }); + } + Fields::Named(_) => { + variants_with_named_fields.push(quote! { + #( #variant_docs )* + #variant_name {#(#named_variant_fields),* } + }); + convert_cases.push(quote! { + #item_with_named_fields_ident::#variant_name {#(#variant_field_names),*} => #item_name::#variant_name {#(#variant_field_names),*}, + }); + } + Fields::Unit => { + variants_with_named_fields.push(quote! { + #( #variant_docs )* + #variant_name + }); + convert_cases.push(quote! { + #item_with_named_fields_ident::#variant_name => #item_name::#variant_name, + }); + } + } + } + + let enum_defn = quote! { + #[derive(::clap::Parser)] + pub enum #item_with_named_fields_ident #generics { + #(#variants_with_named_fields,)* + } + }; + + let from_body = quote! { + match item { + #(#convert_cases)* + } + }; + (enum_defn, from_body) + } + Data::Struct(s) => { + let mut named_fields = StructFieldExtractor::get_or_generate_named_fields(&s.fields); + named_fields + .iter_mut() + .for_each(|field| field.filter_attrs(|attr| attr.path.is_ident("doc"))); + let field_names = named_fields.iter().map(|f| &f.ident).collect::>(); + let conversion_logic = match s.fields { + Fields::Named(_) => quote! {{ + let #item_with_named_fields_ident { #(#field_names),* } = item; + #item_name{#(#field_names),*} + }}, + Fields::Unnamed(_) => { + quote! { + let #item_with_named_fields_ident { #(#field_names),* } = item; + #item_name(#(#field_names),*) + } + } + Fields::Unit => quote! { #item_name }, + }; + + let struct_defn = quote! { + #[derive(::clap::Parser)] + pub struct #item_with_named_fields_ident #generics { + #(#named_fields),* + } + }; + (struct_defn, conversion_logic) + } + Data::Union(_) => { + return Err(syn::Error::new_spanned( + ast, + "Unions are not supported as CLI wallet args", + )) + } + }; + + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + + let clap_type = if is_generic { + quote! { #item_with_named_fields_ident #ty_generics } + } else { + quote! { #item_with_named_fields_ident } + }; + + let expanded = quote! { + // Create a new data type which matches the original, but with all fields named. + // This is the type that Clap will parse the CLI args into + #named_type_defn + + // Define a `From` implementation which converts from the named fields version to the original version + impl #impl_generics From<#clap_type> for #item_name #ty_generics #where_clause { + fn from(item: #item_with_named_fields_ident #ty_generics) -> Self { + #conversion_logic + } + } + + // Implement the `CliWalletArg` trait for the original type. This is what allows the original type to be used as a CLI arg. + impl #impl_generics sov_modules_api::CliWalletArg for #item_name #ty_generics #where_clause { + type CliStringRepr = #clap_type; + } + }; + Ok(expanded.into()) +} diff --git a/module-system/sov-modules-macros/src/common.rs b/module-system/sov-modules-macros/src/common.rs index 1a35835ad..2c5efb74d 100644 --- a/module-system/sov-modules-macros/src/common.rs +++ b/module-system/sov-modules-macros/src/common.rs @@ -1,14 +1,44 @@ +use std::collections::HashMap; + use proc_macro2::{Ident, Span, TokenStream}; use quote::{format_ident, ToTokens}; -use syn::{DataStruct, GenericParam, Generics, ImplGenerics, Meta, TypeGenerics, WhereClause}; +use syn::punctuated::Punctuated; +use syn::spanned::Spanned; +use syn::{ + DataStruct, Fields, GenericParam, Generics, ImplGenerics, Meta, PathSegment, TypeGenerics, + TypeParamBound, TypePath, WhereClause, WherePredicate, +}; #[derive(Clone)] pub(crate) struct StructNamedField { pub(crate) ident: proc_macro2::Ident, pub(crate) ty: syn::Type, + pub(crate) attrs: Vec, pub(crate) vis: syn::Visibility, } +impl StructNamedField { + pub(crate) fn filter_attrs(&mut self, filter: impl FnMut(&syn::Attribute) -> bool) { + self.attrs = std::mem::take(&mut self.attrs) + .into_iter() + .filter(filter) + .collect(); + } +} + +impl ToTokens for StructNamedField { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + let docs = &self.attrs; + let vis = &self.vis; + let ident = &self.ident; + let ty = &self.ty; + tokens.extend(quote::quote! { + #( #docs )* + #vis #ident: #ty + }); + } +} + pub(crate) struct StructFieldExtractor { macro_name: &'static str, } @@ -36,6 +66,42 @@ impl StructFieldExtractor { } } + /// Extract the named fields from a struct, or generate named fields matching the fields of an unnamed struct. + /// Names follow the pattern `field0`, `field1`, etc. + pub(crate) fn get_or_generate_named_fields(fields: &Fields) -> Vec { + match fields { + Fields::Unnamed(unnamed_fields) => unnamed_fields + .unnamed + .iter() + .enumerate() + .map(|(i, field)| { + let ident = Ident::new(&format!("field{}", i), field.span()); + let ty = &field.ty; + StructNamedField { + attrs: field.attrs.clone(), + vis: field.vis.clone(), + ident, + ty: ty.clone(), + } + }) + .collect::>(), + Fields::Named(fields_named) => fields_named + .named + .iter() + .map(|field| { + let ty = &field.ty; + StructNamedField { + attrs: field.attrs.clone(), + vis: field.vis.clone(), + ident: field.ident.clone().expect("Named fields must have names!"), + ty: ty.clone(), + } + }) + .collect::>(), + Fields::Unit => Vec::new(), + } + } + fn get_fields_from_data_struct( &self, data_struct: &DataStruct, @@ -57,6 +123,7 @@ impl StructFieldExtractor { let field = StructNamedField { ident: field_ident.clone(), ty: original_field.ty.clone(), + attrs: original_field.attrs.clone(), vis: original_field.vis.clone(), }; @@ -151,7 +218,10 @@ pub(crate) fn get_generics_type_param( Ok(generic_param.clone()) } -pub fn get_attribute_values(item: &syn::DeriveInput, attribute_name: &str) -> Vec { +pub(crate) fn get_attribute_values( + item: &syn::DeriveInput, + attribute_name: &str, +) -> Vec { let mut values = vec![]; // Find the attribute with the given name on the root item @@ -172,7 +242,9 @@ pub fn get_attribute_values(item: &syn::DeriveInput, attribute_name: &str) -> Ve values } -pub fn get_serialization_attrs(item: &syn::DeriveInput) -> Result, syn::Error> { +pub(crate) fn get_serialization_attrs( + item: &syn::DeriveInput, +) -> Result, syn::Error> { const SERIALIZE: &str = "Serialize"; const DESERIALIZE: &str = "Deserialize"; @@ -213,3 +285,148 @@ pub fn get_serialization_attrs(item: &syn::DeriveInput) -> Result where T: SomeOtherTrait { +/// field: T +/// } +/// }; +/// // We want to extract both the inline bounds, and the bounds from the where clause... +/// // so that the generics from above definition are equivalent what we would have gotten +/// // from writing `T: SomeTrait + SomeOtherTrait` inline +/// let desired_bounds_for_t: syn::TypeParam = syn::parse_quote!(T: SomeTrait + SomeThirdTrait); +/// +/// // That is exactly what `GenericTypesWithBounds` does +/// let our_bounds = extract_generic_type_bounds(&test_struct.generics); +/// assert_eq!(our_bounds.get(T), Some(&desired_bounds_for_t.bounds)); +/// ``` +pub(crate) fn extract_generic_type_bounds( + generics: &Generics, +) -> HashMap> { + let mut generics_with_bounds: HashMap<_, _> = Default::default(); + // Collect the inline bounds from each generic param + for param in generics.params.iter() { + if let GenericParam::Type(ty) = param { + let path_segment = PathSegment { + ident: ty.ident.clone(), + arguments: syn::PathArguments::None, + }; + let path = syn::Path { + leading_colon: None, + segments: Punctuated::from_iter(vec![path_segment]), + }; + let type_path = syn::TypePath { qself: None, path }; + generics_with_bounds.insert(type_path, ty.bounds.clone()); + } + } + + // Iterate over the bounds in the `where_clause` and add them to the map + if let Some(where_clause) = &generics.where_clause { + for predicate in &where_clause.predicates { + // We can ignore lifetimes and "Eq" predicates since they don't add any trait bounds + // so just match on `Type` predicates + if let WherePredicate::Type(predicate_type) = predicate { + // If the bounded type is a regular type path, we need to extract the bounds and add them to the map. + // For now, we ignore more exotic bounds `[T; N]: SomeTrait`. + if let syn::Type::Path(type_path) = &predicate_type.bounded_ty { + match generics_with_bounds.entry(type_path.clone()) { + std::collections::hash_map::Entry::Occupied(mut entry) => { + entry.get_mut().extend(predicate_type.bounds.clone()) + } + std::collections::hash_map::Entry::Vacant(entry) => { + entry.insert(predicate_type.bounds.clone()); + } + } + } + } + } + } + generics_with_bounds +} + +/// Extract the type ident from a `TypePath`. +pub fn extract_ident(type_path: &syn::TypePath) -> &Ident { + &type_path + .path + .segments + .last() + .expect("Type path must have at least one segment") + .ident +} + +#[cfg(test)] +mod tests { + use syn::parse_quote; + + use crate::common::extract_generic_type_bounds; + + #[test] + fn test_generic_types_with_bounds() { + let test_struct: syn::ItemStruct = syn::parse_quote! { + struct TestStruct where T: SomeThirdTrait { + field: (T, U, V) + } + }; + let generics = test_struct.generics; + let our_bounds = extract_generic_type_bounds(&generics); + let expected_bounds_for_t: syn::TypeParam = + syn::parse_quote!(T: SomeTrait + SomeThirdTrait); + let expected_bounds_for_u: syn::TypeParam = syn::parse_quote!(U: SomeOtherTrait); + + assert_eq!( + our_bounds.get(&parse_quote!(T)), + Some(&expected_bounds_for_t.bounds) + ); + assert_eq!( + our_bounds.get(&parse_quote!(U)), + Some(&expected_bounds_for_u.bounds) + ); + assert_eq!( + our_bounds.get(&parse_quote!(V)), + Some(&syn::punctuated::Punctuated::new()) + ); + } + + #[test] + fn test_generic_types_with_associated_type_bounds() { + let test_struct: syn::ItemStruct = syn::parse_quote! { + struct TestStruct where T::Error: Debug { + field: (T, U, V) + } + }; + let generics = test_struct.generics; + let our_bounds = extract_generic_type_bounds(&generics); + let expected_bounds_for_t: syn::TypeParam = syn::parse_quote!(T: SomeTrait); + let expected_bounds_for_t_error: syn::WherePredicate = syn::parse_quote!(T::Error: Debug); + if let syn::WherePredicate::Type(expected_bounds_for_t_error) = expected_bounds_for_t_error + { + assert_eq!( + our_bounds.get(&parse_quote!(T::Error)), + Some(&expected_bounds_for_t_error.bounds) + ); + } else { + unreachable!("Expected a type predicate") + }; + let expected_bounds_for_u: syn::TypeParam = syn::parse_quote!(U: SomeOtherTrait); + + assert_eq!( + our_bounds.get(&parse_quote!(T)), + Some(&expected_bounds_for_t.bounds) + ); + + assert_eq!( + our_bounds.get(&parse_quote!(U)), + Some(&expected_bounds_for_u.bounds) + ); + assert_eq!( + our_bounds.get(&parse_quote!(V)), + Some(&syn::punctuated::Punctuated::new()) + ); + } +} diff --git a/module-system/sov-modules-macros/src/lib.rs b/module-system/sov-modules-macros/src/lib.rs index cf5d42100..5d1680110 100644 --- a/module-system/sov-modules-macros/src/lib.rs +++ b/module-system/sov-modules-macros/src/lib.rs @@ -11,7 +11,7 @@ mod module_call_json_schema; mod module_info; mod rpc; -use cli_parser::CliParserMacro; +use cli_parser::{derive_cli_wallet_arg, CliParserMacro}; use default_runtime::DefaultRuntimeMacro; use dispatch::dispatch_call::DispatchCallMacro; use dispatch::genesis::GenesisMacro; @@ -19,7 +19,7 @@ use dispatch::message_codec::MessageCodec; use module_call_json_schema::derive_module_call_json_schema; use proc_macro::TokenStream; use rpc::ExposeRpcMacro; -use syn::parse_macro_input; +use syn::{parse_macro_input, DeriveInput}; /// Derives the [`ModuleInfo`](trait.ModuleInfo.html) trait for the underlying `struct`. /// @@ -244,23 +244,84 @@ pub fn expose_rpc(attr: TokenStream, input: TokenStream) -> TokenStream { /// /// ## Examples /// ``` -/// use sov_modules_api::{Context, DispatchCall}; +/// use sov_modules_api::{Context, DispatchCall, MessageCodec}; /// use sov_modules_api::default_context::DefaultContext; -/// use sov_modules_api::macros::{MessageCodec, cli_parser}; +/// use sov_modules_api::macros::CliWallet; /// -/// #[derive(DispatchCall, MessageCodec)] +/// #[derive(DispatchCall, MessageCodec, CliWallet)] /// #[serialization(borsh::BorshDeserialize, borsh::BorshSerialize)] -/// #[cli_parser(DefaultContext)] /// pub struct Runtime { /// pub bank: sov_bank::Bank, /// // ... /// } /// ``` -#[proc_macro_attribute] -pub fn cli_parser(attr: TokenStream, input: TokenStream) -> TokenStream { - let context_type = parse_macro_input!(attr); +#[proc_macro_derive(CliWallet, attributes(cli_skip))] +pub fn cli_parser(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input); let cli_parser = CliParserMacro::new("Cmd"); + handle_macro_error(cli_parser.cli_macro(input)) +} - handle_macro_error(cli_parser.cli_parser(input, context_type)) +/// Implement [`sov_modules_api::CliWalletArg`] for the annotated struct or enum. Unions are not supported. +/// +/// Under the hood, this macro generates a new struct or enum which derives the [`clap::Parser`] trait, and then implements the +/// [`sov_modules_api::CliWalletArg`] trait where the `CliStringRepr` type is the new struct or enum. +/// +/// As an implementation detail, `clap` requires that all types have named fields - so this macro auto generates an appropriate +/// `clap`-compatible type from the annotated item. Tor example, the struct `MyStruct(u64, u64)` would be transformed into +/// `MyStructWithNamedFields { field0: u64, field1: u64 }`. +/// +/// ## Example +/// +/// This code.. +/// ```rust +/// use sov_modules_api::macros::CliWalletArg; +/// #[derive(CliWalletArg, Clone)] +/// pub enum MyEnum { +/// /// A number +/// Number(u32), +/// /// A hash +/// Hash { hash: String }, +/// } +/// ``` +/// +/// ...expands into the following code: +/// ```rust,ignore +/// // The original enum definition is left in its original place +/// pub enum MyEnum { +/// /// A number +/// Number(u32), +/// /// A hash +/// Hash { hash: String }, +/// } +/// +/// // We generate a new enum with named fields which can derive `clap::Parser`. +/// // Since this variant is only ever converted back to the original, we +/// // don't carry over any of the original derives. However, we do preserve +/// // doc comments from the original version so that `clap` can display them. +/// #[derive(::clap::Parser)] +/// pub enum MyEnumWithNamedFields { +/// /// A number +/// Number { field0: u32 } , +/// /// A hash +/// Hash { hash: String }, +/// } +/// // We generate a `From` impl to convert between the types. +/// impl From for MyEnum { +/// fn from(item: MyEnumWithNamedFields) -> Self { +/// match item { +/// Number { field0 } => MyEnum::Number(field0), +/// Hash { hash } => MyEnum::Hash { hash }, +/// } +/// } +/// } +/// +/// impl sov_modules_api::CliWalletArg for MyEnum { +/// type CliStringRepr = MyEnumWithNamedFields; +/// } +/// ``` +#[proc_macro_derive(CliWalletArg)] +pub fn custom_enum_clap(input: TokenStream) -> TokenStream { + let input: DeriveInput = parse_macro_input!(input); + handle_macro_error(derive_cli_wallet_arg(input)) } diff --git a/module-system/sov-modules-macros/tests/all_tests.rs b/module-system/sov-modules-macros/tests/all_tests.rs index b5aaca92e..d0ee67aab 100644 --- a/module-system/sov-modules-macros/tests/all_tests.rs +++ b/module-system/sov-modules-macros/tests/all_tests.rs @@ -25,3 +25,13 @@ fn rpc_tests() { let t = trybuild::TestCases::new(); t.pass("tests/derive_rpc.rs"); } + +#[test] +fn cli_wallet_arg_tests() { + let t: trybuild::TestCases = trybuild::TestCases::new(); + t.pass("tests/cli_wallet_arg/derive_enum_named_fields.rs"); + t.pass("tests/cli_wallet_arg/derive_struct_unnamed_fields.rs"); + t.pass("tests/cli_wallet_arg/derive_struct_named_fields.rs"); + t.pass("tests/cli_wallet_arg/derive_enum_mixed_fields.rs"); + t.pass("tests/cli_wallet_arg/derive_enum_unnamed_fields.rs"); +} diff --git a/module-system/sov-modules-macros/tests/cli_wallet_arg/derive_enum_mixed_fields.rs b/module-system/sov-modules-macros/tests/cli_wallet_arg/derive_enum_mixed_fields.rs new file mode 100644 index 000000000..031ff8dd7 --- /dev/null +++ b/module-system/sov-modules-macros/tests/cli_wallet_arg/derive_enum_mixed_fields.rs @@ -0,0 +1,30 @@ +use clap::Parser; +use sov_modules_api::macros::CliWalletArg; + +#[derive(CliWalletArg, Debug, PartialEq)] +pub enum MyEnum { + Foo { first_field: u32, str_field: String }, + Bar(u8), +} + +fn main() { + let expected_foo = MyEnum::Foo { + first_field: 1, + str_field: "hello".to_string(), + }; + let actual_foo = ::CliStringRepr::try_parse_from(&[ + "myenum", "foo", "1", "hello", + ]) + .expect("parsing must succed") + .into(); + assert_eq!(expected_foo, actual_foo); + + let expected_bar = MyEnum::Bar(2); + let actual_bar = ::CliStringRepr::try_parse_from(&[ + "myenum", "bar", "2", + ]) + .expect("parsing must succed") + .into(); + + assert_eq!(expected_bar, actual_bar); +} diff --git a/module-system/sov-modules-macros/tests/cli_wallet_arg/derive_enum_named_fields.rs b/module-system/sov-modules-macros/tests/cli_wallet_arg/derive_enum_named_fields.rs new file mode 100644 index 000000000..cbd067a66 --- /dev/null +++ b/module-system/sov-modules-macros/tests/cli_wallet_arg/derive_enum_named_fields.rs @@ -0,0 +1,31 @@ +use clap::Parser; +use sov_modules_api::macros::CliWalletArg; + +#[derive(CliWalletArg, Debug, PartialEq)] +pub enum MyEnum { + Foo { first_field: u32, str_field: String }, + Bar { byte: u8 }, +} + +fn main() { + let expected_foo = MyEnum::Foo { + first_field: 1, + str_field: "hello".to_string(), + }; + let actual_foo = ::CliStringRepr::try_parse_from(&[ + "myenum", "foo", "1", "hello", + ]) + .expect("parsing must succed") + .into(); + assert_eq!(expected_foo, actual_foo); + + let expected_bar = MyEnum::Bar { byte: 2 }; + + let actual_bar = ::CliStringRepr::try_parse_from(&[ + "myenum", "bar", "2", + ]) + .expect("parsing must succed") + .into(); + + assert_eq!(expected_bar, actual_bar); +} diff --git a/module-system/sov-modules-macros/tests/cli_wallet_arg/derive_enum_unnamed_fields.rs b/module-system/sov-modules-macros/tests/cli_wallet_arg/derive_enum_unnamed_fields.rs new file mode 100644 index 000000000..6ae865657 --- /dev/null +++ b/module-system/sov-modules-macros/tests/cli_wallet_arg/derive_enum_unnamed_fields.rs @@ -0,0 +1,27 @@ +use clap::Parser; +use sov_modules_api::macros::CliWalletArg; + +#[derive(CliWalletArg, Debug, PartialEq)] +pub enum MyEnum { + Foo(u32, String), + Bar(u8), +} + +fn main() { + let expected_foo = MyEnum::Foo(1, "hello".to_string()); + let actual_foo = ::CliStringRepr::try_parse_from(&[ + "myenum", "foo", "1", "hello", + ]) + .expect("parsing must succed") + .into(); + assert_eq!(expected_foo, actual_foo); + + let expected_bar = MyEnum::Bar(2); + let actual_bar = ::CliStringRepr::try_parse_from(&[ + "myenum", "bar", "2", + ]) + .expect("parsing must succed") + .into(); + + assert_eq!(expected_bar, actual_bar); +} diff --git a/module-system/sov-modules-macros/tests/cli_wallet_arg/derive_struct_named_fields.rs b/module-system/sov-modules-macros/tests/cli_wallet_arg/derive_struct_named_fields.rs new file mode 100644 index 000000000..16e520c8c --- /dev/null +++ b/module-system/sov-modules-macros/tests/cli_wallet_arg/derive_struct_named_fields.rs @@ -0,0 +1,21 @@ +use clap::Parser; +use sov_modules_api::macros::CliWalletArg; + +#[derive(CliWalletArg, Debug, PartialEq)] +pub struct MyStruct { + first_field: u32, + str_field: String, +} + +fn main() { + let expected = MyStruct { + first_field: 1, + str_field: "hello".to_string(), + }; + let actual = ::CliStringRepr::try_parse_from(&[ + "mystruct", "1", "hello", + ]) + .expect("parsing must succed") + .into(); + assert_eq!(expected, actual); +} diff --git a/module-system/sov-modules-macros/tests/cli_wallet_arg/derive_struct_unnamed_fields.rs b/module-system/sov-modules-macros/tests/cli_wallet_arg/derive_struct_unnamed_fields.rs new file mode 100644 index 000000000..68b12cd98 --- /dev/null +++ b/module-system/sov-modules-macros/tests/cli_wallet_arg/derive_struct_unnamed_fields.rs @@ -0,0 +1,15 @@ +use clap::Parser; +use sov_modules_api::macros::CliWalletArg; + +#[derive(CliWalletArg, Debug, PartialEq)] +pub struct MyStruct(u32, String); + +fn main() { + let expected = MyStruct(1, "hello".to_string()); + let actual = ::CliStringRepr::try_parse_from(&[ + "mystruct", "1", "hello", + ]) + .expect("parsing must succed") + .into(); + assert_eq!(expected, actual); +} diff --git a/module-system/sov-modules-macros/tests/dispatch/derive_dispatch.rs b/module-system/sov-modules-macros/tests/dispatch/derive_dispatch.rs index 62f23a7ae..82adc1be8 100644 --- a/module-system/sov-modules-macros/tests/dispatch/derive_dispatch.rs +++ b/module-system/sov-modules-macros/tests/dispatch/derive_dispatch.rs @@ -1,8 +1,8 @@ mod modules; use modules::{first_test_module, second_test_module}; use sov_modules_api::default_context::ZkDefaultContext; -use sov_modules_api::macros::{DefaultRuntime, MessageCodec}; -use sov_modules_api::{Address, Context, DispatchCall, Genesis, ModuleInfo}; +use sov_modules_api::macros::DefaultRuntime; +use sov_modules_api::{Address, Context, DispatchCall, Genesis, MessageCodec, ModuleInfo}; use sov_state::ZkStorage; #[derive(Genesis, DispatchCall, MessageCodec, DefaultRuntime)] diff --git a/module-system/sov-modules-macros/tests/dispatch/derive_genesis.rs b/module-system/sov-modules-macros/tests/dispatch/derive_genesis.rs index 15306d7a1..29b91c3ee 100644 --- a/module-system/sov-modules-macros/tests/dispatch/derive_genesis.rs +++ b/module-system/sov-modules-macros/tests/dispatch/derive_genesis.rs @@ -2,8 +2,8 @@ mod modules; use modules::{first_test_module, second_test_module}; use sov_modules_api::default_context::ZkDefaultContext; -use sov_modules_api::macros::{DefaultRuntime, MessageCodec}; -use sov_modules_api::{Context, DispatchCall, Genesis}; +use sov_modules_api::macros::DefaultRuntime; +use sov_modules_api::{Context, DispatchCall, Genesis, MessageCodec}; use sov_state::ZkStorage; // Debugging hint: To expand the macro in tests run: `cargo expand --test tests` diff --git a/rollup-interface/src/state_machine/mocks.rs b/rollup-interface/src/state_machine/mocks.rs index 95e4cd867..a053c59c0 100644 --- a/rollup-interface/src/state_machine/mocks.rs +++ b/rollup-interface/src/state_machine/mocks.rs @@ -108,6 +108,21 @@ pub struct MockAddress { addr: [u8; 32], } +impl core::str::FromStr for MockAddress { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + let addr = hex::decode(s)?; + if addr.len() != 32 { + return Err(anyhow::anyhow!("Invalid address length")); + } + + let mut array = [0; 32]; + array.copy_from_slice(&addr); + Ok(MockAddress { addr: array }) + } +} + impl<'a> TryFrom<&'a [u8]> for MockAddress { type Error = Error;