From 289735c3c68afc13746761ac64b73de70bccb4e0 Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Fri, 6 Oct 2023 21:55:37 -0400 Subject: [PATCH 01/35] simpler message on nightly --- src/project.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/project.rs b/src/project.rs index cd22ada..433e5bf 100644 --- a/src/project.rs +++ b/src/project.rs @@ -30,10 +30,7 @@ pub enum BuildError { #[error("could not find WASM in release dir ({path}).")] NoWasmFound { path: PathBuf }, #[error( - r#"compressed program size ({got}) exceeds max ({want}) despite --nightly flag. We recommend splitting up your program. -We are actively working to reduce WASM program sizes that use the Stylus SDK. -To see all available optimization options, see more in: -https://github.com/OffchainLabs/cargo-stylus/blob/main/OPTIMIZING_BINARIES.md"# + r#"compressed program size ({got}) exceeds max ({want}) despite --nightly flag. We recommend splitting up your program."# )] ExceedsMaxDespiteBestEffort { got: ByteSize, want: ByteSize }, #[error( @@ -135,10 +132,7 @@ https://github.com/OffchainLabs/cargo-stylus/blob/main/OPTIMIZING_BINARIES.md"#, OptLevel::Z => { if !cfg.nightly { println!( - r#"Compressed program still exceeding max program size {} > max of 24Kb, -rebuilding with optimizations. We are actively working to reduce WASM program sizes that are -using the Stylus SDK. To see all available optimization options, see more in: -https://github.com/OffchainLabs/cargo-stylus/blob/main/OPTIMIZING_BINARIES.md"#, + r#"Program still exceeds max program size {} > max of 24Kb"#, got.red(), ); // Attempt to build again with the nightly flag enabled and extra optimizations From d5b4c117467e4eeddf952f77fabe80c4174386ef Mon Sep 17 00:00:00 2001 From: afosan Date: Sun, 28 Jan 2024 22:13:20 +0300 Subject: [PATCH 02/35] fix typo in src/tx.rs --- src/tx.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tx.rs b/src/tx.rs index e906449..e27ddd9 100644 --- a/src/tx.rs +++ b/src/tx.rs @@ -19,7 +19,7 @@ pub enum TxError { NoBaseFee, #[error("no receipt found for tx hash ({tx_hash})")] NoReceiptFound { tx_hash: H256 }, - #[error("({tx_kind}) got reverted with has ({tx_hash})")] + #[error("({tx_kind}) got reverted with hash ({tx_hash})")] Reverted { tx_kind: String, tx_hash: H256 }, } From 9bcfc70219d7cddbb5b193b29283014ea4eec338 Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Wed, 31 Jan 2024 16:40:22 -0600 Subject: [PATCH 03/35] skip size limit check --- src/check.rs | 6 ++++-- src/deploy.rs | 4 +++- src/main.rs | 4 ++++ src/project.rs | 11 +++++++++-- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/check.rs b/src/check.rs index f3dda61..9270e06 100644 --- a/src/check.rs +++ b/src/check.rs @@ -67,13 +67,15 @@ pub async fn run_checks(cfg: CheckConfig) -> eyre::Result { opt_level: project::OptLevel::default(), nightly: cfg.nightly, rebuild: true, + skip_contract_size_check: cfg.skip_contract_size_check, }) .map_err(|e| eyre!("failed to build project to WASM: {e}"))?, }; println!("Reading WASM file at {}", wasm_file_path.display().grey()); - let (precompressed_bytes, init_code) = project::compress_wasm(&wasm_file_path) - .map_err(|e| eyre!("failed to get compressed WASM bytes: {e}"))?; + let (precompressed_bytes, init_code) = + project::compress_wasm(&wasm_file_path, cfg.skip_contract_size_check) + .map_err(|e| eyre!("failed to get compressed WASM bytes: {e}"))?; let precompressed_size = FileByteSize::new(precompressed_bytes.len() as u64); println!("Uncompressed WASM size: {precompressed_size}"); diff --git a/src/deploy.rs b/src/deploy.rs index 001a633..07b1f01 100644 --- a/src/deploy.rs +++ b/src/deploy.rs @@ -117,10 +117,12 @@ programs to Stylus chains here https://docs.arbitrum.io/stylus/stylus-quickstart opt_level: project::OptLevel::default(), nightly: cfg.check_cfg.nightly, rebuild: false, // The check step at the start of this command rebuilt. + skip_contract_size_check: cfg.check_cfg.skip_contract_size_check, }) .map_err(|e| eyre!("could not build project to WASM: {e}"))?, }; - let (_, init_code) = project::compress_wasm(&wasm_file_path)?; + let (_, init_code) = + project::compress_wasm(&wasm_file_path, cfg.check_cfg.skip_contract_size_check)?; println!(""); println!("{}", "====DEPLOYMENT====".grey()); println!( diff --git a/src/main.rs b/src/main.rs index a74c562..d92ea9c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -114,6 +114,10 @@ pub struct CheckConfig { /// Whether to use Rust nightly. #[arg(long)] nightly: bool, + /// Whether to skip the contract size check. In case the contract size is exceeded, a warning + /// will be emitted, but the overall cargo stylus check command will not fail. + #[arg(long)] + skip_contract_size_check: bool, } #[derive(Args, Clone, Debug)] diff --git a/src/project.rs b/src/project.rs index 433e5bf..2188bf4 100644 --- a/src/project.rs +++ b/src/project.rs @@ -23,6 +23,7 @@ pub struct BuildConfig { pub opt_level: OptLevel, pub nightly: bool, pub rebuild: bool, + pub skip_contract_size_check: bool, } #[derive(thiserror::Error, Debug, PartialEq, Eq, Clone)] @@ -111,7 +112,7 @@ pub fn build_project_dylib(cfg: BuildConfig) -> Result { }) .ok_or(BuildError::NoWasmFound { path: release_path })?; - if let Err(e) = compress_wasm(&wasm_file_path) { + if let Err(e) = compress_wasm(&wasm_file_path, cfg.skip_contract_size_check) { if let Some(BuildError::MaxCompressedSizeExceeded { got, .. }) = e.downcast_ref() { match cfg.opt_level { OptLevel::S => { @@ -127,6 +128,7 @@ https://github.com/OffchainLabs/cargo-stylus/blob/main/OPTIMIZING_BINARIES.md"#, opt_level: OptLevel::Z, nightly: cfg.nightly, rebuild: true, + skip_contract_size_check: cfg.skip_contract_size_check, }); } OptLevel::Z => { @@ -141,6 +143,7 @@ https://github.com/OffchainLabs/cargo-stylus/blob/main/OPTIMIZING_BINARIES.md"#, opt_level: OptLevel::Z, nightly: true, rebuild: true, + skip_contract_size_check: cfg.skip_contract_size_check, }); } return Err(BuildError::ExceedsMaxDespiteBestEffort { @@ -157,7 +160,7 @@ https://github.com/OffchainLabs/cargo-stylus/blob/main/OPTIMIZING_BINARIES.md"#, } /// Reads a WASM file at a specified path and returns its brotli compressed bytes. -pub fn compress_wasm(wasm_path: &PathBuf) -> Result<(Vec, Vec)> { +pub fn compress_wasm(wasm_path: &PathBuf, skip_size_check: bool) -> Result<(Vec, Vec)> { let wasm_file_bytes = std::fs::read(wasm_path).map_err(|e| { eyre!( "could not read WASM file at target path {}: {e}", @@ -177,6 +180,10 @@ pub fn compress_wasm(wasm_path: &PathBuf) -> Result<(Vec, Vec)> { let mut deploy_ready_code = hex::decode(EOF_PREFIX).unwrap(); deploy_ready_code.extend(compressed_bytes); + if skip_size_check { + return Ok((wasm_bytes.to_vec(), deploy_ready_code)); + } + let precompressed_size = ByteSize::b(wasm_bytes.len() as u64); if precompressed_size > MAX_PRECOMPRESSED_WASM_SIZE { return Err(BuildError::MaxPrecompressedSizeExceeded { From 5dc6587c9529cc8253028355ba90f4c85c39209e Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Thu, 1 Feb 2024 09:43:41 -0600 Subject: [PATCH 04/35] include gas estimates --- src/deploy.rs | 3 ++- src/tx.rs | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/deploy.rs b/src/deploy.rs index 07b1f01..9f68b63 100644 --- a/src/deploy.rs +++ b/src/deploy.rs @@ -8,7 +8,7 @@ use std::path::{Path, PathBuf}; use std::str::FromStr; use ethers::types::{Eip1559TransactionRequest, H160, U256}; -use ethers::utils::{get_contract_address, to_checksum}; +use ethers::utils::{format_ether, get_contract_address, to_checksum}; use ethers::{middleware::SignerMiddleware, providers::Middleware, signers::Signer}; use eyre::{bail, eyre}; @@ -99,6 +99,7 @@ programs to Stylus chains here https://docs.arbitrum.io/stylus/stylus-quickstart to_checksum(&addr, None), ); } + println!("Address has ETH Balance: {}", format_ether(balance).mint()); } // The folder at which to output the transaction data bytes. diff --git a/src/tx.rs b/src/tx.rs index e27ddd9..a05a534 100644 --- a/src/tx.rs +++ b/src/tx.rs @@ -61,9 +61,20 @@ where .await .map_err(|e| eyre!("could not estimate gas {e}"))?; + let estimate_gas_price = client + .get_gas_price() + .await + .map_err(|e| eyre!("could not estimate gas price for tx {e}"))?; + + let total_estimated_cost = estimated + .checked_mul(estimate_gas_price) + .ok_or(eyre!("could not multiply estimated gas cost by gas price"))?; + println!( - "Estimated gas for {tx_kind}: {} gas units", - estimated.mint() + "Estimations for {tx_kind}: gas price: {}, gas units: {}, total ETH cost : {}", + estimate_gas_price.mint(), + estimated.mint(), + format_ether(total_estimated_cost).mint(), ); if estimate_only { From a34dcdc6f6894ca8e3cf3e36f4eaf80cb88509de Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Thu, 1 Feb 2024 10:24:24 -0600 Subject: [PATCH 05/35] format gwei gas price --- src/tx.rs | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/tx.rs b/src/tx.rs index a05a534..cda2fe6 100644 --- a/src/tx.rs +++ b/src/tx.rs @@ -50,28 +50,44 @@ where let base_fee_gwei = format_units(base_fee, "gwei") .map_err(|e| eyre!("could not format base fee as gwei: {e}"))?; println!("Base fee: {} gwei", base_fee_gwei.grey()); - if !(estimate_only) { + if !estimate_only { tx_request.max_fee_per_gas = Some(base_fee); tx_request.max_priority_fee_per_gas = Some(base_fee); } - let typed = TypedTransaction::Eip1559(tx_request.clone()); - let estimated = client - .estimate_gas(&typed, None) + let address = &tx_request + .from + .ok_or(eyre!("no sender address specified for tx"))?; + let balance = client + .get_balance(*address, None) .await - .map_err(|e| eyre!("could not estimate gas {e}"))?; + .map_err(|e| eyre!("could not get sender balance: {e}"))?; + + let typed = TypedTransaction::Eip1559(tx_request.clone()); + let estimated = client.estimate_gas(&typed, None).await.map_err(|e| { + if e.to_string().contains("gas required exceeds allowance") { + return eyre!( + "not enough funds to transact, only had ETH balance of {}", + format_ether(balance) + ); + } + eyre!("could not estimate gas: {e}") + })?; let estimate_gas_price = client .get_gas_price() .await - .map_err(|e| eyre!("could not estimate gas price for tx {e}"))?; + .map_err(|e| eyre!("could not estimate gas price for tx: {e}"))?; let total_estimated_cost = estimated .checked_mul(estimate_gas_price) .ok_or(eyre!("could not multiply estimated gas cost by gas price"))?; + let estimate_gas_price = format_units(estimate_gas_price, "gwei") + .map_err(|e| eyre!("could not format gas price to gwei: {e}"))?; + println!( - "Estimations for {tx_kind}: gas price: {}, gas units: {}, total ETH cost : {}", + "Estimations for {tx_kind}: gas price (gwei): {}, gas units: {}, total ETH cost: {}", estimate_gas_price.mint(), estimated.mint(), format_ether(total_estimated_cost).mint(), From af3ae23e158828f63b45a6a4f257eb002149e93b Mon Sep 17 00:00:00 2001 From: Chris Cordle Date: Fri, 10 May 2024 16:29:23 -0400 Subject: [PATCH 06/35] update install instructions with cargo-stylus-check --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0fcb053..09525bb 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ A cargo subcommand for building, verifying, and deploying Arbitrum Stylus WASM p Install [Rust](https://www.rust-lang.org/tools/install), and then install the plugin using the Cargo tool: ``` -RUSTFLAGS="-C link-args=-rdynamic" cargo install --force cargo-stylus +cargo install --force cargo-stylus cargo-stylus-check ``` Add the `wasm32-unknown-unknown` build target to your Rust compiler: From be9faca7720b534de7ec210fa5a071eae79824ec Mon Sep 17 00:00:00 2001 From: Rachel Bousfield Date: Fri, 31 May 2024 14:04:52 -0500 Subject: [PATCH 07/35] Subcommands and Extensions (#33) * refactor subcommands * data fee * add support for extensions, refactor into subcommands, and support data fees * cargo stylus new & check refactor, use alloy, general improvements, bug fixes * support for activation * description issue fix, delete unused items * edits * estimate gas * host ios added * symbols --------- Co-authored-by: Raul Jordan --- .cargo/{config => config.toml} | 0 {ci => .ci}/build_and_test.bat | 0 {ci => .ci}/build_and_test.sh | 0 .github/workflows/linux.yml | 2 +- .github/workflows/mac.yml | 2 +- Cargo.lock | 1655 +++--- Cargo.toml | 38 +- cgen/Cargo.toml | 15 + {src/c => cgen/src}/gen.rs | 19 +- cgen/src/main.rs | 34 + check/Cargo.lock | 4612 +++++++++++++++++ check/Cargo.toml | 33 + Dockerfile => check/Dockerfile | 0 .../OPTIMIZING_BINARIES.md | 0 VALID_WASM.md => check/VALID_WASM.md | 0 {licenses => check/licenses}/Apache-2.0 | 0 {licenses => check/licenses}/COPYRIGHT.md | 0 {licenses => check/licenses}/DCO.txt | 0 {licenses => check/licenses}/MIT | 0 check/src/check.rs | 234 + check/src/constants.rs | 33 + check/src/deploy.rs | 232 + check/src/export_abi.rs | 56 + check/src/macros.rs | 18 + check/src/main.rs | 133 + check/src/new.rs | 31 + check/src/project.rs | 132 + check/src/wallet.rs | 38 + example/Cargo.toml | 11 + example/src/main.rs | 51 + install.sh | 5 + main/Cargo.toml | 16 + main/src/main.rs | 131 + replay/Cargo.toml | 26 + {src/replay => replay/src}/hostio.rs | 24 +- replay/src/main.rs | 204 + {src/replay => replay/src}/query.js | 0 {src/replay => replay/src}/trace.rs | 34 +- src/check.rs | 180 - src/constants.rs | 34 - src/deploy.rs | 241 - src/export_abi.rs | 115 - src/main.rs | 265 - src/new.rs | 39 - src/project.rs | 205 - src/replay/mod.rs | 122 - src/tx.rs | 143 - src/wallet.rs | 65 - util/Cargo.toml | 17 + {src => util/src}/color.rs | 48 +- src/c/mod.rs => util/src/lib.rs | 6 +- src/util.rs => util/src/sys.rs | 26 +- util/src/text.rs | 10 + 53 files changed, 7246 insertions(+), 2089 deletions(-) rename .cargo/{config => config.toml} (100%) rename {ci => .ci}/build_and_test.bat (100%) rename {ci => .ci}/build_and_test.sh (100%) create mode 100644 cgen/Cargo.toml rename {src/c => cgen/src}/gen.rs (95%) create mode 100644 cgen/src/main.rs create mode 100644 check/Cargo.lock create mode 100644 check/Cargo.toml rename Dockerfile => check/Dockerfile (100%) rename OPTIMIZING_BINARIES.md => check/OPTIMIZING_BINARIES.md (100%) rename VALID_WASM.md => check/VALID_WASM.md (100%) rename {licenses => check/licenses}/Apache-2.0 (100%) rename {licenses => check/licenses}/COPYRIGHT.md (100%) rename {licenses => check/licenses}/DCO.txt (100%) rename {licenses => check/licenses}/MIT (100%) create mode 100644 check/src/check.rs create mode 100644 check/src/constants.rs create mode 100644 check/src/deploy.rs create mode 100644 check/src/export_abi.rs create mode 100644 check/src/macros.rs create mode 100644 check/src/main.rs create mode 100644 check/src/new.rs create mode 100644 check/src/project.rs create mode 100644 check/src/wallet.rs create mode 100644 example/Cargo.toml create mode 100644 example/src/main.rs create mode 100755 install.sh create mode 100644 main/Cargo.toml create mode 100644 main/src/main.rs create mode 100644 replay/Cargo.toml rename {src/replay => replay/src}/hostio.rs (97%) create mode 100644 replay/src/main.rs rename {src/replay => replay/src}/query.js (100%) rename {src/replay => replay/src}/trace.rs (95%) delete mode 100644 src/check.rs delete mode 100644 src/constants.rs delete mode 100644 src/deploy.rs delete mode 100644 src/export_abi.rs delete mode 100644 src/main.rs delete mode 100644 src/new.rs delete mode 100644 src/project.rs delete mode 100644 src/replay/mod.rs delete mode 100644 src/tx.rs delete mode 100644 src/wallet.rs create mode 100644 util/Cargo.toml rename {src => util/src}/color.rs (51%) rename src/c/mod.rs => util/src/lib.rs (55%) rename src/util.rs => util/src/sys.rs (58%) create mode 100644 util/src/text.rs diff --git a/.cargo/config b/.cargo/config.toml similarity index 100% rename from .cargo/config rename to .cargo/config.toml diff --git a/ci/build_and_test.bat b/.ci/build_and_test.bat similarity index 100% rename from ci/build_and_test.bat rename to .ci/build_and_test.bat diff --git a/ci/build_and_test.sh b/.ci/build_and_test.sh similarity index 100% rename from ci/build_and_test.sh rename to .ci/build_and_test.sh diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index b836fa0..78b333d 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -30,4 +30,4 @@ jobs: rustup target add ${{ matrix.target }} - name: Build and Test - run: ./ci/build_and_test.sh \ No newline at end of file + run: ./.ci/build_and_test.sh diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index c86a212..49918f7 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -31,4 +31,4 @@ jobs: rustup target add ${{ matrix.target }} - name: Build and Test - run: ./ci/build_and_test.sh \ No newline at end of file + run: ./.ci/build_and_test.sh diff --git a/Cargo.lock b/Cargo.lock index 2069d37..c6a17c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18,7 +18,7 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ - "gimli 0.28.0", + "gimli 0.28.1", ] [[package]] @@ -40,9 +40,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ "getrandom", "once_cell", @@ -51,20 +51,30 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.5" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] +[[package]] +name = "alloy-ethers-typecast" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec4b243dba5902d17bdcf1bcd5e2cc5baae08e3a4361e4063568b0b227c7eb34" +dependencies = [ + "alloy-primitives 0.5.4", + "ethers", +] + [[package]] name = "alloy-json-abi" -version = "0.3.2" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fe46acf61ad5bd7a5c21839bb2526358382fb8a6526f7ba393bdf593e2ae43f" +checksum = "786689872ec4e7d354810ab0dffd48bb40b838c047522eb031cbd47d15634849" dependencies = [ - "alloy-primitives 0.3.3", + "alloy-primitives 0.7.2", "alloy-sol-type-parser", "serde", "serde_json", @@ -72,18 +82,21 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.3.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e416903084d3392ebd32d94735c395d6709415b76c7728e594d3f996f2b03e65" +checksum = "9c234f92024707f224510ff82419b2be0e1d8e1fd911defcac5a085cd7f83898" dependencies = [ "alloy-rlp", "bytes", "cfg-if", "const-hex", "derive_more", + "getrandom", "hex-literal", "itoa", + "keccak-asm", "proptest", + "rand", "ruint", "serde", "tiny-keccak", @@ -91,9 +104,9 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.4.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4084879b7257d5b95b9009837c07a1868bd7d60e66418a7764b9b580ae64e0" +checksum = "525448f6afc1b70dd0f9d0a8145631bf2f5e434678ab23ab18409ca264cae6b3" dependencies = [ "alloy-rlp", "bytes", @@ -102,6 +115,8 @@ dependencies = [ "derive_more", "hex-literal", "itoa", + "k256", + "keccak-asm", "proptest", "rand", "ruint", @@ -111,26 +126,73 @@ dependencies = [ [[package]] name = "alloy-rlp" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f938f00332d63a5b0ac687bd6f46d03884638948921d9f8b50c59563d421ae25" +checksum = "8d58d9f5da7b40e9bfff0b7e7816700be4019db97d4b6359fe7f94a9e22e42ac" dependencies = [ "arrayvec", "bytes", - "smol_str", +] + +[[package]] +name = "alloy-sol-macro" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89c80a2cb97e7aa48611cbb63950336f9824a174cdf670527cc6465078a26ea1" +dependencies = [ + "alloy-sol-macro-input", + "const-hex", + "heck 0.4.1", + "indexmap 2.1.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.48", + "syn-solidity", + "tiny-keccak", +] + +[[package]] +name = "alloy-sol-macro-input" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c58894b58ac50979eeac6249661991ac40b9d541830d9a725f7714cc9ef08c23" +dependencies = [ + "const-hex", + "dunce", + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.48", + "syn-solidity", ] [[package]] name = "alloy-sol-type-parser" -version = "0.3.2" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "627a32998aee7a7eedd351e9b6d4cacef9426935219a3a61befa332db1be5ca3" +checksum = "7da8e71ea68e780cc203919e03f69f59e7afe92d2696fb1dcb6662f61e4031b6" +dependencies = [ + "winnow 0.6.7", +] + +[[package]] +name = "alloy-sol-types" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "399287f68d1081ed8b1f4903c49687658b95b142207d7cb4ae2f4813915343ef" +dependencies = [ + "alloy-primitives 0.7.2", + "alloy-sol-macro", + "const-hex", + "serde", +] [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" dependencies = [ "anstyle", "anstyle-parse", @@ -142,45 +204,160 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "ark-ff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.4.0", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", ] [[package]] -name = "array-init" -version = "0.0.4" +name = "ark-ff-macros" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23589ecb866b460d3a0f1278834750268c607e8e28a1b982c907219f3178cd72" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" dependencies = [ - "nodrop", + "num-bigint", + "num-traits", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std 0.3.0", + "digest 0.9.0", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std 0.4.0", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", ] [[package]] @@ -200,13 +377,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.73" +version = "0.1.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.48", ] [[package]] @@ -217,7 +394,7 @@ checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" dependencies = [ "futures", "pharos", - "rustc_version", + "rustc_version 0.4.0", ] [[package]] @@ -267,9 +444,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.3" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -306,9 +483,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "bitvec" @@ -363,9 +540,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "byte-slice-cast" @@ -397,15 +574,15 @@ dependencies = [ [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" dependencies = [ "serde", ] @@ -448,9 +625,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cfa25e60aea747ec7e1124f238816749faa93759c6ff5b31f1ccdda137f4479" +checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d" dependencies = [ "serde", ] @@ -459,39 +636,93 @@ dependencies = [ name = "cargo-stylus" version = "0.2.1" dependencies = [ + "cargo-stylus-util", + "clap", + "eyre", +] + +[[package]] +name = "cargo-stylus-cgen" +version = "0.2.1" +dependencies = [ + "alloy-json-abi", + "clap", + "eyre", + "serde_json", + "tiny-keccak", +] + +[[package]] +name = "cargo-stylus-check" +version = "0.2.1" +dependencies = [ + "alloy-ethers-typecast", "alloy-json-abi", - "alloy-primitives 0.4.0", + "alloy-primitives 0.7.2", + "alloy-sol-macro", + "alloy-sol-types", "brotli2", "bytes", "bytesize", + "cargo-stylus-util", "clap", "ethers", "eyre", - "function_name", "hex", "lazy_static", - "libc", - "libloading", - "parking_lot", - "rustc-host", "serde", "serde_json", - "sneks", "thiserror", "tiny-keccak", "tokio", "wasmer", ] +[[package]] +name = "cargo-stylus-example" +version = "0.2.1" +dependencies = [ + "clap", +] + +[[package]] +name = "cargo-stylus-replay" +version = "0.2.1" +dependencies = [ + "alloy-primitives 0.7.2", + "cargo-stylus-util", + "clap", + "ethers", + "eyre", + "function_name", + "lazy_static", + "libc", + "libloading", + "parking_lot", + "rustc-host", + "sneks", + "tokio", +] + +[[package]] +name = "cargo-stylus-util" +version = "0.2.1" +dependencies = [ + "ethers", + "eyre", + "hex", + "rustc-host", +] + [[package]] name = "cargo_metadata" -version = "0.17.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7daec1a2a2129eeba1644b220b4647ec537b0b5d4bfd6876fcc5a540056b592" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" dependencies = [ "camino", "cargo-platform", - "semver", + "semver 1.0.21", "serde", "serde_json", "thiserror", @@ -515,9 +746,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.28" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ed24df0632f708f5f6d8082675bef2596f7084dee3dd55f632290bf35bfe0f" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "num-traits", ] @@ -534,9 +765,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.6" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ "clap_builder", "clap_derive", @@ -544,9 +775,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.6" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstream", "anstyle", @@ -556,21 +787,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.2" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.48", ] [[package]] name = "clap_lex" -version = "0.5.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "coins-bip32" @@ -580,7 +811,7 @@ checksum = "3b6be4a5df2098cd811f3194f64ddb96c267606bffd9689ac7b0160097b01ad3" dependencies = [ "bs58", "coins-core", - "digest", + "digest 0.10.7", "hmac", "k256", "serde", @@ -610,10 +841,10 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5286a0843c21f8367f7be734f89df9b822e0321d8bcce8d6e735aadff7d74979" dependencies = [ - "base64 0.21.3", + "base64 0.21.7", "bech32", "bs58", - "digest", + "digest 0.10.7", "generic-array", "hex", "ripemd", @@ -632,21 +863,22 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "const-hex" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08849ed393c907c90016652a01465a12d86361cd38ad2a7de026c56a520cc259" +checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557" dependencies = [ "cfg-if", "cpufeatures", "hex", + "proptest", "serde", ] [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "constant_time_eq" @@ -669,6 +901,22 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + [[package]] name = "corosensei" version = "0.1.4" @@ -684,9 +932,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -717,7 +965,7 @@ dependencies = [ "gimli 0.26.2", "log", "regalloc2", - "smallvec 1.11.0", + "smallvec", "target-lexicon", ] @@ -747,7 +995,7 @@ dependencies = [ "hashbrown 0.12.3", "indexmap 1.9.3", "log", - "smallvec 1.11.0", + "smallvec", ] [[package]] @@ -764,7 +1012,7 @@ checksum = "0d70abacb8cfef3dc8ff7e8836e9c1d70f7967dfdac824a4cd5e30223415aca6" dependencies = [ "cranelift-codegen", "log", - "smallvec 1.11.0", + "smallvec", "target-lexicon", ] @@ -783,48 +1031,30 @@ dependencies = [ "cfg-if", ] -[[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" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.15" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", - "memoffset 0.9.0", - "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crunchy" @@ -834,9 +1064,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.5.2" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", "rand_core", @@ -883,7 +1113,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.48", ] [[package]] @@ -894,7 +1124,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.37", + "syn 2.0.48", ] [[package]] @@ -904,7 +1134,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.0", + "hashbrown 0.14.3", "lock_api", "once_cell", "parking_lot_core", @@ -912,9 +1142,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "der" @@ -928,9 +1158,12 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.8" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] [[package]] name = "derivative" @@ -952,7 +1185,7 @@ dependencies = [ "convert_case 0.4.0", "proc-macro2", "quote", - "rustc_version", + "rustc_version 0.4.0", "syn 1.0.109", ] @@ -962,6 +1195,15 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" +[[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.7" @@ -1024,12 +1266,12 @@ checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" [[package]] name = "ecdsa" -version = "0.16.8" +version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der", - "digest", + "digest 0.10.7", "elliptic-curve", "rfc6979", "signature", @@ -1044,13 +1286,13 @@ checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.13.5" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", - "digest", + "digest 0.10.7", "ff", "generic-array", "group", @@ -1081,11 +1323,11 @@ dependencies = [ [[package]] name = "enr" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0be7b2ac146c1f99fe245c02d16af0696450d8e06c135db75e10eeb9e642c20d" +checksum = "fe81b5c06ecfdbc71dd845216f225f53b62a10cb8a16c946836a3467f701d05b" dependencies = [ - "base64 0.21.3", + "base64 0.21.7", "bytes", "hex", "k256", @@ -1093,7 +1335,6 @@ dependencies = [ "rand", "rlp", "serde", - "serde-hex", "sha3", "zeroize", ] @@ -1120,9 +1361,9 @@ dependencies = [ [[package]] name = "enumset" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e875f1719c16de097dee81ed675e2d9bb63096823ed3f0ca827b7dea3028bbbb" +checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" dependencies = [ "enumset_derive", ] @@ -1136,7 +1377,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.48", ] [[package]] @@ -1147,23 +1388,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] [[package]] @@ -1174,7 +1404,7 @@ checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" dependencies = [ "aes", "ctr", - "digest", + "digest 0.10.7", "hex", "hmac", "pbkdf2 0.11.0", @@ -1238,9 +1468,9 @@ dependencies = [ [[package]] name = "ethers" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad13497f6e0a24292fc7b408e30d22fe9dc262da1f40d7b542c3a44e7fc0476" +checksum = "1a5344eea9b20effb5efeaad29418215c4d27017639fd1f908260f59cbbd226e" dependencies = [ "ethers-addressbook", "ethers-contract", @@ -1254,9 +1484,9 @@ dependencies = [ [[package]] name = "ethers-addressbook" -version = "2.0.10" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e9e8acd0ed348403cc73a670c24daba3226c40b98dc1a41903766b3ab6240a" +checksum = "9bf35eb7d2e2092ad41f584951e08ec7c077b142dba29c4f1b8f52d2efddc49c" dependencies = [ "ethers-core", "once_cell", @@ -1266,9 +1496,9 @@ dependencies = [ [[package]] name = "ethers-contract" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d79269278125006bb0552349c03593ffa9702112ca88bc7046cc669f148fb47c" +checksum = "0111ead599d17a7bff6985fd5756f39ca7033edc79a31b23026a8d5d64fa95cd" dependencies = [ "const-hex", "ethers-contract-abigen", @@ -1285,9 +1515,9 @@ dependencies = [ [[package]] name = "ethers-contract-abigen" -version = "2.0.10" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce95a43c939b2e4e2f3191c5ad4a1f279780b8a39139c9905b43a7433531e2ab" +checksum = "bbdfb952aafd385b31d316ed80d7b76215ce09743c172966d840e96924427e0c" dependencies = [ "Inflector", "const-hex", @@ -1302,16 +1532,16 @@ dependencies = [ "reqwest", "serde", "serde_json", - "syn 2.0.37", + "syn 2.0.48", "toml", "walkdir", ] [[package]] name = "ethers-contract-derive" -version = "2.0.10" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9ce44906fc871b3ee8c69a695ca7ec7f70e50cb379c9b9cb5e532269e492f6" +checksum = "7465c814a2ecd0de0442160da13584205d1cdc08f4717a6511cad455bd5d7dc4" dependencies = [ "Inflector", "const-hex", @@ -1320,14 +1550,14 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.37", + "syn 2.0.48", ] [[package]] name = "ethers-core" -version = "2.0.10" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0a17f0708692024db9956b31d7a20163607d2745953f5ae8125ab368ba280ad" +checksum = "918b1a9ba585ea61022647def2f27c29ba19f6d2a4a4c8f68a9ae97fd5769737" dependencies = [ "arrayvec", "bytes", @@ -1346,7 +1576,7 @@ dependencies = [ "serde", "serde_json", "strum", - "syn 2.0.37", + "syn 2.0.48", "tempfile", "thiserror", "tiny-keccak", @@ -1355,13 +1585,14 @@ dependencies = [ [[package]] name = "ethers-etherscan" -version = "2.0.10" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e53451ea4a8128fbce33966da71132cf9e1040dcfd2a2084fd7733ada7b2045" +checksum = "facabf8551b4d1a3c08cb935e7fca187804b6c2525cc0dafb8e5a6dd453a24de" dependencies = [ + "chrono", "ethers-core", "reqwest", - "semver", + "semver 1.0.21", "serde", "serde_json", "thiserror", @@ -1370,9 +1601,9 @@ dependencies = [ [[package]] name = "ethers-middleware" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "473f1ccd0c793871bbc248729fa8df7e6d2981d6226e4343e3bbaa9281074d5d" +checksum = "681ece6eb1d10f7cf4f873059a77c04ff1de4f35c63dd7bccde8f438374fcb93" dependencies = [ "async-trait", "auto_impl", @@ -1397,13 +1628,13 @@ dependencies = [ [[package]] name = "ethers-providers" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6838fa110e57d572336178b7c79e94ff88ef976306852d8cb87d9e5b1fc7c0b5" +checksum = "25d6c0c9455d93d4990c06e049abf9b30daf148cf461ee939c11d88907c60816" dependencies = [ "async-trait", "auto_impl", - "base64 0.21.3", + "base64 0.21.7", "bytes", "const-hex", "enr", @@ -1434,9 +1665,9 @@ dependencies = [ [[package]] name = "ethers-signers" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea44bec930f12292866166f9ddbea6aa76304850e4d8dcd66dc492b43d00ff1" +checksum = "0cb1b714e227bbd2d8c53528adb580b203009728b17d0d0e4119353aa9bc5532" dependencies = [ "async-trait", "coins-bip32", @@ -1453,9 +1684,9 @@ dependencies = [ [[package]] name = "ethers-solc" -version = "2.0.10" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de34e484e7ae3cab99fbfd013d6c5dc7f9013676a4e0e414d8b12e1213e8b3ba" +checksum = "cc2e46e3ec8ef0c986145901fa9864205dc4dcee701f9846be2d56112d34bdea" dependencies = [ "cfg-if", "const-hex", @@ -1470,7 +1701,7 @@ dependencies = [ "path-slash", "rayon", "regex", - "semver", + "semver 1.0.21", "serde", "serde_json", "solang-parser", @@ -1485,9 +1716,9 @@ dependencies = [ [[package]] name = "eyre" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799" dependencies = [ "indenter", "once_cell", @@ -1501,9 +1732,20 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "fastrand" -version = "2.0.0" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fastrlp" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] [[package]] name = "ff" @@ -1535,9 +1777,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" dependencies = [ "crc32fast", "miniz_oxide", @@ -1551,9 +1793,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -1591,9 +1833,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -1606,9 +1848,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -1616,15 +1858,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -1633,9 +1875,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-locks" @@ -1649,26 +1891,26 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.48", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-timer" @@ -1682,9 +1924,9 @@ dependencies = [ [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -1720,9 +1962,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "libc", @@ -1742,9 +1984,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "glob" @@ -1777,9 +2019,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" dependencies = [ "bytes", "fnv", @@ -1787,7 +2029,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap 2.1.0", "slab", "tokio", "tokio-util", @@ -1805,9 +2047,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "hashers" @@ -1824,11 +2066,17 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" [[package]] name = "hex" @@ -1851,23 +2099,23 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest", + "digest 0.10.7", ] [[package]] name = "home" -version = "0.5.5" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "http" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", @@ -1876,9 +2124,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http", @@ -1899,9 +2147,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.27" +version = "0.14.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" dependencies = [ "bytes", "futures-channel", @@ -1914,7 +2162,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.9", + "socket2", "tokio", "tower-service", "tracing", @@ -1923,9 +2171,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http", @@ -1943,9 +2191,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -2007,12 +2255,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown 0.14.3", ] [[package]] @@ -2035,19 +2283,19 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "is-terminal" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" dependencies = [ "hermit-abi", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2070,24 +2318,24 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jobserver" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" dependencies = [ "wasm-bindgen", ] @@ -2098,9 +2346,9 @@ version = "8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" dependencies = [ - "base64 0.21.3", + "base64 0.21.7", "pem", - "ring", + "ring 0.16.20", "serde", "serde_json", "simple_asn1", @@ -2108,9 +2356,9 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.1" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" dependencies = [ "cfg-if", "ecdsa", @@ -2122,13 +2370,23 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ "cpufeatures", ] +[[package]] +name = "keccak-asm" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb8515fff80ed850aea4a1595f2e519c003e2a00a82fe168ebf5269196caf444" +dependencies = [ + "digest 0.10.7", + "sha3-asm", +] + [[package]] name = "lalrpop" version = "0.20.0" @@ -2171,9 +2429,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.148" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libloading" @@ -2187,21 +2445,32 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.7" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libredox" +version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.2", + "libc", + "redox_syscall", +] [[package]] name = "linux-raw-sys" -version = "0.4.5" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -2222,26 +2491,21 @@ dependencies = [ "libc", ] -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - [[package]] name = "md-5" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ - "digest", + "cfg-if", + "digest 0.10.7", ] [[package]] name = "memchr" -version = "2.6.2" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5486aed0026218e61b8a01d5fbd5a0a134649abb71a0e53b7bc088529dced86e" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "memmap2" @@ -2261,15 +2525,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - [[package]] name = "mime" version = "0.3.17" @@ -2287,9 +2542,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "wasi", @@ -2308,12 +2563,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" -[[package]] -name = "nodrop" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" - [[package]] name = "num-bigint" version = "0.4.4" @@ -2337,9 +2586,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", "libm", @@ -2357,39 +2606,39 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70bf6736f74634d299d00086f02986875b3c2d924781a6a2cb6c201e73da0ceb" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ea360eafe1022f7cc56cd7b869ed57330fb2453d0c7831d99b74c65d2f5597" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.48", ] [[package]] name = "object" -version = "0.32.0" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "open-fastrlp" @@ -2424,9 +2673,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "parity-scale-codec" -version = "3.6.5" +version = "3.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" +checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" dependencies = [ "arrayvec", "bitvec", @@ -2438,11 +2687,11 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.5" +version = "3.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" +checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 2.0.0", "proc-macro2", "quote", "syn 1.0.109", @@ -2460,15 +2709,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", - "smallvec 1.11.0", - "windows-targets", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", ] [[package]] @@ -2482,6 +2731,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + [[package]] name = "path-slash" version = "0.2.1" @@ -2494,7 +2749,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" dependencies = [ - "digest", + "digest 0.10.7", "hmac", "password-hash", "sha2", @@ -2506,7 +2761,7 @@ version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ - "digest", + "digest 0.10.7", "hmac", ] @@ -2521,9 +2776,20 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] [[package]] name = "petgraph" @@ -2532,7 +2798,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.0.0", + "indexmap 2.1.0", ] [[package]] @@ -2542,7 +2808,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" dependencies = [ "futures", - "rustc_version", + "rustc_version 0.4.0", ] [[package]] @@ -2575,7 +2841,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.48", ] [[package]] @@ -2613,7 +2879,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.48", ] [[package]] @@ -2640,9 +2906,15 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" @@ -2658,19 +2930,19 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "prettyplease" -version = "0.2.12" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64d9ba0963cdcea2e1b2230fbae2bab30eb25a174be395c41e764bfb65dd62" +checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" dependencies = [ "proc-macro2", - "syn 2.0.37", + "syn 2.0.48", ] [[package]] name = "primitive-types" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3486ccba82358b11a77516035647c34ba167dfa53312630de83b12bd4f3d66" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" dependencies = [ "fixed-hash", "impl-codec", @@ -2687,7 +2959,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", - "toml_edit", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +dependencies = [ + "toml_edit 0.20.7", +] + +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit 0.21.0", ] [[package]] @@ -2716,28 +3006,28 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] [[package]] name = "proptest" -version = "1.2.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e35c06b98bf36aba164cc17cb25f7e232f5c4aeea73baa14b8a9f0d92dbfa65" +checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" dependencies = [ "bit-set", - "bitflags 1.3.2", - "byteorder", + "bit-vec", + "bitflags 2.4.2", "lazy_static", "num-traits", "rand", "rand_chacha", "rand_xorshift", - "regex-syntax 0.6.29", + "regex-syntax 0.8.2", "rusty-fork", "tempfile", "unarray", @@ -2771,9 +3061,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -2825,9 +3115,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" dependencies = [ "either", "rayon-core", @@ -2835,42 +3125,31 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.11.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" 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 1.3.2", ] [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "redox_users" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" dependencies = [ "getrandom", - "redox_syscall 0.2.16", + "libredox", "thiserror", ] @@ -2883,43 +3162,43 @@ dependencies = [ "fxhash", "log", "slice-group-by", - "smallvec 1.11.0", + "smallvec", ] [[package]] name = "regex" -version = "1.9.4" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ "aho-corasick", "memchr", "regex-automata", - "regex-syntax 0.7.5", + "regex-syntax 0.8.2", ] [[package]] name = "regex-automata" -version = "0.3.7" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.5", + "regex-syntax 0.8.2", ] [[package]] name = "regex-syntax" -version = "0.6.29" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "regex-syntax" -version = "0.7.5" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "region" @@ -2935,20 +3214,20 @@ dependencies = [ [[package]] name = "rend" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581008d2099240d37fb08d77ad713bcaec2c4d89d50b5b21a8bb1996bbab68ab" +checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" dependencies = [ "bytecheck", ] [[package]] name = "reqwest" -version = "0.11.20" +version = "0.11.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" +checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" dependencies = [ - "base64 0.21.3", + "base64 0.21.7", "bytes", "encoding_rs", "futures-core", @@ -2970,6 +3249,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "system-configuration", "tokio", "tokio-rustls", "tower-service", @@ -2977,7 +3257,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 0.25.2", + "webpki-roots", "winreg", ] @@ -3000,29 +3280,44 @@ dependencies = [ "cc", "libc", "once_cell", - "spin", - "untrusted", + "spin 0.5.2", + "untrusted 0.7.1", "web-sys", "winapi", ] +[[package]] +name = "ring" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.48.0", +] + [[package]] name = "ripemd" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" dependencies = [ - "digest", + "digest 0.10.7", ] [[package]] name = "rkyv" -version = "0.7.42" +version = "0.7.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" +checksum = "527a97cdfef66f65998b5f3b637c26f5a5ec09cc52a3f9932313ac645f4190f5" dependencies = [ "bitvec", "bytecheck", + "bytes", "hashbrown 0.12.3", "indexmap 1.9.3", "ptr_meta", @@ -3030,14 +3325,14 @@ dependencies = [ "rkyv_derive", "seahash", "tinyvec", - "uuid 1.4.1", + "uuid 1.7.0", ] [[package]] name = "rkyv_derive" -version = "0.7.42" +version = "0.7.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" +checksum = "b5c462a1328c8e67e4d6dbad1eb0355dd43e8ab432c6e227a43657f16ade5033" dependencies = [ "proc-macro2", "quote", @@ -3068,12 +3363,22 @@ dependencies = [ [[package]] name = "ruint" -version = "1.10.1" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95294d6e3a6192f3aabf91c38f56505a625aa495533442744185a36d75a790c4" +checksum = "608a5726529f2f0ef81b8fde9873c4bb829d6b5b5ca6be4d97345ddf0749c825" dependencies = [ + "alloy-rlp", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "bytes", + "fastrlp", + "num-bigint", + "num-traits", + "parity-scale-codec", + "primitive-types", "proptest", "rand", + "rlp", "ruint-macro", "serde", "valuable", @@ -3107,67 +3412,66 @@ dependencies = [ "thiserror", ] +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver", + "semver 1.0.21", ] [[package]] name = "rustix" -version = "0.38.10" +version = "0.38.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6248e1caa625eb708e266e06159f135e8c26f2bb7ceb72dc4b2766d0340964" +checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.2", "errno", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.21.7" +version = "0.21.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", - "ring", - "rustls-webpki 0.101.4", + "ring 0.17.7", + "rustls-webpki", "sct", ] [[package]] name = "rustls-pemfile" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" -dependencies = [ - "base64 0.21.3", -] - -[[package]] -name = "rustls-webpki" -version = "0.100.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e98ff011474fa39949b7e5c0428f9b4937eda7da7848bbb947786b7be0b27dab" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "ring", - "untrusted", + "base64 0.21.7", ] [[package]] name = "rustls-webpki" -version = "0.101.4" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d93931baf2d282fff8d3a532bbfd7653f734643161b87e3e01e59a04439bf0d" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring", - "untrusted", + "ring 0.17.7", + "untrusted 0.9.0", ] [[package]] @@ -3190,9 +3494,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "salsa20" @@ -3214,9 +3518,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c0a159d0c45c12b20c5a844feb1fe4bea86e28f17b92a5f0c42193634d3782" +checksum = "7f7d66a1128282b7ef025a8ead62a4a9fcf017382ec53b8ffbf4d7bf77bd3c60" dependencies = [ "cfg-if", "derive_more", @@ -3226,11 +3530,11 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "912e55f6d20e0e80d63733872b40e1227c0bce1e1ab81ba67d696339bfd7fd29" +checksum = "abf2c68b89cafb3b8d918dd07b42be0da66ff202cf1155c5739a4e0c1ea0dc19" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "syn 1.0.109", @@ -3256,12 +3560,12 @@ dependencies = [ [[package]] name = "sct" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring", - "untrusted", + "ring 0.17.7", + "untrusted 0.9.0", ] [[package]] @@ -3286,13 +3590,31 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.18" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" dependencies = [ "serde", ] +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + [[package]] name = "send_wrapper" version = "0.4.0" @@ -3307,24 +3629,13 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" dependencies = [ "serde_derive", ] -[[package]] -name = "serde-hex" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca37e3e4d1b39afd7ff11ee4e947efae85adfddf4841787bfa47c470e96dc26d" -dependencies = [ - "array-init", - "serde", - "smallvec 0.6.14", -] - [[package]] name = "serde-wasm-bindgen" version = "0.4.5" @@ -3338,20 +3649,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.48", ] [[package]] name = "serde_json" -version = "1.0.105" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" dependencies = [ "itoa", "ryu", @@ -3360,9 +3671,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" dependencies = [ "serde", ] @@ -3381,24 +3692,24 @@ dependencies = [ [[package]] name = "sha1" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", - "digest", + "digest 0.10.7", ] [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest", + "digest 0.10.7", ] [[package]] @@ -3407,17 +3718,27 @@ version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "digest", + "digest 0.10.7", "keccak", ] +[[package]] +name = "sha3-asm" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bac61da6b35ad76b195eb4771210f947734321a8d81d7738e1580d953bc7a15e" +dependencies = [ + "cc", + "cfg-if", +] + [[package]] name = "signature" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest", + "digest 0.10.7", "rand_core", ] @@ -3462,27 +3783,9 @@ checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" [[package]] name = "smallvec" -version = "0.6.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" -dependencies = [ - "maybe-uninit", -] - -[[package]] -name = "smallvec" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" - -[[package]] -name = "smol_str" -version = "0.2.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74212e6bbe9a4352329b2f68ba3130c15a3f26fe88ff22dbdc6cdd58fa85e99c" -dependencies = [ - "serde", -] +checksum = "3b187f0231d56fe41bfb12034819dd2bf336422a5866de41bc3fec4b2e3883e8" [[package]] name = "sneks" @@ -3492,24 +3795,14 @@ checksum = "1754a9953937d149fb279d362241e4b92c4f237a491f4524835e8e78dd43810d" dependencies = [ "convert_case 0.6.0", "quote", - "syn 2.0.37", -] - -[[package]] -name = "socket2" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" -dependencies = [ - "libc", - "winapi", + "syn 2.0.48", ] [[package]] name = "socket2" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", "windows-sys 0.48.0", @@ -3517,9 +3810,9 @@ dependencies = [ [[package]] name = "solang-parser" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cb9fa2fa2fa6837be8a2495486ff92e3ffe68a99b6eeba288e139efdd842457" +checksum = "c425ce1c59f4b154717592f0bdf4715c3a1d55058883622d3157e1f0908a5b26" dependencies = [ "itertools 0.11.0", "lalrpop", @@ -3535,11 +3828,17 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der", @@ -3572,9 +3871,9 @@ dependencies = [ [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" @@ -3587,15 +3886,15 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.25.2" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "rustversion", - "syn 2.0.37", + "syn 2.0.48", ] [[package]] @@ -3606,16 +3905,16 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "svm-rs" -version = "0.3.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597e3a746727984cb7ea2487b6a40726cad0dbe86628e7d429aa6b8c4c153db4" +checksum = "20689c7d03b6461b502d0b95d6c24874c7d24dea2688af80486a130a06af3b07" dependencies = [ "dirs", "fs2", "hex", "once_cell", "reqwest", - "semver", + "semver 1.0.21", "serde", "serde_json", "sha2", @@ -3637,15 +3936,48 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.37" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "syn-solidity" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa0cefd02f532035d83cfec82647c6eb53140b0485220760e669f4bad489e36" +dependencies = [ + "paste", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tap" version = "1.0.1" @@ -3654,21 +3986,21 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-lexicon" -version = "0.12.11" +version = "0.12.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" +checksum = "69758bda2e78f098e4ccb393021a0963bb3442eac05f135c30f61b7370bbafae" [[package]] name = "tempfile" -version = "3.8.0" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" dependencies = [ "cfg-if", "fastrand", - "redox_syscall 0.3.5", + "redox_syscall", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -3684,32 +4016,33 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.47" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.47" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.48", ] [[package]] name = "time" -version = "0.3.28" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" +checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" dependencies = [ "deranged", "itoa", + "powerfmt", "serde", "time-core", "time-macros", @@ -3717,15 +4050,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" +checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" dependencies = [ "time-core", ] @@ -3756,9 +4089,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.32.0" +version = "1.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" dependencies = [ "backtrace", "bytes", @@ -3766,20 +4099,20 @@ dependencies = [ "mio", "num_cpus", "pin-project-lite", - "socket2 0.5.3", + "socket2", "tokio-macros", "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.48", ] [[package]] @@ -3794,9 +4127,9 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2dbec703c26b00d74844519606ef15d09a7d6857860f84ad223dec002ddea2" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", @@ -3804,14 +4137,14 @@ dependencies = [ "tokio", "tokio-rustls", "tungstenite", - "webpki-roots 0.23.1", + "webpki-roots", ] [[package]] name = "tokio-util" -version = "0.7.8" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", @@ -3823,36 +4156,58 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.21.0", ] [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.14" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.1.0", + "toml_datetime", + "winnow 0.5.34", +] + +[[package]] +name = "toml_edit" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +dependencies = [ + "indexmap 2.1.0", + "toml_datetime", + "winnow 0.5.34", +] + +[[package]] +name = "toml_edit" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" dependencies = [ - "indexmap 2.0.0", + "indexmap 2.1.0", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.5.34", ] [[package]] @@ -3863,11 +4218,10 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -3875,20 +4229,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.48", ] [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] @@ -3905,15 +4259,15 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tungstenite" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e862a1c4128df0112ab625f55cd5c934bcb4312ba80b39ae4b4835a3fd58e649" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" dependencies = [ "byteorder", "bytes", @@ -3931,9 +4285,15 @@ dependencies = [ [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "uint" @@ -3955,15 +4315,15 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" @@ -3982,9 +4342,9 @@ checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" [[package]] name = "unicode-width" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] name = "unicode-xid" @@ -3998,11 +4358,17 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", @@ -4033,9 +4399,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.4.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" +checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" [[package]] name = "valuable" @@ -4060,9 +4426,9 @@ dependencies = [ [[package]] name = "walkdir" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" dependencies = [ "same-file", "winapi-util", @@ -4085,9 +4451,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -4095,16 +4461,16 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.48", "wasm-bindgen-shared", ] @@ -4133,9 +4499,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" dependencies = [ "cfg-if", "js-sys", @@ -4145,9 +4511,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4155,28 +4521,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "wasm-encoder" -version = "0.32.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba64e81215916eaeb48fee292f29401d69235d62d8b8fd92a7b2844ec5ae5f7" +checksum = "111495d6204760238512f57a9af162f45086504da332af210f2f75dd80b34f1d" dependencies = [ "leb128", ] @@ -4224,7 +4590,7 @@ dependencies = [ "memmap2", "more-asserts", "region", - "smallvec 1.11.0", + "smallvec", "thiserror", "wasmer-types", "wasmer-vm", @@ -4244,7 +4610,7 @@ dependencies = [ "gimli 0.26.2", "more-asserts", "rayon", - "smallvec 1.11.0", + "smallvec", "target-lexicon", "tracing", "wasmer-compiler", @@ -4297,7 +4663,7 @@ dependencies = [ "lazy_static", "libc", "mach", - "memoffset 0.8.0", + "memoffset", "more-asserts", "region", "scopeguard", @@ -4318,9 +4684,9 @@ dependencies = [ [[package]] name = "wast" -version = "64.0.0" +version = "70.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a259b226fd6910225aa7baeba82f9d9933b6d00f2ce1b49b80fa4214328237cc" +checksum = "2ee4bc54bbe1c6924160b9f75e374a1d07532e7580eb632c0ee6cdd109bb217e" dependencies = [ "leb128", "memchr", @@ -4330,18 +4696,18 @@ dependencies = [ [[package]] name = "wat" -version = "1.0.71" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53253d920ab413fca1c7dc2161d601c79b4fdf631d0ba51dd4343bf9b556c3f6" +checksum = "9f0dce8cdc288c717cf01e461a1e451a7b8445d53451123536ba576e423a101a" dependencies = [ "wast", ] [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" dependencies = [ "js-sys", "wasm-bindgen", @@ -4349,18 +4715,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" -dependencies = [ - "rustls-webpki 0.100.2", -] - -[[package]] -name = "webpki-roots" -version = "0.25.2" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" +checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" [[package]] name = "winapi" @@ -4380,9 +4737,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -4412,7 +4769,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", ] [[package]] @@ -4421,21 +4787,42 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", + "windows_aarch64_gnullvm 0.48.5", "windows_aarch64_msvc 0.48.5", "windows_i686_gnu 0.48.5", "windows_i686_msvc 0.48.5", "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm", + "windows_x86_64_gnullvm 0.48.5", "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.33.0" @@ -4448,6 +4835,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.33.0" @@ -4460,6 +4853,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.33.0" @@ -4472,6 +4871,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.33.0" @@ -4484,12 +4889,24 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.33.0" @@ -4502,11 +4919,26 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "winnow" +version = "0.5.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" +dependencies = [ + "memchr", +] + [[package]] name = "winnow" -version = "0.5.15" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" +checksum = "14b9415ee827af173ebb3f15f9083df5a122eb93572ec28741fb153356ea2578" dependencies = [ "memchr", ] @@ -4532,7 +4964,7 @@ dependencies = [ "js-sys", "log", "pharos", - "rustc_version", + "rustc_version 0.4.0", "send_wrapper 0.6.0", "thiserror", "wasm-bindgen", @@ -4557,9 +4989,23 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] [[package]] name = "zip" @@ -4602,11 +5048,10 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.8+zstd.1.5.5" +version = "2.0.9+zstd.1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" +checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" dependencies = [ "cc", - "libc", "pkg-config", ] diff --git a/Cargo.toml b/Cargo.toml index 3d1611f..ab9efed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,31 +1,29 @@ -[package] -name = "cargo-stylus" +[workspace] +members = ["cgen", "check", "example", "main", "replay", "util"] +resolver = "2" + +[workspace.package] +authors = ["Offchain Labs"] version = "0.2.1" edition = "2021" -authors = ["Offchain Labs"] +homepage = "https://arbitrum.io" license = "MIT OR Apache-2.0" -homepage = "https://github.com/OffchainLabs/cargo-stylus" repository = "https://github.com/OffchainLabs/cargo-stylus" -keywords = ["arbitrum", "ethereum", "stylus", "alloy", "cargo"] -description = "CLI tool for deploying Stylus contracts on Arbitrum chains" -[dependencies] -alloy-primitives = "0.4.0" -rustc-host = "0.1.7" -brotli2 = "0.3.2" -bytes = "1.4.0" -clap = { version = "4.4.5", features = [ "derive" ] } +[workspace.dependencies] +alloy-primitives = "0.7.2" +alloy-json-abi = "0.7.2" +alloy-sol-macro = "0.7.2" +alloy-sol-types = "0.7.2" +alloy-ethers-typecast = "0.2.0" +clap = { version = "4.5.4", features = [ "derive", "color" ] } +ethers = "2.0.10" eyre = "0.6.8" hex = "0.4.3" -serde = { version = "1.0.188", features = ["derive"] } -alloy-json-abi = "0.3.2" -bytesize = "1.2.0" -ethers = "2.0.10" +rustc-host = "0.1.7" serde_json = "1.0.103" -tokio = { version = "1.29.1", features = ["macros", "rt-multi-thread" ] } -wasmer = "3.1.0" -thiserror = "1.0.47" tiny-keccak = { version = "2.0.2", features = ["keccak"] } +tokio = { version = "1.29.1", features = ["macros", "rt-multi-thread" ] } # replay tool function_name = "0.3.0" @@ -35,3 +33,5 @@ libloading = "0.8.0" parking_lot = "0.12.1" sneks = "0.1.2" +# members +cargo-stylus-util = { path = "util", version = "0.2.1" } diff --git a/cgen/Cargo.toml b/cgen/Cargo.toml new file mode 100644 index 0000000..5e47211 --- /dev/null +++ b/cgen/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "cargo-stylus-cgen" +authors.workspace = true +version.workspace = true +edition.workspace = true +homepage.workspace = true +license.workspace = true +repository.workspace = true + +[dependencies] +alloy-json-abi.workspace = true +clap.workspace = true +eyre.workspace = true +serde_json.workspace = true +tiny-keccak.workspace = true diff --git a/src/c/gen.rs b/cgen/src/gen.rs similarity index 95% rename from src/c/gen.rs rename to cgen/src/gen.rs index dc98f4e..d646854 100644 --- a/src/c/gen.rs +++ b/cgen/src/gen.rs @@ -1,12 +1,10 @@ -// Copyright 2023, Offchain Labs, Inc. +// Copyright 2023-2024, Offchain Labs, Inc. // For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md use alloy_json_abi::{Function, JsonAbi, StateMutability}; -use eyre::bail; +use eyre::{bail, Result}; use serde_json::Value; -use std::fs; -use std::io::BufReader; -use std::{collections::HashMap, fmt::Write}; +use std::{collections::HashMap, fmt::Write, fs, io::BufReader, path::Path}; use tiny_keccak::{Hasher, Keccak}; fn c_bytearray_initializer(val: &[u8]) -> String { @@ -14,13 +12,16 @@ fn c_bytearray_initializer(val: &[u8]) -> String { format!("{{{}}}", inner.join(", ")) } -pub fn c_gen(in_path: String, out_path: String) -> eyre::Result<()> { - let f = fs::File::open(&in_path)?; +pub fn c_gen(in_path: &Path, out_path: &Path) -> Result<()> { + let f = fs::File::open(in_path)?; let input: Value = serde_json::from_reader(BufReader::new(f))?; let Some(input_contracts) = input["contracts"].as_object() else { - bail!("did not find top-level contracts object in {}", in_path) + bail!( + "did not find top-level contracts object in {}", + in_path.to_string_lossy() + ) }; let mut pathbuf = std::path::PathBuf::new(); @@ -70,7 +71,7 @@ pub fn c_gen(in_path: String, out_path: String) -> eyre::Result<()> { 0 => simple_name.clone(), x => format!("{simple_name}_{x}"), }; - let selector = u32::from_be_bytes(overload.selector()); + let selector = u32::from_be_bytes(*overload.selector()); let (hdr_params, call_params, payable) = match overload.state_mutability { StateMutability::Pure => { diff --git a/cgen/src/main.rs b/cgen/src/main.rs new file mode 100644 index 0000000..e980d20 --- /dev/null +++ b/cgen/src/main.rs @@ -0,0 +1,34 @@ +// Copyright 2023-2024, Offchain Labs, Inc. +// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md + +use clap::Parser; +use eyre::Result; +use std::path::PathBuf; + +mod gen; + +#[derive(Parser, Debug)] +#[command(name = "cgen")] +#[command(bin_name = "cargo stylus")] +#[command(author = "Offchain Labs, Inc.")] +#[command(about = "Generate C code for Stylus ABI bindings.", long_about = None)] +#[command(propagate_version = true)] +#[command(version)] +struct Opts { + #[command(subcommand)] + command: Apis, +} + +#[derive(Parser, Debug, Clone)] +enum Apis { + /// Generate C code. + #[command()] + Cgen { input: PathBuf, out_dir: PathBuf }, +} + +fn main() -> Result<()> { + let args = Opts::parse(); + match args.command { + Apis::Cgen { input, out_dir } => gen::c_gen(&input, &out_dir), + } +} diff --git a/check/Cargo.lock b/check/Cargo.lock new file mode 100644 index 0000000..2069d37 --- /dev/null +++ b/check/Cargo.lock @@ -0,0 +1,4612 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli 0.28.0", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aes" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloy-json-abi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fe46acf61ad5bd7a5c21839bb2526358382fb8a6526f7ba393bdf593e2ae43f" +dependencies = [ + "alloy-primitives 0.3.3", + "alloy-sol-type-parser", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-primitives" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e416903084d3392ebd32d94735c395d6709415b76c7728e594d3f996f2b03e65" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if", + "const-hex", + "derive_more", + "hex-literal", + "itoa", + "proptest", + "ruint", + "serde", + "tiny-keccak", +] + +[[package]] +name = "alloy-primitives" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4084879b7257d5b95b9009837c07a1868bd7d60e66418a7764b9b580ae64e0" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if", + "const-hex", + "derive_more", + "hex-literal", + "itoa", + "proptest", + "rand", + "ruint", + "serde", + "tiny-keccak", +] + +[[package]] +name = "alloy-rlp" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f938f00332d63a5b0ac687bd6f46d03884638948921d9f8b50c59563d421ae25" +dependencies = [ + "arrayvec", + "bytes", + "smol_str", +] + +[[package]] +name = "alloy-sol-type-parser" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "627a32998aee7a7eedd351e9b6d4cacef9426935219a3a61befa332db1be5ca3" + +[[package]] +name = "anstream" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea" + +[[package]] +name = "anstyle-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +dependencies = [ + "anstyle", + "windows-sys 0.48.0", +] + +[[package]] +name = "array-init" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23589ecb866b460d3a0f1278834750268c607e8e28a1b982c907219f3178cd72" +dependencies = [ + "nodrop", +] + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "ascii-canvas" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" +dependencies = [ + "term", +] + +[[package]] +name = "async-trait" +version = "0.1.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "async_io_stream" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" +dependencies = [ + "futures", + "pharos", + "rustc_version", +] + +[[package]] +name = "auto_impl" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" + +[[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 = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[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 = "brotli-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "brotli2" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" +dependencies = [ + "brotli-sys", + "libc", +] + +[[package]] +name = "bs58" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +dependencies = [ + "sha2", + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "bytecheck" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[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 = "bytesize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" + +[[package]] +name = "bzip2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[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 = "camino" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cfa25e60aea747ec7e1124f238816749faa93759c6ff5b31f1ccdda137f4479" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-stylus" +version = "0.2.1" +dependencies = [ + "alloy-json-abi", + "alloy-primitives 0.4.0", + "brotli2", + "bytes", + "bytesize", + "clap", + "ethers", + "eyre", + "function_name", + "hex", + "lazy_static", + "libc", + "libloading", + "parking_lot", + "rustc-host", + "serde", + "serde_json", + "sneks", + "thiserror", + "tiny-keccak", + "tokio", + "wasmer", +] + +[[package]] +name = "cargo_metadata" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7daec1a2a2129eeba1644b220b4647ec537b0b5d4bfd6876fcc5a540056b592" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95ed24df0632f708f5f6d8082675bef2596f7084dee3dd55f632290bf35bfe0f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clap" +version = "4.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "clap_lex" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" + +[[package]] +name = "coins-bip32" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b6be4a5df2098cd811f3194f64ddb96c267606bffd9689ac7b0160097b01ad3" +dependencies = [ + "bs58", + "coins-core", + "digest", + "hmac", + "k256", + "serde", + "sha2", + "thiserror", +] + +[[package]] +name = "coins-bip39" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db8fba409ce3dc04f7d804074039eb68b960b0829161f8e06c95fea3f122528" +dependencies = [ + "bitvec", + "coins-bip32", + "hmac", + "once_cell", + "pbkdf2 0.12.2", + "rand", + "sha2", + "thiserror", +] + +[[package]] +name = "coins-core" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5286a0843c21f8367f7be734f89df9b822e0321d8bcce8d6e735aadff7d74979" +dependencies = [ + "base64 0.21.3", + "bech32", + "bs58", + "digest", + "generic-array", + "hex", + "ripemd", + "serde", + "serde_derive", + "sha2", + "sha3", + "thiserror", +] + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "const-hex" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08849ed393c907c90016652a01465a12d86361cd38ad2a7de026c56a520cc259" +dependencies = [ + "cfg-if", + "cpufeatures", + "hex", + "serde", +] + +[[package]] +name = "const-oid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "corosensei" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80128832c58ea9cbd041d2a759ec449224487b2c1e400453d99d244eead87a8e" +dependencies = [ + "autocfg", + "cfg-if", + "libc", + "scopeguard", + "windows-sys 0.33.0", +] + +[[package]] +name = "cpufeatures" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +dependencies = [ + "libc", +] + +[[package]] +name = "cranelift-bforest" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2ab4512dfd3a6f4be184403a195f76e81a8a9f9e6c898e19d2dc3ce20e0115" +dependencies = [ + "cranelift-entity", +] + +[[package]] +name = "cranelift-codegen" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98b022ed2a5913a38839dfbafe6cf135342661293b08049843362df4301261dc" +dependencies = [ + "arrayvec", + "bumpalo", + "cranelift-bforest", + "cranelift-codegen-meta", + "cranelift-codegen-shared", + "cranelift-egraph", + "cranelift-entity", + "cranelift-isle", + "gimli 0.26.2", + "log", + "regalloc2", + "smallvec 1.11.0", + "target-lexicon", +] + +[[package]] +name = "cranelift-codegen-meta" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "639307b45434ad112a98f8300c0f0ab085cbefcd767efcdef9ef19d4c0756e74" +dependencies = [ + "cranelift-codegen-shared", +] + +[[package]] +name = "cranelift-codegen-shared" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "278e52e29c53fcf32431ef08406c295699a70306d05a0715c5b1bf50e33a9ab7" + +[[package]] +name = "cranelift-egraph" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624b54323b06e675293939311943ba82d323bb340468ce1889be5da7932c8d73" +dependencies = [ + "cranelift-entity", + "fxhash", + "hashbrown 0.12.3", + "indexmap 1.9.3", + "log", + "smallvec 1.11.0", +] + +[[package]] +name = "cranelift-entity" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a59bcbca89c3f1b70b93ab3cbba5e5e0cbf3e63dadb23c7525cb142e21a9d4c" + +[[package]] +name = "cranelift-frontend" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d70abacb8cfef3dc8ff7e8836e9c1d70f7967dfdac824a4cd5e30223415aca6" +dependencies = [ + "cranelift-codegen", + "log", + "smallvec 1.11.0", + "target-lexicon", +] + +[[package]] +name = "cranelift-isle" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "393bc73c451830ff8dbb3a07f61843d6cb41a084f9996319917c0b291ed785bb" + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[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.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset 0.9.0", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[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 = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "darling" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "darling_macro" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.0", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "data-encoding" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case 0.4.0", + "proc-macro2", + "quote", + "rustc_version", + "syn 1.0.109", +] + +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys" +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 = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + +[[package]] +name = "ecdsa" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "elliptic-curve" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "ena" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1" +dependencies = [ + "log", +] + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enr" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0be7b2ac146c1f99fe245c02d16af0696450d8e06c135db75e10eeb9e642c20d" +dependencies = [ + "base64 0.21.3", + "bytes", + "hex", + "k256", + "log", + "rand", + "rlp", + "serde", + "serde-hex", + "sha3", + "zeroize", +] + +[[package]] +name = "enum-iterator" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eeac5c5edb79e4e39fe8439ef35207780a11f69c52cbe424ce3dfad4cb78de6" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "enumset" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e875f1719c16de097dee81ed675e2d9bb63096823ed3f0ca827b7dea3028bbbb" +dependencies = [ + "enumset_derive", +] + +[[package]] +name = "enumset_derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "eth-keystore" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" +dependencies = [ + "aes", + "ctr", + "digest", + "hex", + "hmac", + "pbkdf2 0.11.0", + "rand", + "scrypt", + "serde", + "serde_json", + "sha2", + "sha3", + "thiserror", + "uuid 0.8.2", +] + +[[package]] +name = "ethabi" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" +dependencies = [ + "ethereum-types", + "hex", + "once_cell", + "regex", + "serde", + "serde_json", + "sha3", + "thiserror", + "uint", +] + +[[package]] +name = "ethbloom" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" +dependencies = [ + "crunchy", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "tiny-keccak", +] + +[[package]] +name = "ethereum-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" +dependencies = [ + "ethbloom", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "primitive-types", + "scale-info", + "uint", +] + +[[package]] +name = "ethers" +version = "2.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad13497f6e0a24292fc7b408e30d22fe9dc262da1f40d7b542c3a44e7fc0476" +dependencies = [ + "ethers-addressbook", + "ethers-contract", + "ethers-core", + "ethers-etherscan", + "ethers-middleware", + "ethers-providers", + "ethers-signers", + "ethers-solc", +] + +[[package]] +name = "ethers-addressbook" +version = "2.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6e9e8acd0ed348403cc73a670c24daba3226c40b98dc1a41903766b3ab6240a" +dependencies = [ + "ethers-core", + "once_cell", + "serde", + "serde_json", +] + +[[package]] +name = "ethers-contract" +version = "2.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d79269278125006bb0552349c03593ffa9702112ca88bc7046cc669f148fb47c" +dependencies = [ + "const-hex", + "ethers-contract-abigen", + "ethers-contract-derive", + "ethers-core", + "ethers-providers", + "futures-util", + "once_cell", + "pin-project", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "ethers-contract-abigen" +version = "2.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce95a43c939b2e4e2f3191c5ad4a1f279780b8a39139c9905b43a7433531e2ab" +dependencies = [ + "Inflector", + "const-hex", + "dunce", + "ethers-core", + "ethers-etherscan", + "eyre", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "reqwest", + "serde", + "serde_json", + "syn 2.0.37", + "toml", + "walkdir", +] + +[[package]] +name = "ethers-contract-derive" +version = "2.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9ce44906fc871b3ee8c69a695ca7ec7f70e50cb379c9b9cb5e532269e492f6" +dependencies = [ + "Inflector", + "const-hex", + "ethers-contract-abigen", + "ethers-core", + "proc-macro2", + "quote", + "serde_json", + "syn 2.0.37", +] + +[[package]] +name = "ethers-core" +version = "2.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0a17f0708692024db9956b31d7a20163607d2745953f5ae8125ab368ba280ad" +dependencies = [ + "arrayvec", + "bytes", + "cargo_metadata", + "chrono", + "const-hex", + "elliptic-curve", + "ethabi", + "generic-array", + "k256", + "num_enum", + "once_cell", + "open-fastrlp", + "rand", + "rlp", + "serde", + "serde_json", + "strum", + "syn 2.0.37", + "tempfile", + "thiserror", + "tiny-keccak", + "unicode-xid", +] + +[[package]] +name = "ethers-etherscan" +version = "2.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e53451ea4a8128fbce33966da71132cf9e1040dcfd2a2084fd7733ada7b2045" +dependencies = [ + "ethers-core", + "reqwest", + "semver", + "serde", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "ethers-middleware" +version = "2.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "473f1ccd0c793871bbc248729fa8df7e6d2981d6226e4343e3bbaa9281074d5d" +dependencies = [ + "async-trait", + "auto_impl", + "ethers-contract", + "ethers-core", + "ethers-etherscan", + "ethers-providers", + "ethers-signers", + "futures-channel", + "futures-locks", + "futures-util", + "instant", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", + "tracing-futures", + "url", +] + +[[package]] +name = "ethers-providers" +version = "2.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6838fa110e57d572336178b7c79e94ff88ef976306852d8cb87d9e5b1fc7c0b5" +dependencies = [ + "async-trait", + "auto_impl", + "base64 0.21.3", + "bytes", + "const-hex", + "enr", + "ethers-core", + "futures-core", + "futures-timer", + "futures-util", + "hashers", + "http", + "instant", + "jsonwebtoken", + "once_cell", + "pin-project", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-tungstenite", + "tracing", + "tracing-futures", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "ws_stream_wasm", +] + +[[package]] +name = "ethers-signers" +version = "2.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea44bec930f12292866166f9ddbea6aa76304850e4d8dcd66dc492b43d00ff1" +dependencies = [ + "async-trait", + "coins-bip32", + "coins-bip39", + "const-hex", + "elliptic-curve", + "eth-keystore", + "ethers-core", + "rand", + "sha2", + "thiserror", + "tracing", +] + +[[package]] +name = "ethers-solc" +version = "2.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de34e484e7ae3cab99fbfd013d6c5dc7f9013676a4e0e414d8b12e1213e8b3ba" +dependencies = [ + "cfg-if", + "const-hex", + "dirs", + "dunce", + "ethers-core", + "glob", + "home", + "md-5", + "num_cpus", + "once_cell", + "path-slash", + "rayon", + "regex", + "semver", + "serde", + "serde_json", + "solang-parser", + "svm-rs", + "thiserror", + "tiny-keccak", + "tokio", + "tracing", + "walkdir", + "yansi", +] + +[[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 = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "fastrand" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flate2" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fs2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "function_name" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1ab577a896d09940b5fe12ec5ae71f9d8211fff62c919c03a3750a9901e98a7" +dependencies = [ + "function_name-proc-macro", +] + +[[package]] +name = "function_name-proc-macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673464e1e314dd67a0fd9544abc99e8eb28d0c7e3b69b033bcff9b2d00b87333" + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[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-executor", + "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-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-locks" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45ec6fe3675af967e67c5536c0b9d44e34e6c52f86bedc4ea49c5317b8e94d06" +dependencies = [ + "futures-channel", + "futures-task", +] + +[[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.37", +] + +[[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-timer" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" +dependencies = [ + "gloo-timers", + "send_wrapper 0.4.0", +] + +[[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 = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" +dependencies = [ + "fallible-iterator", + "indexmap 1.9.3", + "stable_deref_trait", +] + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 1.9.3", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + +[[package]] +name = "hashers" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2bca93b15ea5a746f220e56587f71e73c6165eab783df9e26590069953e3c30" +dependencies = [ + "fxhash", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" + +[[package]] +name = "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.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + +[[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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.9", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +dependencies = [ + "serde", +] + +[[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 = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ipnet" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" + +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[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.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonwebtoken" +version = "8.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" +dependencies = [ + "base64 0.21.3", + "pem", + "ring", + "serde", + "serde_json", + "simple_asn1", +] + +[[package]] +name = "k256" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", + "signature", +] + +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lalrpop" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da4081d44f4611b66c6dd725e6de3169f9f63905421e8626fcb86b6a898998b8" +dependencies = [ + "ascii-canvas", + "bit-set", + "diff", + "ena", + "is-terminal", + "itertools 0.10.5", + "lalrpop-util", + "petgraph", + "regex", + "regex-syntax 0.7.5", + "string_cache", + "term", + "tiny-keccak", + "unicode-xid", +] + +[[package]] +name = "lalrpop-util" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f35c735096c0293d313e8f2a641627472b83d01b937177fe76e5e2708d31e0d" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "libc" +version = "0.2.148" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" + +[[package]] +name = "libloading" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "libm" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" + +[[package]] +name = "linux-raw-sys" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" + +[[package]] +name = "lock_api" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] +name = "md-5" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" +dependencies = [ + "digest", +] + +[[package]] +name = "memchr" +version = "2.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5486aed0026218e61b8a01d5fbd5a0a134649abb71a0e53b7bc088529dced86e" + +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "more-asserts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" + +[[package]] +name = "new_debug_unreachable" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[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.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70bf6736f74634d299d00086f02986875b3c2d924781a6a2cb6c201e73da0ceb" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ea360eafe1022f7cc56cd7b869ed57330fb2453d0c7831d99b74c65d2f5597" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "object" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "open-fastrlp" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", + "ethereum-types", + "open-fastrlp-derive", +] + +[[package]] +name = "open-fastrlp-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" +dependencies = [ + "bytes", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "parity-scale-codec" +version = "3.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" +dependencies = [ + "arrayvec", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[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.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.3.5", + "smallvec 1.11.0", + "windows-targets", +] + +[[package]] +name = "password-hash" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" +dependencies = [ + "base64ct", + "rand_core", + "subtle", +] + +[[package]] +name = "path-slash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest", + "hmac", + "password-hash", + "sha2", +] + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest", + "hmac", +] + +[[package]] +name = "pem" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap 2.0.0", +] + +[[package]] +name = "pharos" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" +dependencies = [ + "futures", + "rustc_version", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared 0.11.2", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared 0.11.2", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared 0.11.2", + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[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 = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "prettyplease" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64d9ba0963cdcea2e1b2230fbae2bab30eb25a174be395c41e764bfb65dd62" +dependencies = [ + "proc-macro2", + "syn 2.0.37", +] + +[[package]] +name = "primitive-types" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f3486ccba82358b11a77516035647c34ba167dfa53312630de83b12bd4f3d66" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "uint", +] + +[[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-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proptest" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e35c06b98bf36aba164cc17cb25f7e232f5c4aeea73baa14b8a9f0d92dbfa65" +dependencies = [ + "bit-set", + "bitflags 1.3.2", + "byteorder", + "lazy_static", + "num-traits", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax 0.6.29", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[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", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core", +] + +[[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 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall 0.2.16", + "thiserror", +] + +[[package]] +name = "regalloc2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300d4fbfb40c1c66a78ba3ddd41c1110247cf52f97b87d0f2fc9209bd49b030c" +dependencies = [ + "fxhash", + "log", + "slice-group-by", + "smallvec 1.11.0", +] + +[[package]] +name = "regex" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax 0.7.5", +] + +[[package]] +name = "regex-automata" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.7.5", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" + +[[package]] +name = "region" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76e189c2369884dce920945e2ddf79b3dff49e071a167dd1817fa9c4c00d512e" +dependencies = [ + "bitflags 1.3.2", + "libc", + "mach", + "winapi", +] + +[[package]] +name = "rend" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581008d2099240d37fb08d77ad713bcaec2c4d89d50b5b21a8bb1996bbab68ab" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "reqwest" +version = "0.11.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" +dependencies = [ + "base64 0.21.3", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-rustls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots 0.25.2", + "winreg", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[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 = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest", +] + +[[package]] +name = "rkyv" +version = "0.7.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" +dependencies = [ + "bitvec", + "bytecheck", + "hashbrown 0.12.3", + "indexmap 1.9.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid 1.4.1", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rlp-derive", + "rustc-hex", +] + +[[package]] +name = "rlp-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ruint" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95294d6e3a6192f3aabf91c38f56505a625aa495533442744185a36d75a790c4" +dependencies = [ + "proptest", + "rand", + "ruint-macro", + "serde", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09" + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc-host" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cca3c284cc507e641638806e7d3f162814091e0122a5b9877063b6c9c7b9f2" +dependencies = [ + "thiserror", +] + +[[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.38.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed6248e1caa625eb708e266e06159f135e8c26f2bb7ceb72dc4b2766d0340964" +dependencies = [ + "bitflags 2.4.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustls" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +dependencies = [ + "log", + "ring", + "rustls-webpki 0.101.4", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +dependencies = [ + "base64 0.21.3", +] + +[[package]] +name = "rustls-webpki" +version = "0.100.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e98ff011474fa39949b7e5c0428f9b4937eda7da7848bbb947786b7be0b27dab" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d93931baf2d282fff8d3a532bbfd7653f734643161b87e3e01e59a04439bf0d" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "salsa20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +dependencies = [ + "cipher", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scale-info" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c0a159d0c45c12b20c5a844feb1fe4bea86e28f17b92a5f0c42193634d3782" +dependencies = [ + "cfg-if", + "derive_more", + "parity-scale-codec", + "scale-info-derive", +] + +[[package]] +name = "scale-info-derive" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "912e55f6d20e0e80d63733872b40e1227c0bce1e1ab81ba67d696339bfd7fd29" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scrypt" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f9e24d2b632954ded8ab2ef9fea0a0c769ea56ea98bddbafbad22caeeadf45d" +dependencies = [ + "hmac", + "pbkdf2 0.11.0", + "salsa20", + "sha2", +] + +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +dependencies = [ + "serde", +] + +[[package]] +name = "send_wrapper" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" + +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + +[[package]] +name = "serde" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-hex" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca37e3e4d1b39afd7ff11ee4e947efae85adfddf4841787bfa47c470e96dc26d" +dependencies = [ + "array-init", + "serde", + "smallvec 0.6.14", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_derive" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "serde_json" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +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 = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest", + "rand_core", +] + +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror", + "time", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + +[[package]] +name = "smallvec" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" +dependencies = [ + "maybe-uninit", +] + +[[package]] +name = "smallvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" + +[[package]] +name = "smol_str" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74212e6bbe9a4352329b2f68ba3130c15a3f26fe88ff22dbdc6cdd58fa85e99c" +dependencies = [ + "serde", +] + +[[package]] +name = "sneks" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1754a9953937d149fb279d362241e4b92c4f237a491f4524835e8e78dd43810d" +dependencies = [ + "convert_case 0.6.0", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "solang-parser" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cb9fa2fa2fa6837be8a2495486ff92e3ffe68a99b6eeba288e139efdd842457" +dependencies = [ + "itertools 0.11.0", + "lalrpop", + "lalrpop-util", + "phf", + "thiserror", + "unicode-xid", +] + +[[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 = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "string_cache" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +dependencies = [ + "new_debug_unreachable", + "once_cell", + "parking_lot", + "phf_shared 0.10.0", + "precomputed-hash", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.37", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "svm-rs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597e3a746727984cb7ea2487b6a40726cad0dbe86628e7d429aa6b8c4c153db4" +dependencies = [ + "dirs", + "fs2", + "hex", + "once_cell", + "reqwest", + "semver", + "serde", + "serde_json", + "sha2", + "thiserror", + "url", + "zip", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "target-lexicon" +version = "0.12.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" + +[[package]] +name = "tempfile" +version = "3.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.3.5", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] + +[[package]] +name = "thiserror" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "time" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" +dependencies = [ + "deranged", + "itoa", + "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.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" +dependencies = [ + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[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.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2 0.5.3", + "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.37", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2dbec703c26b00d74844519606ef15d09a7d6857860f84ad223dec002ddea2" +dependencies = [ + "futures-util", + "log", + "rustls", + "tokio", + "tokio-rustls", + "tungstenite", + "webpki-roots 0.23.1", +] + +[[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-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +dependencies = [ + "indexmap 2.0.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[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", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "tungstenite" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e862a1c4128df0112ab625f55cd5c934bcb4312ba80b39ae4b4835a3fd58e649" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand", + "rustls", + "sha1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[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.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom", + "serde", +] + +[[package]] +name = "uuid" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + +[[package]] +name = "walkdir" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[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.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.37", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-downcast" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340" +dependencies = [ + "js-sys", + "once_cell", + "wasm-bindgen", + "wasm-bindgen-downcast-macros", +] + +[[package]] +name = "wasm-bindgen-downcast-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "wasm-encoder" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ba64e81215916eaeb48fee292f29401d69235d62d8b8fd92a7b2844ec5ae5f7" +dependencies = [ + "leb128", +] + +[[package]] +name = "wasmer" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78caedecd8cb71ed47ccca03b68d69414a3d278bb031e6f93f15759344efdd52" +dependencies = [ + "bytes", + "cfg-if", + "derivative", + "indexmap 1.9.3", + "js-sys", + "more-asserts", + "rustc-demangle", + "serde", + "serde-wasm-bindgen", + "target-lexicon", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-downcast", + "wasmer-compiler", + "wasmer-compiler-cranelift", + "wasmer-derive", + "wasmer-types", + "wasmer-vm", + "wat", + "winapi", +] + +[[package]] +name = "wasmer-compiler" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726a8450541af4a57c34af7b6973fdbfc79f896cc7e733429577dfd1d1687180" +dependencies = [ + "backtrace", + "cfg-if", + "enum-iterator", + "enumset", + "lazy_static", + "leb128", + "memmap2", + "more-asserts", + "region", + "smallvec 1.11.0", + "thiserror", + "wasmer-types", + "wasmer-vm", + "wasmparser", + "winapi", +] + +[[package]] +name = "wasmer-compiler-cranelift" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e5633f90f372563ebbdf3f9799c7b29ba11c90e56cf9b54017112d2e656c95" +dependencies = [ + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "gimli 0.26.2", + "more-asserts", + "rayon", + "smallvec 1.11.0", + "target-lexicon", + "tracing", + "wasmer-compiler", + "wasmer-types", +] + +[[package]] +name = "wasmer-derive" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97901fdbaae383dbb90ea162cc3a76a9fa58ac39aec7948b4c0b9bbef9307738" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "wasmer-types" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67f1f2839f4f61509550e4ddcd0e658e19f3af862b51c79fda15549d735d659b" +dependencies = [ + "bytecheck", + "enum-iterator", + "enumset", + "indexmap 1.9.3", + "more-asserts", + "rkyv", + "target-lexicon", + "thiserror", +] + +[[package]] +name = "wasmer-vm" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043118ec4f16d1714fed3aab758b502b864bd865e1d5188626c9ad290100563f" +dependencies = [ + "backtrace", + "cc", + "cfg-if", + "corosensei", + "dashmap", + "derivative", + "enum-iterator", + "fnv", + "indexmap 1.9.3", + "lazy_static", + "libc", + "mach", + "memoffset 0.8.0", + "more-asserts", + "region", + "scopeguard", + "thiserror", + "wasmer-types", + "winapi", +] + +[[package]] +name = "wasmparser" +version = "0.95.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ea896273ea99b15132414be1da01ab0d8836415083298ecaffbe308eaac87a" +dependencies = [ + "indexmap 1.9.3", + "url", +] + +[[package]] +name = "wast" +version = "64.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a259b226fd6910225aa7baeba82f9d9933b6d00f2ce1b49b80fa4214328237cc" +dependencies = [ + "leb128", + "memchr", + "unicode-width", + "wasm-encoder", +] + +[[package]] +name = "wat" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53253d920ab413fca1c7dc2161d601c79b4fdf631d0ba51dd4343bf9b556c3f6" +dependencies = [ + "wast", +] + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" +dependencies = [ + "rustls-webpki 0.100.2", +] + +[[package]] +name = "webpki-roots" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" + +[[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-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[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.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43dbb096663629518eb1dfa72d80243ca5a6aca764cae62a2df70af760a9be75" +dependencies = [ + "windows_aarch64_msvc 0.33.0", + "windows_i686_gnu 0.33.0", + "windows_i686_msvc 0.33.0", + "windows_x86_64_gnu 0.33.0", + "windows_x86_64_msvc 0.33.0", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "winnow" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "ws_stream_wasm" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7999f5f4217fe3818726b66257a4475f71e74ffd190776ad053fa159e50737f5" +dependencies = [ + "async_io_stream", + "futures", + "js-sys", + "log", + "pharos", + "rustc_version", + "send_wrapper 0.6.0", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" + +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "aes", + "byteorder", + "bzip2", + "constant_time_eq", + "crc32fast", + "crossbeam-utils", + "flate2", + "hmac", + "pbkdf2 0.11.0", + "sha1", + "time", + "zstd", +] + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[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/check/Cargo.toml b/check/Cargo.toml new file mode 100644 index 0000000..f223bc1 --- /dev/null +++ b/check/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "cargo-stylus-check" +keywords = ["arbitrum", "ethereum", "stylus", "alloy", "cargo"] +description = "CLI tool for deploying Stylus contracts on Arbitrum chains" + +authors.workspace = true +edition.workspace = true +homepage.workspace = true +license.workspace = true +version.workspace = true +repository.workspace = true + +[dependencies] +alloy-primitives.workspace = true +alloy-json-abi.workspace = true +alloy-sol-macro.workspace = true +alloy-sol-types.workspace = true +alloy-ethers-typecast.workspace = true +brotli2 = "0.3.2" +bytes = "1.4.0" +bytesize = "1.2.0" +cargo-stylus-util.workspace = true +clap.workspace = true +eyre.workspace = true +hex.workspace = true +lazy_static.workspace = true +serde = { version = "1.0.188", features = ["derive"] } +ethers.workspace = true +serde_json = "1.0.103" +tiny-keccak = { version = "2.0.2", features = ["keccak"] } +thiserror = "1.0.47" +tokio.workspace = true +wasmer = "3.1.0" diff --git a/Dockerfile b/check/Dockerfile similarity index 100% rename from Dockerfile rename to check/Dockerfile diff --git a/OPTIMIZING_BINARIES.md b/check/OPTIMIZING_BINARIES.md similarity index 100% rename from OPTIMIZING_BINARIES.md rename to check/OPTIMIZING_BINARIES.md diff --git a/VALID_WASM.md b/check/VALID_WASM.md similarity index 100% rename from VALID_WASM.md rename to check/VALID_WASM.md diff --git a/licenses/Apache-2.0 b/check/licenses/Apache-2.0 similarity index 100% rename from licenses/Apache-2.0 rename to check/licenses/Apache-2.0 diff --git a/licenses/COPYRIGHT.md b/check/licenses/COPYRIGHT.md similarity index 100% rename from licenses/COPYRIGHT.md rename to check/licenses/COPYRIGHT.md diff --git a/licenses/DCO.txt b/check/licenses/DCO.txt similarity index 100% rename from licenses/DCO.txt rename to check/licenses/DCO.txt diff --git a/licenses/MIT b/check/licenses/MIT similarity index 100% rename from licenses/MIT rename to check/licenses/MIT diff --git a/check/src/check.rs b/check/src/check.rs new file mode 100644 index 0000000..771168f --- /dev/null +++ b/check/src/check.rs @@ -0,0 +1,234 @@ +// Copyright 2023-2024, Offchain Labs, Inc. +// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md + +use crate::{ + check::ArbWasm::ArbWasmErrors, + constants::{ARB_WASM_H160, ONE_ETH}, + macros::*, + project::{self, BuildConfig}, + CheckConfig, +}; +use alloy_primitives::{Address, B256, U256}; +use alloy_sol_macro::sol; +use alloy_sol_types::{SolCall, SolInterface}; +use bytesize::ByteSize; +use cargo_stylus_util::{color::Color, sys, text}; +use ethers::{ + core::types::spoof, + prelude::*, + providers::RawCall, + types::{spoof::State, transaction::eip2718::TypedTransaction, Eip1559TransactionRequest}, +}; +use eyre::{bail, eyre, ErrReport, Result, WrapErr}; +use serde_json::Value; +use std::path::PathBuf; + +sol! { + interface ArbWasm { + function activateProgram(address program) + external + payable + returns (uint16 version, uint256 dataFee); + + function stylusVersion() external view returns (uint16 version); + + function codehashVersion(bytes32 codehash) external view returns (uint16 version); + + error ProgramNotWasm(); + error ProgramNotActivated(); + error ProgramNeedsUpgrade(uint16 version, uint16 stylusVersion); + error ProgramExpired(uint64 ageInSeconds); + error ProgramUpToDate(); + error ProgramKeepaliveTooSoon(uint64 ageInSeconds); + error ProgramInsufficientValue(uint256 have, uint256 want); + } +} + +/// Checks that a program is valid and can be deployed onchain. +/// Returns whether the WASM is already up-to-date and activated onchain, and the data fee. +pub async fn check(cfg: &CheckConfig) -> Result { + if cfg.endpoint == "https://stylus-testnet.arbitrum.io/rpc" { + let version = "cargo stylus version 0.2.1".to_string().red(); + bail!("The old Stylus testnet is no longer supported.\nPlease downgrade to {version}",); + } + + let verbose = cfg.verbose; + let wasm = cfg.build_wasm().wrap_err("failed to build wasm")?; + + if verbose { + greyln!("reading wasm file at {}", wasm.to_string_lossy().lavender()); + } + + let (wasm, code) = project::compress_wasm(&wasm).wrap_err("failed to compress WASM")?; + + greyln!("contract size: {}", format_file_size(code.len(), 16, 24)); + + if verbose { + greyln!("wasm size: {}", format_file_size(wasm.len(), 96, 128)); + greyln!("connecting to RPC: {}", &cfg.endpoint.lavender()); + } + + // check if the program already exists + let provider = sys::new_provider(&cfg.endpoint)?; + let codehash = alloy_primitives::keccak256(&code); + + if program_exists(codehash, &provider).await? { + return Ok(ProgramCheck::Active(code)); + } + + let address = cfg.program_address.unwrap_or(H160::random()); + let fee = check_activate(code.clone().into(), address, &provider).await?; + let visual_fee = format_data_fee(fee).unwrap_or("???".red()); + greyln!("wasm data fee: {visual_fee}"); + Ok(ProgramCheck::Ready(code, fee)) +} + +/// Whether a program is active, or needs activation. +#[derive(PartialEq)] +pub enum ProgramCheck { + /// Program already exists onchain. + Active(Vec), + /// Program can be activated with the given data fee. + Ready(Vec, U256), +} + +impl ProgramCheck { + pub fn code(&self) -> &[u8] { + match self { + Self::Active(code) => code, + Self::Ready(code, _) => code, + } + } + + pub fn suggest_fee(&self) -> U256 { + match self { + Self::Active(_) => U256::default(), + Self::Ready(_, data_fee) => data_fee * U256::from(120) / U256::from(100), + } + } +} + +impl CheckConfig { + fn build_wasm(&self) -> Result { + if let Some(wasm) = self.wasm_file.clone() { + return Ok(wasm); + } + project::build_dylib(BuildConfig::new(self.rust_stable)) + } +} + +/// Pretty-prints a file size based on its limits. +pub fn format_file_size(len: usize, mid: u64, max: u64) -> String { + let len = ByteSize::b(len as u64); + let mid = ByteSize::kib(mid); + let max = ByteSize::kib(max); + if len <= mid { + len.mint() + } else if len <= max { + len.yellow() + } else { + len.pink() + } +} + +/// Pretty-prints a data fee. +fn format_data_fee(fee: U256) -> Result { + let fee: u64 = (fee / U256::from(1e9)).try_into()?; + let fee: f64 = fee as f64 / 1e9; + let text = format!("Ξ{fee:.6}"); + Ok(if fee <= 5e14 { + text.mint() + } else if fee <= 5e15 { + text.yellow() + } else { + text.pink() + }) +} + +struct EthCallError { + data: Vec, + msg: String, +} + +impl From for ErrReport { + fn from(value: EthCallError) -> Self { + eyre!(value.msg) + } +} + +/// A funded eth_call to ArbWasm. +async fn eth_call( + tx: Eip1559TransactionRequest, + mut state: State, + provider: &Provider, +) -> Result, EthCallError>> { + let tx = TypedTransaction::Eip1559(tx.to(*ARB_WASM_H160)); + state.account(Default::default()).balance = Some(ethers::types::U256::MAX); // infinite balance + + match provider.call_raw(&tx).state(&state).await { + Ok(bytes) => Ok(Ok(bytes.to_vec())), + Err(ProviderError::JsonRpcClientError(error)) => { + let error = error + .as_error_response() + .ok_or_else(|| eyre!("json RPC failure: {error}"))?; + + let msg = error.message.clone(); + let data = match &error.data { + Some(Value::String(data)) => text::decode0x(data)?.to_vec(), + Some(value) => bail!("failed to decode RPC failure: {value}"), + None => vec![], + }; + Ok(Err(EthCallError { data, msg })) + } + Err(error) => Err(error.into()), + } +} + +/// Checks whether a program has already been activated with the most recent version of Stylus. +async fn program_exists(codehash: B256, provider: &Provider) -> Result { + let data = ArbWasm::codehashVersionCall { codehash }.abi_encode(); + let tx = Eip1559TransactionRequest::new().data(data); + let outs = eth_call(tx, State::default(), provider).await?; + + let program_version = match outs { + Ok(outs) => { + let ArbWasm::codehashVersionReturn { version } = + ArbWasm::codehashVersionCall::abi_decode_returns(&outs, true)?; + version + } + Err(EthCallError { data, msg }) => { + let Ok(error) = ArbWasmErrors::abi_decode(&data, true) else { + bail!("unknown ArbWasm error: {msg}"); + }; + use ArbWasmErrors as A; + match error { + A::ProgramNotWasm(_) => bail!("not a Stylus program"), + A::ProgramNotActivated(_) | A::ProgramNeedsUpgrade(_) | A::ProgramExpired(_) => { + return Ok(false); + } + _ => bail!("unexpected ArbWasm error: {msg}"), + } + } + }; + + let data = ArbWasm::stylusVersionCall {}.abi_encode(); + let tx = Eip1559TransactionRequest::new().data(data); + let outs = eth_call(tx, State::default(), provider).await??; + let ArbWasm::stylusVersionReturn { version } = + ArbWasm::stylusVersionCall::abi_decode_returns(&outs, true)?; + + Ok(program_version == version) +} + +/// Checks program activation, returning the data fee. +async fn check_activate(code: Bytes, address: H160, provider: &Provider) -> Result { + let program = Address::from(address.to_fixed_bytes()); + let data = ArbWasm::activateProgramCall { program }.abi_encode(); + let tx = Eip1559TransactionRequest::new().data(data).value(ONE_ETH); + let state = spoof::code(address, code); + let outs = eth_call(tx, state, provider).await??; + let ArbWasm::activateProgramReturn { dataFee, .. } = + ArbWasm::activateProgramCall::abi_decode_returns(&outs, true)?; + + Ok(dataFee) +} diff --git a/check/src/constants.rs b/check/src/constants.rs new file mode 100644 index 0000000..9c7b9a8 --- /dev/null +++ b/check/src/constants.rs @@ -0,0 +1,33 @@ +// Copyright 2023-2024, Offchain Labs, Inc. +// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md + +use alloy_primitives::{address, Address}; +use ethers::types::{H160, U256}; +use lazy_static::lazy_static; + +/// EOF prefix used in Stylus compressed WASMs on-chain +pub const EOF_PREFIX_NO_DICT: &str = "EFF00000"; + +/// Maximum brotli compression level used for Stylus programs. +pub const BROTLI_COMPRESSION_LEVEL: u32 = 11; + +lazy_static! { + /// Address of the ArbWasm precompile. + pub static ref ARB_WASM_H160: H160 = H160(*ARB_WASM_ADDRESS.0); +} + +/// Address of the ArbWasm precompile. +pub const ARB_WASM_ADDRESS: Address = address!("0000000000000000000000000000000000000071"); + +/// Target for compiled WASM folder in a Rust project +pub const RUST_TARGET: &str = "wasm32-unknown-unknown"; + +/// The default repo to clone when creating new projects +pub const GITHUB_TEMPLATE_REPO: &str = "https://github.com/OffchainLabs/stylus-hello-world"; + +/// The minimal entrypoint repo +pub const GITHUB_TEMPLATE_REPO_MINIMAL: &str = + "https://github.com/OffchainLabs/stylus-hello-world-minimal"; + +/// One ether in wei. +pub const ONE_ETH: U256 = U256([1000000000000000000, 0, 0, 0]); diff --git a/check/src/deploy.rs b/check/src/deploy.rs new file mode 100644 index 0000000..7f2792d --- /dev/null +++ b/check/src/deploy.rs @@ -0,0 +1,232 @@ +// Copyright 2023-2024, Offchain Labs, Inc. +// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md + +#![allow(clippy::println_empty_string)] + +use crate::{ + check::{self, ProgramCheck}, + constants::ARB_WASM_H160, + macros::*, + DeployConfig, +}; +use alloy_primitives::{Address, U256 as AU256}; +use alloy_sol_macro::sol; +use alloy_sol_types::SolCall; +use cargo_stylus_util::{ + color::{Color, DebugColor}, + sys, +}; +use ethers::{ + core::k256::ecdsa::SigningKey, + middleware::SignerMiddleware, + prelude::*, + providers::{Middleware, Provider}, + signers::Signer, + types::{transaction::eip2718::TypedTransaction, Eip1559TransactionRequest, H160, U256, U64}, +}; +use eyre::{bail, eyre, Result, WrapErr}; + +sol! { + interface ArbWasm { + function activateProgram(address program) + external + payable + returns (uint16 version, uint256 dataFee); + } +} + +type SignerClient = SignerMiddleware, Wallet>; + +/// Deploys a stylus program, activating if needed. +pub async fn deploy(cfg: DeployConfig) -> Result<()> { + macro_rules! run { + ($expr:expr) => { + $expr.await? + }; + ($expr:expr, $($msg:expr),+) => { + $expr.await.wrap_err_with(|| eyre!($($msg),+))? + }; + } + + let program = run!(check::check(&cfg.check_config), "cargo stylus check failed"); + let verbose = cfg.check_config.verbose; + + let client = sys::new_provider(&cfg.check_config.endpoint)?; + let chain_id = run!(client.get_chainid(), "failed to get chain id"); + + let wallet = cfg.auth.wallet().wrap_err("failed to load wallet")?; + let wallet = wallet.with_chain_id(chain_id.as_u64()); + let sender = wallet.address(); + let client = SignerMiddleware::new(client, wallet); + + if verbose { + greyln!("sender address: {}", sender.debug_lavender()); + } + + let data_fee = program.suggest_fee(); + + if let ProgramCheck::Ready(..) = &program { + // check balance early + let balance = run!(client.get_balance(sender, None), "failed to get balance"); + let balance = alloy_ethers_typecast::ethers_u256_to_alloy(balance); + + if balance < data_fee && !cfg.estimate_gas { + bail!( + "not enough funds in account {} to pay for data fee\n\ + balance {} < {}\n\ + please see the Quickstart guide for funding new accounts:\n{}", + sender.red(), + balance.red(), + format!("{data_fee} wei").red(), + "https://docs.arbitrum.io/stylus/stylus-quickstart".yellow(), + ); + } + } + + let contract = cfg.deploy_contract(program.code(), sender, &client).await?; + + match program { + ProgramCheck::Ready(..) => cfg.activate(sender, contract, data_fee, &client).await?, + ProgramCheck::Active(_) => greyln!("wasm already activated!"), + } + Ok(()) +} + +impl DeployConfig { + async fn deploy_contract( + &self, + code: &[u8], + sender: H160, + client: &SignerClient, + ) -> Result { + let mut init_code = Vec::with_capacity(42 + code.len()); + init_code.push(0x7f); // PUSH32 + init_code.extend(AU256::from(code.len()).to_be_bytes::<32>()); + init_code.push(0x80); // DUP1 + init_code.push(0x60); // PUSH1 + init_code.push(0x2a); // 42 the prelude length + init_code.push(0x60); // PUSH1 + init_code.push(0x00); + init_code.push(0x39); // CODECOPY + init_code.push(0x60); // PUSH1 + init_code.push(0x00); + init_code.push(0xf3); // RETURN + init_code.extend(code); + + let tx = Eip1559TransactionRequest::new() + .from(sender) + .data(init_code); + + let verbose = self.check_config.verbose; + let gas = client + .estimate_gas(&TypedTransaction::Eip1559(tx.clone()), None) + .await?; + + if self.check_config.verbose || self.estimate_gas { + greyln!("deploy gas estimate: {}", format_gas(gas)); + } + if self.estimate_gas { + let nonce = client.get_transaction_count(sender, None).await?; + return Ok(ethers::utils::get_contract_address(sender, nonce)); + } + + let receipt = self.run_tx("deploy", tx, Some(gas), client).await?; + let contract = receipt.contract_address.ok_or(eyre!("missing address"))?; + let address = contract.debug_lavender(); + + if verbose { + let gas = format_gas(receipt.gas_used.unwrap_or_default()); + greyln!( + "deployed code at address: {address} {} {gas}", + "with".grey() + ); + } else { + greyln!("deployed code at address: {address}"); + } + Ok(contract) + } + + async fn activate( + &self, + sender: H160, + contract: H160, + data_fee: AU256, + client: &SignerClient, + ) -> Result<()> { + let verbose = self.check_config.verbose; + let data_fee = alloy_ethers_typecast::alloy_u256_to_ethers(data_fee); + let program: Address = contract.to_fixed_bytes().into(); + + let data = ArbWasm::activateProgramCall { program }.abi_encode(); + + let tx = Eip1559TransactionRequest::new() + .from(sender) + .to(*ARB_WASM_H160) + .data(data) + .value(data_fee); + + let gas = client + .estimate_gas(&TypedTransaction::Eip1559(tx.clone()), None) + .await + .map_err(|e| eyre!("did not estimate correctly: {e}"))?; + + if self.check_config.verbose || self.estimate_gas { + greyln!("activation gas estimate: {}", format_gas(gas)); + } + if self.estimate_gas { + return Ok(()); + } + + let receipt = self.run_tx("activate", tx, Some(gas), client).await?; + + if verbose { + let gas = format_gas(receipt.gas_used.unwrap_or_default()); + greyln!("activated with {gas}"); + } + greyln!( + "program activated and ready onchain with tx hash: {}", + receipt.transaction_hash.debug_lavender() + ); + Ok(()) + } + + async fn run_tx( + &self, + name: &str, + tx: Eip1559TransactionRequest, + gas: Option, + client: &SignerClient, + ) -> Result { + let mut tx = TypedTransaction::Eip1559(tx); + if let Some(gas) = gas { + tx.set_gas(gas); + } + + let tx = client.send_transaction(tx, None).await?; + let tx_hash = tx.tx_hash(); + let verbose = self.check_config.verbose; + + if verbose { + greyln!("sent {name} tx: {}", tx_hash.debug_lavender()); + } + let Some(receipt) = tx.await.wrap_err("tx failed to complete")? else { + bail!("failed to get receipt for tx {}", tx_hash.lavender()); + }; + if receipt.status != Some(U64::from(1)) { + bail!("{name} tx reverted {}", tx_hash.debug_red()); + } + Ok(receipt) + } +} + +fn format_gas(gas: U256) -> String { + let gas: u64 = gas.try_into().unwrap_or(u64::MAX); + let text = format!("{gas} gas"); + if gas <= 3_000_000 { + text.mint() + } else if gas <= 7_000_000 { + text.yellow() + } else { + text.pink() + } +} diff --git a/check/src/export_abi.rs b/check/src/export_abi.rs new file mode 100644 index 0000000..d508395 --- /dev/null +++ b/check/src/export_abi.rs @@ -0,0 +1,56 @@ +// Copyright 2023-2024, Offchain Labs, Inc. +// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md + +use crate::macros::*; +use cargo_stylus_util::{color::Color, sys}; +use eyre::{bail, Result, WrapErr}; +use std::{ + io::Write, + path::PathBuf, + process::{self, Command, Stdio}, +}; + +/// Exports Solidity ABIs by running the program natively. +pub fn export_abi(file: Option, json: bool) -> Result<()> { + if json && !sys::command_exists("solc") { + let link = "https://docs.soliditylang.org/en/latest/installing-solidity.html".red(); + bail!("solc not found. Please see\n{link}"); + } + + let target = format!("--target={}", sys::host_arch()?); + let mut output = Command::new("cargo") + .stderr(Stdio::inherit()) + .arg("run") + .arg("--features=export-abi") + .arg(target) + .output()?; + + if !output.status.success() { + let out = String::from_utf8_lossy(&output.stdout); + let out = (out != "") + .then_some(format!(": {out}")) + .unwrap_or_default(); + egreyln!("failed to run program{out}"); + process::exit(1); + } + + // convert the ABI to a JSON file via solc + if json { + let solc = Command::new("solc") + .stdin(Stdio::piped()) + .stderr(Stdio::inherit()) + .stdout(Stdio::piped()) + .arg("--abi") + .arg("-") + .spawn() + .wrap_err("failed to run solc")?; + + let mut stdin = solc.stdin.as_ref().unwrap(); + stdin.write_all(&output.stdout)?; + output = solc.wait_with_output()?; + } + + let mut out = sys::file_or_stdout(file)?; + out.write_all(&output.stdout)?; + Ok(()) +} diff --git a/check/src/macros.rs b/check/src/macros.rs new file mode 100644 index 0000000..82aef8d --- /dev/null +++ b/check/src/macros.rs @@ -0,0 +1,18 @@ +// Copyright 2023-2024, Offchain Labs, Inc. +// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md + +macro_rules! greyln { + ($($msg:expr),*) => {{ + let msg = format!($($msg),*); + println!("{}", msg.grey()) + }}; +} + +macro_rules! egreyln { + ($($msg:expr),*) => {{ + let msg = format!($($msg),*); + eprintln!("{}", msg.grey()) + }}; +} + +pub(crate) use {egreyln, greyln}; diff --git a/check/src/main.rs b/check/src/main.rs new file mode 100644 index 0000000..4de49b2 --- /dev/null +++ b/check/src/main.rs @@ -0,0 +1,133 @@ +// Copyright 2023-2024, Offchain Labs, Inc. +// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md + +use clap::{ArgGroup, Args, Parser}; +use ethers::types::H160; +use eyre::{eyre, Context, Result}; +use std::path::PathBuf; +use tokio::runtime::Builder; + +mod check; +mod constants; +mod deploy; +mod export_abi; +mod macros; +mod new; +mod project; +mod wallet; + +#[derive(Parser, Debug)] +#[command(name = "check")] +#[command(bin_name = "cargo stylus")] +#[command(author = "Offchain Labs, Inc.")] +#[command(propagate_version = true)] +#[command(version)] +struct Opts { + #[command(subcommand)] + command: Apis, +} + +#[derive(Parser, Debug, Clone)] +enum Apis { + /// Create a new Rust project. + New { + /// Project name. + name: PathBuf, + /// Create a minimal program. + #[arg(long)] + minimal: bool, + }, + /// Export a Solidity ABI. + ExportAbi { + /// The output file (defaults to stdout). + #[arg(long)] + output: Option, + /// Write a JSON ABI instead using solc. Requires solc. + #[arg(long)] + json: bool, + }, + /// Check a contract. + #[command(alias = "c")] + Check(CheckConfig), + /// Deploy a contract. + #[command(alias = "d")] + Deploy(DeployConfig), +} + +#[derive(Args, Clone, Debug)] +struct CheckConfig { + /// Arbitrum RPC endpoint. + #[arg(short, long, default_value = "https://stylusv2.arbitrum.io/rpc")] + endpoint: String, + /// The WASM to check (defaults to any found in the current directory). + #[arg(long)] + wasm_file: Option, + /// Where to deploy and activate the program (defaults to a random address). + #[arg(long)] + program_address: Option, + /// Whether to use stable Rust. + #[arg(long)] + rust_stable: bool, + /// Whether to print debug info. + #[arg(long)] + verbose: bool, +} + +#[derive(Args, Clone, Debug)] +struct DeployConfig { + #[command(flatten)] + check_config: CheckConfig, + /// Wallet source to use. + #[command(flatten)] + auth: AuthOpts, + /// Only perform gas estimation. + #[arg(long)] + estimate_gas: bool, +} + +#[derive(Clone, Debug, Args)] +#[clap(group(ArgGroup::new("key").required(true).args(&["private_key_path", "private_key", "keystore_path"])))] +struct AuthOpts { + /// File path to a text file containing a hex-encoded private key. + #[arg(long)] + private_key_path: Option, + /// Private key as a hex string. Warning: this exposes your key to shell history. + #[arg(long)] + private_key: Option, + /// Path to an Ethereum wallet keystore file (e.g. clef). + #[arg(long)] + keystore_path: Option, + /// Keystore password file. + #[arg(long)] + keystore_password_path: Option, +} + +fn main() -> Result<()> { + let args = Opts::parse(); + let runtime = Builder::new_multi_thread().enable_all().build()?; + runtime.block_on(main_impl(args)) +} + +async fn main_impl(args: Opts) -> Result<()> { + macro_rules! run { + ($expr:expr, $($msg:expr),+) => { + $expr.wrap_err_with(|| eyre!($($msg),+))? + }; + } + + match args.command { + Apis::New { name, minimal } => { + run!(new::new(&name, minimal), "failed to open new project"); + } + Apis::ExportAbi { json, output } => { + run!(export_abi::export_abi(output, json), "failed to export abi"); + } + Apis::Check(config) => { + run!(check::check(&config).await, "stylus checks failed"); + } + Apis::Deploy(config) => { + run!(deploy::deploy(config).await, "failed to deploy"); + } + } + Ok(()) +} diff --git a/check/src/new.rs b/check/src/new.rs new file mode 100644 index 0000000..668df01 --- /dev/null +++ b/check/src/new.rs @@ -0,0 +1,31 @@ +// Copyright 2023-2024, Offchain Labs, Inc. +// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md + +use crate::constants::{GITHUB_TEMPLATE_REPO, GITHUB_TEMPLATE_REPO_MINIMAL}; +use cargo_stylus_util::{ + color::{Color, GREY}, + sys, +}; +use eyre::{bail, Context, Result}; +use std::{env::current_dir, path::Path}; + +/// Creates a new Stylus project in the current directory +pub fn new(name: &Path, minimal: bool) -> Result<()> { + let repo = match minimal { + true => GITHUB_TEMPLATE_REPO_MINIMAL, + false => GITHUB_TEMPLATE_REPO, + }; + let output = sys::new_command("git") + .arg("clone") + .arg(repo) + .arg(name) + .output() + .wrap_err("git clone failed")?; + + if !output.status.success() { + bail!("git clone command failed"); + } + let path = current_dir().wrap_err("no current dir")?.join(name); + println!("{GREY}new project at: {}", path.to_string_lossy().mint()); + Ok(()) +} diff --git a/check/src/project.rs b/check/src/project.rs new file mode 100644 index 0000000..fce5bcf --- /dev/null +++ b/check/src/project.rs @@ -0,0 +1,132 @@ +// Copyright 2023-2024, Offchain Labs, Inc. +// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md + +use crate::{ + constants::{BROTLI_COMPRESSION_LEVEL, EOF_PREFIX_NO_DICT, RUST_TARGET}, + macros::*, +}; +use brotli2::read::BrotliEncoder; +use cargo_stylus_util::{color::Color, sys}; +use eyre::{eyre, Result, WrapErr}; +use std::{env::current_dir, fs, io::Read, path::PathBuf, process}; + +#[derive(Default, PartialEq)] +pub enum OptLevel { + #[default] + S, + Z, +} + +#[derive(Default)] +pub struct BuildConfig { + pub opt_level: OptLevel, + pub stable: bool, + pub rebuild: bool, +} + +impl BuildConfig { + pub fn new(stable: bool) -> Self { + Self { + stable, + ..Default::default() + } + } +} + +#[derive(thiserror::Error, Debug, PartialEq, Eq, Clone)] +pub enum BuildError { + #[error("could not find WASM in release dir ({path}).")] + NoWasmFound { path: PathBuf }, +} + +/// Build a Rust project to WASM and return the path to the compiled WASM file. +pub fn build_dylib(cfg: BuildConfig) -> Result { + let cwd: PathBuf = current_dir().map_err(|e| eyre!("could not get current dir: {e}"))?; + + let mut cmd = sys::new_command("cargo"); + + if !cfg.stable { + cmd.arg("+nightly"); + } + + cmd.arg("build"); + cmd.arg("--lib"); + + if !cfg.stable { + cmd.arg("-Z"); + cmd.arg("build-std=std,panic_abort"); + cmd.arg("-Z"); + cmd.arg("build-std-features=panic_immediate_abort"); + } + + if cfg.opt_level == OptLevel::Z { + cmd.arg("--config"); + cmd.arg("profile.release.opt-level='z'"); + } + + let output = cmd + .arg("--release") + .arg(format!("--target={RUST_TARGET}")) + .output() + .wrap_err("failed to execute cargo build")?; + + if !output.status.success() { + egreyln!("cargo build command failed"); + process::exit(1); + } + + let release_path = cwd + .join("target") + .join(RUST_TARGET) + .join("release") + .join("deps"); + + // Gets the files in the release folder. + let release_files: Vec = fs::read_dir(&release_path) + .map_err(|e| eyre!("could not read deps dir: {e}"))? + .filter_map(|r| r.ok()) + .map(|r| r.path()) + .filter(|r| r.is_file()) + .collect(); + + let wasm_file_path = release_files + .into_iter() + .find(|p| { + if let Some(ext) = p.file_name() { + return ext.to_string_lossy().contains(".wasm"); + } + false + }) + .ok_or(BuildError::NoWasmFound { path: release_path })?; + + let (wasm, code) = compress_wasm(&wasm_file_path).wrap_err("failed to compress WASM")?; + + greyln!( + "contract size: {}", + crate::check::format_file_size(code.len(), 16, 24) + ); + greyln!( + "wasm size: {}", + crate::check::format_file_size(wasm.len(), 96, 128) + ); + Ok(wasm_file_path) +} + +/// Reads a WASM file at a specified path and returns its brotli compressed bytes. +pub fn compress_wasm(wasm: &PathBuf) -> Result<(Vec, Vec)> { + let wasm = + fs::read(wasm).wrap_err_with(|| eyre!("failed to read Wasm {}", wasm.to_string_lossy()))?; + + let wasm = wasmer::wat2wasm(&wasm).wrap_err("failed to parse Wasm")?; + + let mut compressor = BrotliEncoder::new(&*wasm, BROTLI_COMPRESSION_LEVEL); + let mut compressed_bytes = vec![]; + compressor + .read_to_end(&mut compressed_bytes) + .wrap_err("failed to compress WASM bytes")?; + + let mut contract_code = hex::decode(EOF_PREFIX_NO_DICT).unwrap(); + contract_code.extend(compressed_bytes); + + Ok((wasm.to_vec(), contract_code)) +} diff --git a/check/src/wallet.rs b/check/src/wallet.rs new file mode 100644 index 0000000..55fb461 --- /dev/null +++ b/check/src/wallet.rs @@ -0,0 +1,38 @@ +// Copyright 2023-2024, Offchain Labs, Inc. +// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md + +use crate::AuthOpts; +use cargo_stylus_util::text; +use ethers::signers::LocalWallet; +use eyre::{eyre, Context, Result}; +use std::fs; + +/// Loads a wallet for signing transactions. +impl AuthOpts { + pub fn wallet(&self) -> Result { + macro_rules! wallet { + ($key:expr) => {{ + let key = text::decode0x($key).wrap_err("invalid private key")?; + LocalWallet::from_bytes(&key).wrap_err("invalid private key") + }}; + } + + if let Some(key) = &self.private_key { + return wallet!(key); + } + + if let Some(file) = &self.private_key_path { + let key = fs::read_to_string(file).wrap_err("could not open private key file")?; + return wallet!(key); + } + + let keystore = self.keystore_path.as_ref().ok_or(eyre!("no keystore"))?; + let password = self + .keystore_password_path + .as_ref() + .map(fs::read_to_string) + .unwrap_or(Ok("".into()))?; + + LocalWallet::decrypt_keystore(keystore, password).wrap_err("could not decrypt keystore") + } +} diff --git a/example/Cargo.toml b/example/Cargo.toml new file mode 100644 index 0000000..51e691a --- /dev/null +++ b/example/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "cargo-stylus-example" +authors.workspace = true +version.workspace = true +edition.workspace = true +homepage.workspace = true +license.workspace = true +repository.workspace = true + +[dependencies] +clap.workspace = true diff --git a/example/src/main.rs b/example/src/main.rs new file mode 100644 index 0000000..ac2e947 --- /dev/null +++ b/example/src/main.rs @@ -0,0 +1,51 @@ +// Copyright 2023-2024, Offchain Labs, Inc. +// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md + +//! This crate provides an example cargo stylus extension named `cargo-stylus-example`. +//! Normally, the command `cargo stylus example` would return an error saying it's unknown. +//! Installing this crate will cause `cargo stylus` to run this subcommand. +//! +//! ```sh +//! cargo install --path example # use this when developing locally. +//! cargo install cargo-stylus-example # use this once you've published the crate. +//! cargo stylus example --help # see that execution passes here. +//! ``` + +use clap::Parser; +use std::path::PathBuf; + +#[derive(Parser, Debug)] +#[command(name = "example")] +#[command(bin_name = "cargo stylus")] +#[command(author = "Your name / company")] +#[command(about = "Short description of custom command.", long_about = None)] +#[command(propagate_version = true)] +#[command(version)] +struct Opts { + #[command(subcommand)] + command: Apis, +} + +#[derive(Parser, Debug, Clone)] +enum Apis { + /// Short description of custom command. + #[command()] + Example { + /// Description of this arg. + /// The missing `#[arg()]` annotation means its unnamed. + my_file: PathBuf, + + /// Description of this arg. + /// The `#[arg(long)]` means you have to pass `--my-flag`. + #[arg(long)] + my_flag: bool, + }, +} + +fn main() { + let args = Opts::parse(); + let Apis::Example { my_file, my_flag } = args.command; + + // do something with your args + println!("example: {} {}", my_file.to_string_lossy(), my_flag); +} diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..682f003 --- /dev/null +++ b/install.sh @@ -0,0 +1,5 @@ +cargo fmt +cargo clippy --package cargo-stylus --package cargo-stylus-cgen --package cargo-stylus-check +cargo install --path main +cargo install --path cgen +cargo install --path check diff --git a/main/Cargo.toml b/main/Cargo.toml new file mode 100644 index 0000000..367d996 --- /dev/null +++ b/main/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "cargo-stylus" +keywords = ["arbitrum", "ethereum", "stylus", "alloy", "cargo"] +description = "CLI tool for building Stylus contracts on Arbitrum chains" + +authors.workspace = true +edition.workspace = true +homepage.workspace = true +license.workspace = true +version.workspace = true +repository.workspace = true + +[dependencies] +cargo-stylus-util.workspace = true +clap.workspace = true +eyre.workspace = true diff --git a/main/src/main.rs b/main/src/main.rs new file mode 100644 index 0000000..601afb0 --- /dev/null +++ b/main/src/main.rs @@ -0,0 +1,131 @@ +// Copyright 2023-2024, Offchain Labs, Inc. +// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md + +use cargo_stylus_util::{color::Color, sys}; +use clap::Parser; +use eyre::{bail, Result}; +use std::{env, os::unix::process::CommandExt}; + +#[derive(Parser, Debug)] +#[command(name = "stylus")] +#[command(bin_name = "cargo stylus")] +#[command(author = "Offchain Labs, Inc.")] +#[command(about = "Cargo subcommand for developing Stylus projects", long_about = None)] +#[command(propagate_version = true)] +#[command(version)] +struct Opts { + #[command(subcommand)] + command: Subcommands, +} + +#[derive(Parser, Debug, Clone)] +enum Subcommands { + #[command(alias = "n")] + /// Create a new Rust project. + New, + #[command(alias = "x")] + /// Export a Solidity ABI. + ExportAbi, + /// Check a contract. + #[command(alias = "c")] + Check, + /// Deploy a contract. + #[command(alias = "d")] + Deploy, + /// Replay a transaction in gdb. + #[command(alias = "r")] + Replay, + /// Trace a transaction. + #[command()] + Trace, + /// Generate C code. + #[command()] + CGen, +} + +struct Binary<'a> { + name: &'a str, + apis: &'a [&'a str], + rust_flags: Option<&'a str>, +} + +const COMMANDS: &[Binary] = &[ + Binary { + name: "cargo-stylus-check", + apis: &["new", "export-abi", "check", "deploy", "n", "x", "c", "d"], + rust_flags: None, + }, + Binary { + name: "cargo-stylus-cgen", + apis: &["cgen"], + rust_flags: None, + }, + Binary { + name: "cargo-stylus-replay", + apis: &["trace", "replay", "r"], + rust_flags: None, + }, + Binary { + name: "cargo-stylus-test", + apis: &["test", "t"], + rust_flags: Some(r#"RUSTFLAGS="-C link-args=-rdynamic""#), + }, +]; + +fn exit_with_help_msg() -> ! { + Opts::parse_from(["--help"]); + unreachable!() +} + +fn exit_with_version() -> ! { + Opts::parse_from(["--version"]); + unreachable!() +} + +fn main() -> Result<()> { + // skip the starting arguments passed from the OS and/or cargo. + let mut args = + env::args().skip_while(|x| x == "cargo" || x == "stylus" || x.contains("cargo-stylus")); + + let Some(arg) = args.next() else { + exit_with_help_msg(); + }; + + // perform any builtins + match arg.as_str() { + "--help" | "-h" => exit_with_help_msg(), + "--version" | "-V" => exit_with_version(), + _ => {} + }; + + let Some(bin) = COMMANDS.iter().find(|x| x.apis.contains(&arg.as_str())) else { + // see if custom extension exists + let custom = format!("cargo-stylus-{arg}"); + if sys::command_exists(&custom) { + let err = sys::new_command(&custom).arg(arg).args(args).exec(); + bail!("failed to invoke {}: {err}", custom.red()); + } + + eprintln!("Unknown subcommand {}.", arg.red()); + eprintln!(); + exit_with_help_msg(); + }; + + let name = bin.name; + + // not all subcommands are shipped with `cargo-stylus`. + if !sys::command_exists(name) { + let flags = bin.rust_flags.map(|x| format!("{x} ")).unwrap_or_default(); + let install = format!(" {flags}cargo install --force {name}"); + + eprintln!("{} {}{}", "missing".grey(), name.red(), ".".grey()); + eprintln!(); + eprintln!("{}", "to install it, run".grey()); + eprintln!("{}", install.yellow()); + return Ok(()); + } + + // should never return + let err = sys::new_command(name).arg(arg).args(args).exec(); + bail!("failed to invoke {}: {err}", name.red()); +} diff --git a/replay/Cargo.toml b/replay/Cargo.toml new file mode 100644 index 0000000..63e2d16 --- /dev/null +++ b/replay/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "cargo-stylus-replay" +keywords = ["arbitrum", "ethereum", "stylus", "alloy", "gdb"] +description = "CLI tool for replaying Stylus transactions on Arbitrum chains" + +authors.workspace = true +edition.workspace = true +homepage.workspace = true +license.workspace = true +version.workspace = true +repository.workspace = true + +[dependencies] +alloy-primitives.workspace = true +cargo-stylus-util.workspace = true +clap.workspace = true +ethers.workspace = true +eyre.workspace = true +function_name.workspace = true +lazy_static.workspace = true +libc.workspace = true +libloading.workspace = true +parking_lot.workspace = true +rustc-host.workspace = true +sneks.workspace = true +tokio.workspace = true diff --git a/src/replay/hostio.rs b/replay/src/hostio.rs similarity index 97% rename from src/replay/hostio.rs rename to replay/src/hostio.rs index a048433..1674ee4 100644 --- a/src/replay/hostio.rs +++ b/replay/src/hostio.rs @@ -1,4 +1,4 @@ -// Copyright 2022-2023, Offchain Labs, Inc. +// Copyright 2022-2024, Offchain Labs, Inc. // For licensing, see https://github.com/OffchainLabs/stylus-sdk-rs/blob/stylus/licenses/COPYRIGHT.md #![allow(unused)] @@ -86,6 +86,20 @@ pub unsafe extern "C" fn storage_store_bytes32(key_ptr: *const u8, value_ptr: *c assert_eq!(read_fixed(value_ptr), value); } +#[named] +#[no_mangle] +pub unsafe extern "C" fn storage_cache_bytes32(key_ptr: *const u8, value_ptr: *const u8) { + frame!(StorageCacheBytes32 { key, value }); + assert_eq!(read_fixed(key_ptr), key); + assert_eq!(read_fixed(value_ptr), value); +} + +#[named] +#[no_mangle] +pub unsafe extern "C" fn storage_flush_cache(clear: u32) { + frame!(StorageFlushCache { clear }); +} + /// Gets the ETH balance in wei of the account at the given address. /// The semantics are equivalent to that of the EVM's [`BALANCE`] opcode. /// @@ -433,8 +447,8 @@ pub unsafe extern "C" fn evm_ink_left() -> u64 { /// Calls made voluntarily will unproductively consume gas. #[named] #[no_mangle] -pub unsafe extern "C" fn memory_grow(new_pages: u16) { - frame!(MemoryGrow { pages }); +pub unsafe extern "C" fn pay_for_memory_grow(new_pages: u16) { + frame!(PayForMemoryGrow { pages }); assert_eq!(new_pages, pages); } @@ -500,8 +514,8 @@ pub unsafe extern "C" fn read_return_data( size_value: usize, ) -> usize { frame!(ReadReturnData { offset, size, data }); - assert_eq!(offset_value, offset); - assert_eq!(size_value, size); + assert_eq!(offset_value, offset as usize); + assert_eq!(size_value, size as usize); copy!(data, dest, data.len()); data.len() } diff --git a/replay/src/main.rs b/replay/src/main.rs new file mode 100644 index 0000000..485d822 --- /dev/null +++ b/replay/src/main.rs @@ -0,0 +1,204 @@ +// Copyright 2023-2024, Offchain Labs, Inc. +// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/stylus/licenses/COPYRIGHT.md + +use crate::trace::Trace; +use alloy_primitives::TxHash; +use cargo_stylus_util::{color::Color, sys}; +use clap::{Args, Parser}; +use eyre::{bail, eyre, Context, Result}; +use std::{ + os::unix::process::CommandExt, + path::{Path, PathBuf}, +}; +use tokio::runtime::Builder; + +mod hostio; +mod trace; + +#[derive(Parser, Clone, Debug)] +#[command(name = "cargo-stylus-replay")] +#[command(bin_name = "cargo stylus replay")] +#[command(author = "Offchain Labs, Inc.")] +#[command(version = env!("CARGO_PKG_VERSION"))] +#[command(about = "Cargo command for replaying Arbitrum Stylus transactions", long_about = None)] +#[command(propagate_version = true)] +pub struct Opts { + #[command(subcommand)] + command: Subcommands, +} + +#[derive(Parser, Debug, Clone)] +enum Subcommands { + /// Replay a transaction in gdb. + #[command(alias = "r")] + Replay(ReplayArgs), + /// Trace a transaction. + #[command(alias = "t")] + Trace(TraceArgs), +} + +#[derive(Args, Clone, Debug)] +struct ReplayArgs { + /// RPC endpoint. + #[arg(short, long, default_value = "http://localhost:8547")] + endpoint: String, + /// Tx to replay. + #[arg(short, long)] + tx: TxHash, + /// Project path. + #[arg(short, long, default_value = ".")] + project: PathBuf, + /// Whether to use stable Rust. Note that nightly is needed to expand macros. + #[arg(short, long)] + stable_rust: bool, + /// Whether this process is the child of another. + #[arg(short, long, hide(true))] + child: bool, +} + +#[derive(Args, Clone, Debug)] +struct TraceArgs { + /// RPC endpoint. + #[arg(short, long, default_value = "http://localhost:8547")] + endpoint: String, + /// Tx to replay. + #[arg(short, long)] + tx: TxHash, + /// Project path. + #[arg(short, long, default_value = ".")] + project: PathBuf, +} + +fn main() -> Result<()> { + let args = Opts::parse(); + + // use the current thread for replay + let mut runtime = match args.command { + Subcommands::Trace(_) => Builder::new_multi_thread(), + Subcommands::Replay(_) => Builder::new_current_thread(), + }; + + let runtime = runtime.enable_all().build()?; + runtime.block_on(main_impl(args)) +} + +async fn main_impl(args: Opts) -> Result<()> { + macro_rules! run { + ($expr:expr, $($msg:expr),+) => { + $expr.await.wrap_err_with(|| eyre!($($msg),+)) + }; + } + + match args.command { + Subcommands::Trace(args) => run!(self::trace(args), "failed to trace tx"), + Subcommands::Replay(args) => run!(self::replay(args), "failed to replay tx"), + } +} + +async fn trace(args: TraceArgs) -> Result<()> { + let provider = sys::new_provider(&args.endpoint)?; + let trace = Trace::new(provider, args.tx).await?; + println!("{}", trace.json); + Ok(()) +} + +async fn replay(args: ReplayArgs) -> Result<()> { + if !args.child { + let rust_gdb = sys::command_exists("rust-gdb"); + if !rust_gdb { + println!( + "{} not installed, falling back to {}", + "rust-gdb".red(), + "gdb".red() + ); + } + + let mut cmd = match rust_gdb { + true => sys::new_command("rust-gdb"), + false => sys::new_command("gdb"), + }; + cmd.arg("--quiet"); + cmd.arg("-ex=set breakpoint pending on"); + cmd.arg("-ex=b user_entrypoint"); + cmd.arg("-ex=r"); + cmd.arg("--args"); + + for arg in std::env::args() { + cmd.arg(arg); + } + cmd.arg("--child"); + let err = cmd.exec(); + + bail!("failed to exec gdb {}", err); + } + + let provider = sys::new_provider(&args.endpoint)?; + let trace = Trace::new(provider, args.tx).await?; + + build_so(&args.project, args.stable_rust)?; + let so = find_so(&args.project)?; + + // TODO: don't assume the contract is top-level + let args_len = trace.tx.input.len(); + + unsafe { + *hostio::FRAME.lock() = Some(trace.reader()); + + type Entrypoint = unsafe extern "C" fn(usize) -> usize; + let lib = libloading::Library::new(so)?; + let main: libloading::Symbol = lib.get(b"user_entrypoint")?; + + match main(args_len) { + 0 => println!("call completed successfully"), + 1 => println!("call reverted"), + x => println!("call exited with unknown status code: {}", x.red()), + } + } + Ok(()) +} + +pub fn build_so(path: &Path, stable: bool) -> Result<()> { + let mut cargo = sys::new_command("cargo"); + + if !stable { + cargo.arg("+nightly"); + } + cargo + .current_dir(path) + .arg("build") + .arg("--lib") + .arg("--target") + .arg(rustc_host::from_cli()?) + .output()?; + Ok(()) +} + +pub fn find_so(project: &Path) -> Result { + let triple = rustc_host::from_cli()?; + let so_dir = project.join(format!("target/{triple}/debug/")); + let so_dir = std::fs::read_dir(&so_dir) + .map_err(|e| eyre!("failed to open {}: {e}", so_dir.to_string_lossy()))? + .filter_map(|r| r.ok()) + .map(|r| r.path()) + .filter(|r| r.is_file()); + + let mut file: Option = None; + for entry in so_dir { + let Some(ext) = entry.file_name() else { + continue; + }; + let ext = ext.to_string_lossy(); + + if ext.contains(".so") { + if let Some(other) = file { + let other = other.file_name().unwrap().to_string_lossy(); + bail!("more than one .so found: {ext} and {other}",); + } + file = Some(entry); + } + } + let Some(file) = file else { + bail!("failed to find .so"); + }; + Ok(file) +} diff --git a/src/replay/query.js b/replay/src/query.js similarity index 100% rename from src/replay/query.js rename to replay/src/query.js diff --git a/src/replay/trace.rs b/replay/src/trace.rs similarity index 95% rename from src/replay/trace.rs rename to replay/src/trace.rs index 90b23c5..b30c4de 100644 --- a/src/replay/trace.rs +++ b/replay/src/trace.rs @@ -3,8 +3,8 @@ #![allow(clippy::redundant_closure_call)] -use crate::color::{Color, DebugColor}; -use alloy_primitives::{Address, TxHash, B256, U256}; +use alloy_primitives::{Address, FixedBytes, TxHash, B256, U256}; +use cargo_stylus_util::color::{Color, DebugColor}; use ethers::{ providers::{JsonRpcClient, Middleware, Provider}, types::{ @@ -18,7 +18,7 @@ use std::{collections::VecDeque, mem}; #[derive(Debug)] pub struct Trace { - top_frame: TraceFrame, + pub top_frame: TraceFrame, pub receipt: TransactionReceipt, pub tx: Transaction, pub json: Value, @@ -236,6 +236,13 @@ impl TraceFrame { key: read_b256!(args), value: read_b256!(args), }, + "storage_cache_bytes32" => StorageCacheBytes32 { + key: read_b256!(args), + value: read_b256!(args), + }, + "storage_flush_cache" => StorageFlushCache { + clear: read_u8!(args), + }, "account_balance" => AccountBalance { address: read_address!(args), balance: read_u256!(outs), @@ -293,7 +300,7 @@ impl TraceFrame { "tx_origin" => TxOrigin { origin: read_address!(outs), }, - "memory_grow" => MemoryGrow { + "memory_grow" => PayForMemoryGrow { pages: read_u16!(args), }, "call_contract" => CallContract { @@ -339,8 +346,8 @@ impl TraceFrame { data: read_data!(args), }, "read_return_data" => ReadReturnData { - offset: read_usize!(args), - size: read_usize!(args), + offset: read_u32!(args), + size: read_u32!(args), data: read_data!(outs), }, "return_data_size" => ReturnDataSize { @@ -352,7 +359,7 @@ impl TraceFrame { "console_log" => ConsoleLog { text: read_string!(args), }, - x => todo!("Missing hostio {x}"), + x => todo!("Missing hostio details {x}"), }; assert!(args.is_empty(), "{name}"); @@ -397,6 +404,13 @@ pub enum HostioKind { key: B256, value: B256, }, + StorageCacheBytes32 { + key: FixedBytes<32>, + value: FixedBytes<32>, + }, + StorageFlushCache { + clear: u8, + }, AccountBalance { address: Address, balance: U256, @@ -432,7 +446,7 @@ pub enum HostioKind { EvmInkLeft { ink_left: u64, }, - MemoryGrow { + PayForMemoryGrow { pages: u16, }, MsgReentrant { @@ -506,8 +520,8 @@ pub enum HostioKind { topics: usize, }, ReadReturnData { - offset: usize, - size: usize, + offset: u32, + size: u32, data: Box<[u8]>, }, ReturnDataSize { diff --git a/src/check.rs b/src/check.rs deleted file mode 100644 index 9270e06..0000000 --- a/src/check.rs +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright 2023, Offchain Labs, Inc. -// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md - -use bytesize::ByteSize; -use ethers::prelude::*; -use ethers::utils::get_contract_address; -use ethers::{ - providers::JsonRpcClient, - types::{transaction::eip2718::TypedTransaction, Address}, -}; -use std::path::PathBuf; -use std::str::FromStr; - -use ethers::types::Eip1559TransactionRequest; -use ethers::{ - core::types::spoof, - providers::{Provider, RawCall}, -}; -use eyre::{bail, eyre}; - -use crate::constants::PROGRAM_UP_TO_DATE_ERR; -use crate::util; -use crate::{ - color::Color, - constants::ARB_WASM_ADDRESS, - deploy::activation_calldata, - project::{self, BuildConfig}, - wallet, CheckConfig, -}; - -/// Implements a custom wrapper for byte size that can be formatted with color -/// depending on the byte size. For example, file sizes that are greater than 24Kb -/// get formatted in pink as they are large, yellow for less than 24Kb, and mint for -/// WASMS less than 8Kb. -pub struct FileByteSize(ByteSize); - -impl FileByteSize { - fn new(len: u64) -> Self { - Self(ByteSize::b(len)) - } -} - -impl std::fmt::Display for FileByteSize { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self.0 { - n if n <= ByteSize::kb(16) => { - write!(f, "{}", n.mint()) - } - n if n > ByteSize::kb(16) && n <= ByteSize::kb(24) => { - write!(f, "{}", n.yellow()) - } - n => { - write!(f, "{}", n.pink()) - } - } - } -} - -/// Runs a series of checks on the WASM program to ensure it is valid for compilation -/// and code size before being deployed and activated onchain. An optional list of checks -/// to disable can be specified. Returns a boolean that says whether a WASM is already up-to-date -/// and activated onchain. -pub async fn run_checks(cfg: CheckConfig) -> eyre::Result { - let wasm_file_path: PathBuf = match &cfg.wasm_file_path { - Some(path) => PathBuf::from_str(path).unwrap(), - None => project::build_project_dylib(BuildConfig { - opt_level: project::OptLevel::default(), - nightly: cfg.nightly, - rebuild: true, - skip_contract_size_check: cfg.skip_contract_size_check, - }) - .map_err(|e| eyre!("failed to build project to WASM: {e}"))?, - }; - println!("Reading WASM file at {}", wasm_file_path.display().grey()); - - let (precompressed_bytes, init_code) = - project::compress_wasm(&wasm_file_path, cfg.skip_contract_size_check) - .map_err(|e| eyre!("failed to get compressed WASM bytes: {e}"))?; - - let precompressed_size = FileByteSize::new(precompressed_bytes.len() as u64); - println!("Uncompressed WASM size: {precompressed_size}"); - - let compressed_size = FileByteSize::new(init_code.len() as u64); - println!("Compressed WASM size to be deployed onchain: {compressed_size}",); - - println!( - "Connecting to Stylus RPC endpoint: {}", - &cfg.endpoint.mint() - ); - - let provider = util::new_provider(&cfg.endpoint)?; - - let mut expected_program_addr = cfg.clone().expected_program_address; - - // If there is no expected program address specified, compute it from the user's wallet. - if !expected_program_addr.is_zero() { - let wallet = wallet::load(&cfg)?; - let chain_id = provider - .get_chainid() - .await - .map_err(|e| eyre!("could not get chain id {e}"))? - .as_u64(); - let client = - SignerMiddleware::new(provider.clone(), wallet.clone().with_chain_id(chain_id)); - - let addr = wallet.address(); - let nonce = client - .get_transaction_count(addr, None) - .await - .map_err(|e| eyre!("could not get nonce {addr}: {e}"))?; - - expected_program_addr = get_contract_address(wallet.address(), nonce); - } - check_can_activate(provider, &expected_program_addr, init_code).await -} - -/// Checks if a program can be successfully activated onchain before it is deployed -/// by using an eth_call override that injects the program's code at a specified address. -/// This allows for verifying an activation call is correct and will succeed if sent -/// as a transaction with the appropriate gas. Returns a boolean that says whether or not the program's -/// code is up-to-date and activated onchain. -pub async fn check_can_activate( - client: Provider, - expected_program_address: &Address, - compressed_wasm: Vec, -) -> eyre::Result -where - T: JsonRpcClient, -{ - let calldata = activation_calldata(expected_program_address); - let to = hex::decode(ARB_WASM_ADDRESS).unwrap(); - let to = Address::from_slice(&to); - - let tx_request = Eip1559TransactionRequest::new().to(to).data(calldata); - let tx = TypedTransaction::Eip1559(tx_request); - - // Spoof the state as if the program already exists at the specified address - // using an eth_call override. - let state = spoof::code( - Address::from_slice(expected_program_address.as_bytes()), - compressed_wasm.into(), - ); - let (response, program_up_to_date) = match client.call_raw(&tx).state(&state).await { - Ok(response) => (response, false), - Err(e) => { - // TODO: Improve this check by instead calling ArbWasm to check if a program is up to date - // once the feature is available and exposed onchain. - if e.to_string().contains(PROGRAM_UP_TO_DATE_ERR) { - (Bytes::new(), true) - } else { - bail!( - "program predeployment check failed when checking against ARB_WASM_ADDRESS {ARB_WASM_ADDRESS}: {e}" - ); - } - } - }; - - if program_up_to_date { - let msg = "already activated"; - println!( - "Stylus program with same WASM code is {} onchain", - msg.mint() - ); - return Ok(true); - } - - if response.len() < 2 { - bail!( - "Stylus version bytes response too short, expected at least 2 bytes but got: {}", - hex::encode(&response) - ); - } - let n = response.len(); - let version_bytes: [u8; 2] = response[n - 2..] - .try_into() - .map_err(|e| eyre!("could not parse Stylus version bytes: {e}"))?; - let version = u16::from_be_bytes(version_bytes); - println!("Program succeeded Stylus onchain activation checks with Stylus version: {version}"); - Ok(false) -} diff --git a/src/constants.rs b/src/constants.rs deleted file mode 100644 index 6df02eb..0000000 --- a/src/constants.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2023, Offchain Labs, Inc. -// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md -use bytesize::ByteSize; - -/// EOF prefix used in Stylus compressed WASMs on-chain -pub const EOF_PREFIX: &str = "EFF000"; - -/// Maximum brotli compression level used for Stylus programs. -pub const BROTLI_COMPRESSION_LEVEL: u32 = 11; - -/// Address of the Arbitrum WASM precompile on L2. -pub const ARB_WASM_ADDRESS: &str = "0000000000000000000000000000000000000071"; - -/// Maximum allowed size of a program on Arbitrum (and Ethereum). -pub const MAX_PROGRAM_SIZE: ByteSize = ByteSize::kb(24); - -/// Maximum allowed size of a precompressed WASM program. -pub const MAX_PRECOMPRESSED_WASM_SIZE: ByteSize = ByteSize::kb(128); - -/// 4 bytes method selector for the activate method of ArbWasm. -pub const ARBWASM_ACTIVATE_METHOD_HASH: &str = "58c780c2"; - -/// Target for compiled WASM folder in a Rust project -pub const RUST_TARGET: &str = "wasm32-unknown-unknown"; - -/// The default repo to clone when creating new projects -pub const GITHUB_TEMPLATE_REPO: &str = "https://github.com/OffchainLabs/stylus-hello-world"; - -/// The minimal entrypoint repo -pub const GITHUB_TEMPLATE_REPO_MINIMAL: &str = - "https://github.com/OffchainLabs/stylus-hello-world-minimal"; - -/// The error returned from a call onchain if a program is up to date and requires no activation. -pub const PROGRAM_UP_TO_DATE_ERR: &str = "ProgramUpToDate"; diff --git a/src/deploy.rs b/src/deploy.rs deleted file mode 100644 index 9f68b63..0000000 --- a/src/deploy.rs +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright 2023, Offchain Labs, Inc. -// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md - -#![allow(clippy::println_empty_string)] - -use std::io::Write; -use std::path::{Path, PathBuf}; -use std::str::FromStr; - -use ethers::types::{Eip1559TransactionRequest, H160, U256}; -use ethers::utils::{format_ether, get_contract_address, to_checksum}; -use ethers::{middleware::SignerMiddleware, providers::Middleware, signers::Signer}; -use eyre::{bail, eyre}; - -use crate::project::BuildConfig; -use crate::util; -use crate::{check, color::Color, constants, project, tx, wallet, DeployConfig, DeployMode}; - -/// The transaction kind for using the Cargo stylus tool with Stylus programs. -/// Stylus programs can be deployed and activated onchain, and this enum represents -/// these two variants. -pub enum TxKind { - Deployment, - Activation, -} - -impl std::fmt::Display for TxKind { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match *self { - TxKind::Deployment => write!(f, "deployment"), - TxKind::Activation => write!(f, "activation"), - } - } -} - -/// Performs one of three different modes for a Stylus program: -/// DeployOnly: Sends a signed tx to deploy a Stylus program to a new address. -/// ActivateOnly: Sends a signed tx to activate a Stylus program at a specified address. -/// DeployAndActivate (default): Sends both transactions above. -pub async fn deploy(cfg: DeployConfig) -> eyre::Result<()> { - // Run stylus checks before deployment. - let program_is_up_to_date = check::run_checks(cfg.check_cfg.clone()) - .await - .map_err(|e| eyre!("Stylus checks failed: {e}"))?; - let wallet = wallet::load(&cfg.check_cfg).map_err(|e| eyre!("could not load wallet: {e}"))?; - - let provider = util::new_provider(&cfg.check_cfg.endpoint)?; - - let chain_id = provider - .get_chainid() - .await - .map_err(|e| eyre!("could not get chain id: {e}"))? - .as_u64(); - let client = SignerMiddleware::new(&provider, wallet.clone().with_chain_id(chain_id)); - - let addr = wallet.address(); - - println!("Deployer address: {}", to_checksum(&addr, None).grey(),); - - let nonce = client - .get_transaction_count(addr, None) - .await - .map_err(|e| eyre!("could not get nonce for address {addr}: {e}"))?; - - let expected_program_addr = get_contract_address(wallet.address(), nonce); - - let (deploy, activate) = match cfg.mode { - Some(DeployMode::DeployOnly) => (true, false), - Some(DeployMode::ActivateOnly) => (false, true), - // Default mode is to deploy and activate - None => { - if cfg.estimate_gas_only && cfg.activate_program_address.is_none() { - // cannot activate if not really deploying - println!( - r#"Only estimating gas for deployment tx. To estimate gas for activation, -run with --mode=activate-only and specify --activate-program-address. The program must have been deployed -already for estimating activation gas to work. To send individual txs for deployment and activation, see more -on the --mode flag under cargo stylus deploy --help"# - ); - (true, false) - } else { - (true, true) - } - } - }; - - // Whether to send the transactions to the endpoint. - let dry_run = cfg.tx_sending_opts.dry_run; - - // If we are attempting to send a real transaction, we check if the deployer has any funds - // and we return an error, letting the user know they need funds to send the tx and linking to - // our quickstart on ways to do so on testnet. - if !dry_run { - let balance = provider.get_balance(addr, None).await?; - if balance == U256::zero() { - bail!( - r#"address {} has 0 balance onchain – please refer to our Quickstart guide for deploying -programs to Stylus chains here https://docs.arbitrum.io/stylus/stylus-quickstart"#, - to_checksum(&addr, None), - ); - } - println!("Address has ETH Balance: {}", format_ether(balance).mint()); - } - - // The folder at which to output the transaction data bytes. - let output_dir = cfg.tx_sending_opts.output_tx_data_to_dir.as_ref(); - - if dry_run && output_dir.is_none() { - bail!( - "using the --dry-run flag requires specifying the --output-tx-data-to-dir flag as well" - ); - } - - if deploy { - let wasm_file_path: PathBuf = match &cfg.check_cfg.wasm_file_path { - Some(path) => PathBuf::from_str(path).unwrap(), - None => project::build_project_dylib(BuildConfig { - opt_level: project::OptLevel::default(), - nightly: cfg.check_cfg.nightly, - rebuild: false, // The check step at the start of this command rebuilt. - skip_contract_size_check: cfg.check_cfg.skip_contract_size_check, - }) - .map_err(|e| eyre!("could not build project to WASM: {e}"))?, - }; - let (_, init_code) = - project::compress_wasm(&wasm_file_path, cfg.check_cfg.skip_contract_size_check)?; - println!(""); - println!("{}", "====DEPLOYMENT====".grey()); - println!( - "Deploying program to address {}", - to_checksum(&expected_program_addr, None).mint(), - ); - let deployment_calldata = program_deployment_calldata(&init_code); - - // Output the tx data to a user's specified directory if desired. - if let Some(tx_data_output_dir) = output_dir { - write_tx_data(TxKind::Deployment, tx_data_output_dir, &deployment_calldata)?; - } - - if !dry_run { - let mut tx_request = Eip1559TransactionRequest::new() - .from(wallet.address()) - .data(deployment_calldata); - tx::submit_signed_tx( - &client, - TxKind::Deployment, - cfg.estimate_gas_only, - &mut tx_request, - ) - .await - .map_err(|e| eyre!("could not submit signed deployment tx: {e}"))?; - } - println!(""); - } - if activate { - // If program is up-to-date, there is no need for an activation transaction. - if program_is_up_to_date { - return Ok(()); - } - let program_addr = cfg - .activate_program_address - .unwrap_or(expected_program_addr); - println!("{}", "====ACTIVATION====".grey()); - println!( - "Activating program at address {}", - to_checksum(&program_addr, None).mint(), - ); - let activate_calldata = activation_calldata(&program_addr); - - let to = hex::decode(constants::ARB_WASM_ADDRESS).unwrap(); - let to = H160::from_slice(&to); - - // Output the tx data to a user's specified directory if desired. - if let Some(tx_data_output_dir) = output_dir { - write_tx_data(TxKind::Activation, tx_data_output_dir, &activate_calldata)?; - } - - if !dry_run { - let mut tx_request = Eip1559TransactionRequest::new() - .from(wallet.address()) - .to(to) - .data(activate_calldata); - tx::submit_signed_tx( - &client, - TxKind::Activation, - cfg.estimate_gas_only, - &mut tx_request, - ) - .await - .map_err(|e| eyre!("could not submit signed activation tx: {e}"))?; - } - println!(""); - } - Ok(()) -} - -pub fn activation_calldata(program_addr: &H160) -> Vec { - let mut activate_calldata = vec![]; - let activate_method_hash = hex::decode(constants::ARBWASM_ACTIVATE_METHOD_HASH).unwrap(); - activate_calldata.extend(activate_method_hash); - let mut extension = [0u8; 32]; - // Next, we add the address to the last 20 bytes of extension - extension[12..32].copy_from_slice(program_addr.as_bytes()); - activate_calldata.extend(extension); - activate_calldata -} - -/// Prepares an EVM bytecode prelude for contract creation. -pub fn program_deployment_calldata(code: &[u8]) -> Vec { - let mut code_len = [0u8; 32]; - U256::from(code.len()).to_big_endian(&mut code_len); - let mut deploy: Vec = vec![]; - deploy.push(0x7f); // PUSH32 - deploy.extend(code_len); - deploy.push(0x80); // DUP1 - deploy.push(0x60); // PUSH1 - deploy.push(0x2a); // 42 the prelude length - deploy.push(0x60); // PUSH1 - deploy.push(0x00); - deploy.push(0x39); // CODECOPY - deploy.push(0x60); // PUSH1 - deploy.push(0x00); - deploy.push(0xf3); // RETURN - deploy.extend(code); - deploy -} - -fn write_tx_data(tx_kind: TxKind, path: &Path, data: &[u8]) -> eyre::Result<()> { - let file_name = format!("{tx_kind}_tx_data"); - let path = path.join(file_name); - let path_str = path.as_os_str().to_string_lossy(); - println!( - "Writing {tx_kind} tx data bytes of size {} to path {}", - data.len().mint(), - path_str.grey(), - ); - let mut f = std::fs::File::create(&path) - .map_err(|e| eyre!("could not create file to write tx data to path {path_str}: {e}",))?; - f.write_all(data) - .map_err(|e| eyre!("could not write tx data as bytes to file to path {path_str}: {e}")) -} diff --git a/src/export_abi.rs b/src/export_abi.rs deleted file mode 100644 index 8f8111b..0000000 --- a/src/export_abi.rs +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2023, Offchain Labs, Inc. -// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md -use eyre::{bail, eyre, Result}; -use std::{ - fs::File, - path::PathBuf, - process::{Command, Stdio}, -}; - -/// Exports the Solidity ABI for a Stylus Rust program in the current directory to stdout. -pub fn export_solidity_abi(release: bool, output_file: Option) -> Result<()> { - let target_host = - rustc_host::from_cli().map_err(|e| eyre!("could not get host target architecture: {e}"))?; - let mut cmd = Command::new("cargo"); - - cmd.stderr(Stdio::inherit()) - .arg("run") - .arg("--features=export-abi") - .arg(format!("--target={}", target_host)); - - if release { - cmd.arg("--release"); - } - - match output_file.as_ref() { - Some(output_file_path) => { - let output_file = File::create(output_file_path).map_err(|e| { - eyre!( - "could not create output file to write ABI at path {}: {e}", - output_file_path.as_os_str().to_string_lossy() - ) - })?; - cmd.stdout(output_file); - } - None => { - cmd.stdout(Stdio::inherit()); - } - } - - let output = cmd - .output() - .map_err(|e| eyre!("failed to execute export abi command: {e}"))?; - if !output.status.success() { - bail!("Export ABI command failed: {:?}", output); - } - Ok(()) -} - -/// Exports the Solidity JSON ABI output from solc given a Stylus Rust project in the current directory. -/// The solc binary must be installed for this command to succeed. -pub fn export_json_abi(release: bool, output_file: Option) -> Result<()> { - // We first check if solc is installed. - let output = Command::new("solc") - .arg("--version") - .stderr(Stdio::null()) - .stdout(Stdio::null()) - .output() - .map_err(|e| eyre!("could not check solc version: {e}"))?; - if !output.status.success() { - bail!( - r#"The Solidity compiler's solc command failed, perhaps you do not have solc installed. -Please see https://docs.soliditylang.org/en/latest/installing-solidity.html on how to install it"#, - ); - } - - let target_host = - rustc_host::from_cli().map_err(|e| eyre!("could not get host target architecture: {e}"))?; - let mut exportcmd = Command::new("cargo"); - - // We spawn the export command as a child process so we can pipe its output later. - exportcmd - .stderr(Stdio::inherit()) - .arg("run") - .arg("--features=export-abi") - .stdout(Stdio::piped()) - .arg(format!("--target={}", target_host)); - - if release { - exportcmd.arg("--release"); - } - - let child_proc = exportcmd - .spawn() - .map_err(|e| eyre!("failed to execute export abi command: {e}"))?; - - let mut cmd = Command::new("solc"); - - cmd.stdin(Stdio::from(child_proc.stdout.unwrap())) - .stderr(Stdio::inherit()); - - match output_file.as_ref() { - Some(output_file_path) => { - let output_file = File::create(output_file_path).map_err(|e| { - eyre!( - "could not create output file to write ABI at path {}: {e}", - output_file_path.as_os_str().to_string_lossy() - ) - })?; - cmd.stdout(output_file); - } - None => { - cmd.stdout(Stdio::inherit()); - } - } - - let solcout = cmd - .arg("--abi") - .arg("-") - .output() - .map_err(|e| eyre!("failed to execute solc command: {e}"))?; - if !solcout.status.success() { - bail!("Export ABI JSON command using solc failed: {:?}", solcout); - } - Ok(()) -} diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index d92ea9c..0000000 --- a/src/main.rs +++ /dev/null @@ -1,265 +0,0 @@ -// Copyright 2023, Offchain Labs, Inc. -// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md - -use alloy_primitives::TxHash; -use clap::{Args, Parser, ValueEnum}; -use ethers::types::H160; -use eyre::{eyre, Context, Result}; -use std::path::PathBuf; -use tokio::runtime::Builder; - -mod c; -mod check; -mod color; -mod constants; -mod deploy; -mod export_abi; -mod new; -mod project; -mod replay; -mod tx; -mod util; -mod wallet; - -#[derive(Parser, Debug)] -#[command(name = "cargo")] -#[command(bin_name = "cargo")] -enum CargoCli { - Stylus(StylusArgs), - CGen(CGenArgs), // not behind the stylus command, to hide it from rust-developers. -} - -#[derive(Parser, Debug)] -#[command(name = "c_generate")] -struct CGenArgs { - #[arg(required = true)] - input: String, - out_dir: String, -} - -#[derive(Parser, Debug)] -#[command(name = "stylus")] -#[command(bin_name = "cargo stylus")] -#[command(author = "Offchain Labs, Inc.")] -#[command(version = "0.0.1")] -#[command(about = "Cargo command for developing Arbitrum Stylus projects", long_about = None)] -#[command(propagate_version = true)] -struct StylusArgs { - #[command(subcommand)] - command: Subcommands, -} - -#[derive(Parser, Debug, Clone)] -enum Subcommands { - /// Create a new Rust project. - New { - /// Project name. - #[arg(required = true)] - name: String, - /// Create a minimal program. - #[arg(long)] - minimal: bool, - }, - /// Export a Solidity ABI. - ExportAbi { - /// Build in release mode. - #[arg(long)] - release: bool, - /// The Output file (defaults to stdout). - #[arg(long)] - output: Option, - /// Output a JSON ABI instead using solc. Requires solc. - /// See https://docs.soliditylang.org/en/latest/installing-solidity.html - #[arg(long)] - json: bool, - }, - /// Check that a contract can be activated onchain. - #[command(alias = "c")] - Check(CheckConfig), - /// Deploy a stylus contract. - #[command(alias = "d")] - Deploy(DeployConfig), - /// Replay a transaction in gdb. - #[command(alias = "r")] - Replay(ReplayConfig), - /// Trace a transaction. - #[command(alias = "t")] - Trace(TraceConfig), -} - -#[derive(Args, Clone, Debug)] -pub struct CheckConfig { - /// RPC endpoint of the Stylus node to connect to. - #[arg(short, long, default_value = "https://stylus-testnet.arbitrum.io/rpc")] - endpoint: String, - /// Specifies a WASM file instead of looking for one in the current directory. - #[arg(long)] - wasm_file_path: Option, - /// Specify the program address we want to check activation for. If unspecified, it will - /// compute the next program address from the user's wallet address and nonce, which will require - /// wallet-related flags to be specified. - #[arg(long, default_value = "0x0000000000000000000000000000000000000000")] - expected_program_address: H160, - /// File path to a text file containing a private key. - #[arg(long)] - private_key_path: Option, - /// Private key 0x-prefixed hex string to use with the cargo stylus plugin. Warning: this exposes - /// your private key secret in plaintext in your CLI history. We instead recommend using the - /// --private-key-path flag or account keystore options. - #[arg(long)] - private_key: Option, - /// Wallet source to use with the cargo stylus plugin. - #[command(flatten)] - keystore_opts: KeystoreOpts, - /// Whether to use Rust nightly. - #[arg(long)] - nightly: bool, - /// Whether to skip the contract size check. In case the contract size is exceeded, a warning - /// will be emitted, but the overall cargo stylus check command will not fail. - #[arg(long)] - skip_contract_size_check: bool, -} - -#[derive(Args, Clone, Debug)] -pub struct DeployConfig { - #[command(flatten)] - check_cfg: CheckConfig, - /// Estimates deployment gas costs. - #[arg(long)] - estimate_gas_only: bool, - /// By default, submits two transactions to deploy and activate the program to Arbitrum. - /// Otherwise, a user could choose to split up the deploy and activate steps into individual transactions. - #[arg(long, value_enum)] - mode: Option, - /// If only activating an already-deployed, onchain program, the address of the program to send an activation tx for. - #[arg(long)] - activate_program_address: Option, - /// Configuration options for sending the deployment / activation txs through the Cargo stylus deploy command. - #[command(flatten)] - tx_sending_opts: TxSendingOpts, -} - -#[derive(Args, Clone, Debug)] -pub struct ReplayConfig { - /// RPC endpoint. - #[arg(short, long, default_value = "http://localhost:8545")] - endpoint: String, - /// Tx to replay. - #[arg(short, long)] - tx: TxHash, - /// Project path. - #[arg(short, long, default_value = ".")] - project: PathBuf, - /// Whether to use stable Rust. Note that nightly is needed to expand macros. - #[arg(short, long)] - stable_rust: bool, - /// Whether this process is the child of another. - #[arg(short, long, hide(true))] - child: bool, -} - -#[derive(Args, Clone, Debug)] -pub struct TraceConfig { - /// RPC endpoint. - #[arg(short, long, default_value = "http://localhost:8545")] - endpoint: String, - /// Tx to replay. - #[arg(short, long)] - tx: TxHash, - /// Project path. - #[arg(short, long, default_value = ".")] - project: PathBuf, -} - -#[derive(Debug, Clone, ValueEnum)] -pub enum DeployMode { - DeployOnly, - ActivateOnly, -} - -#[derive(Clone, Debug, Args)] -#[group(multiple = true)] -pub struct KeystoreOpts { - /// Path to an Ethereum wallet keystore file, such as the one produced by wallets such as clef. - #[arg(long)] - keystore_path: Option, - /// Path to a text file containing a password to the specified wallet keystore file. - #[arg(long)] - keystore_password_path: Option, -} - -#[derive(Clone, Debug, Args)] -pub struct TxSendingOpts { - /// Prepares transactions to send onchain for deploying and activating a Stylus program, - /// but does not send them. Instead, outputs the prepared tx data hex bytes to files in the directory - /// specified by the --output-tx-data-to-dir flag. Useful for sending the deployment / activation - /// txs via a user's preferred means instead of via the Cargo stylus tool. For example, Foundry's - /// https://book.getfoundry.sh/cast/ CLI tool. - #[arg(long)] - dry_run: bool, - /// Outputs the deployment / activation tx data as bytes to a specified directory. - #[arg(long)] - output_tx_data_to_dir: Option, -} - -fn main() -> Result<()> { - let args = match CargoCli::parse() { - CargoCli::Stylus(args) => args, - CargoCli::CGen(args) => { - return c::gen::c_gen(args.input, args.out_dir); - } - }; - - // use the current thread for replay - let mut runtime = match &args.command { - Subcommands::Replay(_) => Builder::new_current_thread(), - _ => Builder::new_multi_thread(), - }; - - let runtime = runtime.enable_all().build()?; - runtime.block_on(main_impl(args)) -} - -async fn main_impl(args: StylusArgs) -> Result<()> { - macro_rules! run { - ($expr:expr, $($msg:expr),+) => { - $expr.wrap_err_with(|| eyre!($($msg),+))? - }; - } - - match args.command { - Subcommands::New { name, minimal } => { - run!( - new::new_stylus_project(&name, minimal), - "failed to create project" - ); - } - Subcommands::ExportAbi { - release, - json, - output, - } => match json { - true => run!( - export_abi::export_json_abi(release, output), - "failed to export json" - ), - false => run!( - export_abi::export_solidity_abi(release, output), - "failed to export abi" - ), - }, - Subcommands::Check(config) => { - run!(check::run_checks(config).await, "stylus checks failed"); - } - Subcommands::Deploy(config) => { - run!(deploy::deploy(config).await, "failed to deploy"); - } - Subcommands::Replay(config) => { - run!(replay::replay(config).await, "failed to replay tx"); - } - Subcommands::Trace(config) => { - run!(replay::trace(config).await, "failed to trace"); - } - } - Ok(()) -} diff --git a/src/new.rs b/src/new.rs deleted file mode 100644 index 6c6148c..0000000 --- a/src/new.rs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2023, Offchain Labs, Inc. -// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md -use eyre::{bail, eyre}; -use std::{env::current_dir, path::PathBuf}; - -use crate::{ - color::Color, - constants::{GITHUB_TEMPLATE_REPO, GITHUB_TEMPLATE_REPO_MINIMAL}, - util, -}; - -/// Creates a new Stylus project in the current directory -pub fn new_stylus_project(name: &str, minimal: bool) -> eyre::Result<()> { - if name.is_empty() { - bail!("cannot have an empty project name"); - } - let cwd: PathBuf = current_dir().map_err(|e| eyre!("could not get current dir: {e}"))?; - - let repo = match minimal { - true => GITHUB_TEMPLATE_REPO_MINIMAL, - false => GITHUB_TEMPLATE_REPO, - }; - let output = util::new_command("git") - .arg("clone") - .arg(repo) - .arg(name) - .output() - .map_err(|e| eyre!("failed to execute git clone: {e}"))?; - - if !output.status.success() { - bail!("git clone command failed"); - } - let project_path = cwd.join(name); - println!( - "Initialized Stylus project at: {}", - project_path.as_os_str().to_string_lossy().mint() - ); - Ok(()) -} diff --git a/src/project.rs b/src/project.rs deleted file mode 100644 index 2188bf4..0000000 --- a/src/project.rs +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright 2023, Offchain Labs, Inc. -// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md - -use crate::constants::{MAX_PRECOMPRESSED_WASM_SIZE, MAX_PROGRAM_SIZE}; -use crate::util; -use crate::{ - color::Color, - constants::{BROTLI_COMPRESSION_LEVEL, EOF_PREFIX, RUST_TARGET}, -}; -use brotli2::read::BrotliEncoder; -use bytesize::ByteSize; -use eyre::{bail, eyre, Result}; -use std::{env::current_dir, io::Read, path::PathBuf}; - -#[derive(Default, PartialEq)] -pub enum OptLevel { - #[default] - S, - Z, -} - -pub struct BuildConfig { - pub opt_level: OptLevel, - pub nightly: bool, - pub rebuild: bool, - pub skip_contract_size_check: bool, -} - -#[derive(thiserror::Error, Debug, PartialEq, Eq, Clone)] -pub enum BuildError { - #[error("could not find WASM in release dir ({path}).")] - NoWasmFound { path: PathBuf }, - #[error( - r#"compressed program size ({got}) exceeds max ({want}) despite --nightly flag. We recommend splitting up your program."# - )] - ExceedsMaxDespiteBestEffort { got: ByteSize, want: ByteSize }, - #[error( - r#"Brotli-compressed WASM program size ({got}) is bigger than program size limit: ({want}). We recommend splitting up your program. -We are actively working to reduce WASM program sizes that use the Stylus SDK. -To see all available optimization options, see more in: -https://github.com/OffchainLabs/cargo-stylus/blob/main/OPTIMIZING_BINARIES.md"# - )] - MaxCompressedSizeExceeded { got: ByteSize, want: ByteSize }, - #[error( - r#"uncompressed WASM program size ({got}) is bigger than size limit: ({want}). We recommend splitting up your program. -We are actively working to reduce WASM program sizes that use the Stylus SDK. -To see all available optimization options, see more in: -https://github.com/OffchainLabs/cargo-stylus/blob/main/OPTIMIZING_BINARIES.md"#)] - MaxPrecompressedSizeExceeded { got: ByteSize, want: ByteSize }, -} - -/// Build a Rust project to WASM and return the path to the compiled WASM file. -pub fn build_project_dylib(cfg: BuildConfig) -> Result { - let cwd: PathBuf = current_dir().map_err(|e| eyre!("could not get current dir: {e}"))?; - - if cfg.rebuild { - let mut cmd = util::new_command("cargo"); - - if cfg.nightly { - cmd.arg("+nightly"); - let msg = "Warning:".yellow(); - println!("{msg} using Rust nightly. Make sure you are aware of the security risks."); - } - - cmd.arg("build"); - cmd.arg("--lib"); - - if cfg.nightly { - cmd.arg("-Z"); - cmd.arg("build-std=std,panic_abort"); - cmd.arg("-Z"); - cmd.arg("build-std-features=panic_immediate_abort"); - } - - if cfg.opt_level == OptLevel::Z { - cmd.arg("--config"); - cmd.arg("profile.release.opt-level='z'"); - } - - let output = cmd - .arg("--release") - .arg(format!("--target={RUST_TARGET}")) - .output() - .map_err(|e| eyre!("failed to execute cargo build: {e}"))?; - - if !output.status.success() { - bail!("cargo build command failed"); - } - } - - let release_path = cwd - .join("target") - .join(RUST_TARGET) - .join("release") - .join("deps"); - - // Gets the files in the release folder. - let release_files: Vec = std::fs::read_dir(&release_path) - .map_err(|e| eyre!("could not read deps dir: {e}"))? - .filter_map(|r| r.ok()) - .map(|r| r.path()) - .filter(|r| r.is_file()) - .collect(); - - let wasm_file_path = release_files - .into_iter() - .find(|p| { - if let Some(ext) = p.file_name() { - return ext.to_string_lossy().contains(".wasm"); - } - false - }) - .ok_or(BuildError::NoWasmFound { path: release_path })?; - - if let Err(e) = compress_wasm(&wasm_file_path, cfg.skip_contract_size_check) { - if let Some(BuildError::MaxCompressedSizeExceeded { got, .. }) = e.downcast_ref() { - match cfg.opt_level { - OptLevel::S => { - println!( - r#"Compressed program built with defaults had program size {} > max of 24Kb, -rebuilding with optimizations. We are actively working to reduce WASM program sizes that are -using the Stylus SDK. To see all available optimization options, see more in: -https://github.com/OffchainLabs/cargo-stylus/blob/main/OPTIMIZING_BINARIES.md"#, - got.red(), - ); - // Attempt to build again with a bumped-up optimization level. - return build_project_dylib(BuildConfig { - opt_level: OptLevel::Z, - nightly: cfg.nightly, - rebuild: true, - skip_contract_size_check: cfg.skip_contract_size_check, - }); - } - OptLevel::Z => { - if !cfg.nightly { - println!( - r#"Program still exceeds max program size {} > max of 24Kb"#, - got.red(), - ); - // Attempt to build again with the nightly flag enabled and extra optimizations - // only available with nightly compilation. - return build_project_dylib(BuildConfig { - opt_level: OptLevel::Z, - nightly: true, - rebuild: true, - skip_contract_size_check: cfg.skip_contract_size_check, - }); - } - return Err(BuildError::ExceedsMaxDespiteBestEffort { - got: *got, - want: MAX_PROGRAM_SIZE, - } - .into()); - } - } - } - return Err(e); - } - Ok(wasm_file_path) -} - -/// Reads a WASM file at a specified path and returns its brotli compressed bytes. -pub fn compress_wasm(wasm_path: &PathBuf, skip_size_check: bool) -> Result<(Vec, Vec)> { - let wasm_file_bytes = std::fs::read(wasm_path).map_err(|e| { - eyre!( - "could not read WASM file at target path {}: {e}", - wasm_path.as_os_str().to_string_lossy(), - ) - })?; - - let wasm_bytes = wasmer::wat2wasm(&wasm_file_bytes) - .map_err(|e| eyre!("could not parse wasm file bytes: {e}"))?; - - let mut compressor = BrotliEncoder::new(&*wasm_bytes, BROTLI_COMPRESSION_LEVEL); - let mut compressed_bytes = vec![]; - compressor - .read_to_end(&mut compressed_bytes) - .map_err(|e| eyre!("could not Brotli compress WASM bytes: {e}"))?; - - let mut deploy_ready_code = hex::decode(EOF_PREFIX).unwrap(); - deploy_ready_code.extend(compressed_bytes); - - if skip_size_check { - return Ok((wasm_bytes.to_vec(), deploy_ready_code)); - } - - let precompressed_size = ByteSize::b(wasm_bytes.len() as u64); - if precompressed_size > MAX_PRECOMPRESSED_WASM_SIZE { - return Err(BuildError::MaxPrecompressedSizeExceeded { - got: precompressed_size, - want: MAX_PRECOMPRESSED_WASM_SIZE, - } - .into()); - } - - let compressed_size = ByteSize::b(deploy_ready_code.len() as u64); - if compressed_size > MAX_PROGRAM_SIZE { - return Err(BuildError::MaxCompressedSizeExceeded { - got: compressed_size, - want: MAX_PROGRAM_SIZE, - } - .into()); - } - Ok((wasm_bytes.to_vec(), deploy_ready_code)) -} diff --git a/src/replay/mod.rs b/src/replay/mod.rs deleted file mode 100644 index b58de3f..0000000 --- a/src/replay/mod.rs +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2023, Offchain Labs, Inc. -// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/stylus/licenses/COPYRIGHT.md - -use crate::{color::Color, util, ReplayConfig, TraceConfig}; -use eyre::{bail, eyre, Result}; -use std::{ - os::unix::process::CommandExt, - path::{Path, PathBuf}, -}; - -use trace::Trace; - -mod hostio; -mod trace; - -pub async fn replay(config: ReplayConfig) -> Result<()> { - if !config.child { - let rust_gdb = util::command_exists("rust-gdb"); - if !rust_gdb { - println!( - "{} not installed, falling back to {}", - "rust-gdb".red(), - "gdb".red() - ); - } - - let mut cmd = match rust_gdb { - true => util::new_command("rust-gdb"), - false => util::new_command("gdb"), - }; - cmd.arg("--quiet"); - cmd.arg("-ex=set breakpoint pending on"); - cmd.arg("-ex=b user_entrypoint"); - cmd.arg("-ex=r"); - cmd.arg("--args"); - - for arg in std::env::args() { - cmd.arg(arg); - } - cmd.arg("--child"); - let err = cmd.exec(); - - bail!("failed to exec gdb {}", err); - } - - let provider = util::new_provider(&config.endpoint)?; - let trace = Trace::new(provider, config.tx).await?; - - build_so(&config.project, config.stable_rust)?; - let so = find_so(&config.project)?; - - // TODO: don't assume the contract is top-level - let args_len = trace.tx.input.len(); - - unsafe { - *hostio::FRAME.lock() = Some(trace.reader()); - - type Entrypoint = unsafe extern "C" fn(usize) -> usize; - let lib = libloading::Library::new(so)?; - let main: libloading::Symbol = lib.get(b"user_entrypoint")?; - - match main(args_len) { - 0 => println!("call completed successfully"), - 1 => println!("call reverted"), - x => println!("call exited with unknown status code: {}", x.red()), - } - } - Ok(()) -} - -pub async fn trace(config: TraceConfig) -> Result<()> { - let provider = util::new_provider(&config.endpoint)?; - let trace = Trace::new(provider, config.tx).await?; - println!("{}", trace.json); - Ok(()) -} - -pub fn build_so(path: &Path, stable: bool) -> Result<()> { - let mut cargo = util::new_command("cargo"); - - if !stable { - cargo.arg("+nightly"); - } - cargo - .current_dir(path) - .arg("build") - .arg("--lib") - .arg("--target") - .arg(rustc_host::from_cli()?) - .output()?; - Ok(()) -} - -pub fn find_so(project: &Path) -> Result { - let triple = rustc_host::from_cli()?; - let so_dir = project.join(format!("target/{triple}/debug/")); - let so_dir = std::fs::read_dir(&so_dir) - .map_err(|e| eyre!("failed to open {}: {e}", so_dir.to_string_lossy()))? - .filter_map(|r| r.ok()) - .map(|r| r.path()) - .filter(|r| r.is_file()); - - let mut file: Option = None; - for entry in so_dir { - let Some(ext) = entry.file_name() else { - continue; - }; - let ext = ext.to_string_lossy(); - - if ext.contains(".so") { - if let Some(other) = file { - let other = other.file_name().unwrap().to_string_lossy(); - bail!("more than one .so found: {ext} and {other}",); - } - file = Some(entry); - } - } - let Some(file) = file else { - bail!("failed to find .so"); - }; - Ok(file) -} diff --git a/src/tx.rs b/src/tx.rs deleted file mode 100644 index cda2fe6..0000000 --- a/src/tx.rs +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright 2023, Offchain Labs, Inc. -// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md -#![allow(clippy::println_empty_string)] - -use crate::color::Color; -use crate::deploy::TxKind; - -use ethers::types::transaction::eip2718::TypedTransaction; -use ethers::types::{Eip1559TransactionRequest, H256, U256}; -use ethers::utils::{format_ether, format_units}; -use ethers::{middleware::SignerMiddleware, providers::Middleware, signers::Signer}; -use eyre::eyre; - -#[derive(thiserror::Error, Debug, PartialEq, Eq, Clone)] -pub enum TxError { - #[error("no head block found")] - NoHeadBlock, - #[error("no base fee found for block")] - NoBaseFee, - #[error("no receipt found for tx hash ({tx_hash})")] - NoReceiptFound { tx_hash: H256 }, - #[error("({tx_kind}) got reverted with hash ({tx_hash})")] - Reverted { tx_kind: String, tx_hash: H256 }, -} - -/// Submits a tx to a client given a data payload and a -/// transaction request to sign and send. If estimate_only is true, only a call to -/// estimate gas will occur and the actual tx will not be submitted. -pub async fn submit_signed_tx( - client: &SignerMiddleware, - tx_kind: TxKind, - estimate_only: bool, - tx_request: &mut Eip1559TransactionRequest, -) -> eyre::Result<()> -where - M: Middleware, - S: Signer, -{ - let block_num = client - .get_block_number() - .await - .map_err(|e| eyre!("could not get block number: {e}"))?; - let block = client - .get_block(block_num) - .await - .map_err(|e| eyre!("could not get block: {e}"))? - .ok_or(TxError::NoHeadBlock)?; - let base_fee = block.base_fee_per_gas.ok_or(TxError::NoBaseFee)?; - - let base_fee_gwei = format_units(base_fee, "gwei") - .map_err(|e| eyre!("could not format base fee as gwei: {e}"))?; - println!("Base fee: {} gwei", base_fee_gwei.grey()); - if !estimate_only { - tx_request.max_fee_per_gas = Some(base_fee); - tx_request.max_priority_fee_per_gas = Some(base_fee); - } - - let address = &tx_request - .from - .ok_or(eyre!("no sender address specified for tx"))?; - let balance = client - .get_balance(*address, None) - .await - .map_err(|e| eyre!("could not get sender balance: {e}"))?; - - let typed = TypedTransaction::Eip1559(tx_request.clone()); - let estimated = client.estimate_gas(&typed, None).await.map_err(|e| { - if e.to_string().contains("gas required exceeds allowance") { - return eyre!( - "not enough funds to transact, only had ETH balance of {}", - format_ether(balance) - ); - } - eyre!("could not estimate gas: {e}") - })?; - - let estimate_gas_price = client - .get_gas_price() - .await - .map_err(|e| eyre!("could not estimate gas price for tx: {e}"))?; - - let total_estimated_cost = estimated - .checked_mul(estimate_gas_price) - .ok_or(eyre!("could not multiply estimated gas cost by gas price"))?; - - let estimate_gas_price = format_units(estimate_gas_price, "gwei") - .map_err(|e| eyre!("could not format gas price to gwei: {e}"))?; - - println!( - "Estimations for {tx_kind}: gas price (gwei): {}, gas units: {}, total ETH cost: {}", - estimate_gas_price.mint(), - estimated.mint(), - format_ether(total_estimated_cost).mint(), - ); - - if estimate_only { - return Ok(()); - } - - println!("Submitting {tx_kind} tx..."); - - let pending_tx = client - .send_transaction(typed, None) - .await - .map_err(|e| eyre!("could not send tx: {e}"))?; - - let tx_hash = pending_tx.tx_hash(); - - let receipt = pending_tx - .await - .map_err(|e| eyre!("could not get receipt: {e}"))? - .ok_or(TxError::NoReceiptFound { tx_hash })?; - - match receipt.status { - None => Err(TxError::Reverted { - tx_hash, - tx_kind: tx_kind.to_string(), - } - .into()), - Some(_) => { - let tx_hash = receipt.transaction_hash; - let gas_used = receipt.gas_used.unwrap(); - let effective_price = receipt.effective_gas_price.unwrap_or(U256::zero()); - let effective_price_gwei = format_units(effective_price, "gwei") - .map_err(|e| eyre!("could not format effective gas price: {e}"))?; - println!( - "Confirmed {tx_kind} tx {}{}", - "0x".mint(), - hex::encode(tx_hash.as_bytes()).mint(), - ); - println!( - "Gas units used {}, effective gas price {} gwei", - gas_used.mint(), - effective_price_gwei.grey(), - ); - println!( - "Transaction fee: {} ETH", - format_ether(gas_used * effective_price).mint() - ); - Ok(()) - } - } -} diff --git a/src/wallet.rs b/src/wallet.rs deleted file mode 100644 index 47742ca..0000000 --- a/src/wallet.rs +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2023, Offchain Labs, Inc. -// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md -use std::io::{BufRead, BufReader}; -use std::str::FromStr; - -use ethers::signers::LocalWallet; -use eyre::{bail, eyre}; - -use crate::CheckConfig; - -/// Loads a wallet for signing transactions either from a private key file path. -/// or a keystore along with a keystore password file. -pub fn load(cfg: &CheckConfig) -> eyre::Result { - let CheckConfig { - private_key_path, - keystore_opts, - private_key, - .. - } = cfg; - if private_key.is_some() && private_key_path.is_some() { - bail!("cannot provide both --private-key and --private-key-path"); - } - let priv_key_flag_set = private_key.is_some() || private_key_path.is_some(); - if priv_key_flag_set - && (keystore_opts.keystore_password_path.is_some() && keystore_opts.keystore_path.is_some()) - { - bail!("must provide either (--private-key-path or --private-key) or (--keystore-path and --keystore-password-path)"); - } - - match (private_key.as_ref(), private_key_path.as_ref()) { - (Some(privkey), None) => { - return LocalWallet::from_str(privkey) - .map_err(|e| eyre!("could not parse private key: {e}")); - } - (None, Some(priv_key_path)) => { - let privkey = read_secret_from_file(priv_key_path)?; - return LocalWallet::from_str(&privkey) - .map_err(|e| eyre!("could not parse private key: {e}")); - } - (None, None) => {} - _ => unreachable!(), - } - let keystore_password_path = keystore_opts - .keystore_password_path - .as_ref() - .ok_or(eyre!("no keystore password path provided"))?; - let keystore_pass = read_secret_from_file(keystore_password_path)?; - let keystore_path = keystore_opts - .keystore_path - .as_ref() - .ok_or(eyre!("no keystore path provided"))?; - LocalWallet::decrypt_keystore(keystore_path, keystore_pass) - .map_err(|e| eyre!("could not decrypt keystore: {e}")) -} - -fn read_secret_from_file(fpath: &str) -> eyre::Result { - let f = std::fs::File::open(fpath) - .map_err(|e| eyre!("could not open file at path: {fpath}: {e}"))?; - let mut buf_reader = BufReader::new(f); - let mut secret = String::new(); - buf_reader - .read_line(&mut secret) - .map_err(|e| eyre!("could not read secret from file at path {fpath}: {e}"))?; - Ok(secret.trim().to_string()) -} diff --git a/util/Cargo.toml b/util/Cargo.toml new file mode 100644 index 0000000..056b79f --- /dev/null +++ b/util/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "cargo-stylus-util" +keywords = ["arbitrum", "ethereum", "stylus", "alloy", "cargo"] +description = "utilities for cargo stylus and its dependencies" + +authors.workspace = true +edition.workspace = true +homepage.workspace = true +license.workspace = true +version.workspace = true +repository.workspace = true + +[dependencies] +hex.workspace = true +ethers.workspace = true +eyre.workspace = true +rustc-host.workspace = true diff --git a/src/color.rs b/util/src/color.rs similarity index 51% rename from src/color.rs rename to util/src/color.rs index fbea053..06ffd80 100644 --- a/src/color.rs +++ b/util/src/color.rs @@ -1,5 +1,6 @@ -// Copyright 2020-2023, Offchain Labs, Inc. +// Copyright 2020-2024, Offchain Labs, Inc. // For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md + #![allow(dead_code)] use std::fmt::{Debug, Display}; @@ -13,6 +14,7 @@ pub const RED: &str = "\x1b[31;1m"; pub const CLEAR: &str = "\x1b[0;0m"; pub const WHITE: &str = "\x1b[0;1m"; pub const YELLOW: &str = "\x1b[33;1m"; +pub const LAVENDER: &str = "\x1b[38;5;183;1m"; pub trait Color { fn color(&self, color: &str) -> String; @@ -26,24 +28,26 @@ pub trait Color { fn red(&self) -> String; fn white(&self) -> String; fn yellow(&self) -> String; + fn lavender(&self) -> String; } #[rustfmt::skip] impl Color for T where T: Display { fn color(&self, color: &str) -> String { - format!("{}{}{}", color, self, CLEAR) + format!("{color}{}{CLEAR}", self) } - fn blue(&self) -> String { self.color(BLUE) } - fn dim(&self) -> String { self.color(DIM) } - fn clear(&self) -> String { self.color(CLEAR) } - fn grey(&self) -> String { self.color(GREY) } - fn mint(&self) -> String { self.color(MINT) } - fn pink(&self) -> String { self.color(PINK) } - fn red(&self) -> String { self.color(RED) } - fn white(&self) -> String { self.color(WHITE) } - fn yellow(&self) -> String { self.color(YELLOW) } + fn blue(&self) -> String { self.color(BLUE) } + fn dim(&self) -> String { self.color(DIM) } + fn clear(&self) -> String { self.color(CLEAR) } + fn grey(&self) -> String { self.color(GREY) } + fn mint(&self) -> String { self.color(MINT) } + fn pink(&self) -> String { self.color(PINK) } + fn red(&self) -> String { self.color(RED) } + fn white(&self) -> String { self.color(WHITE) } + fn yellow(&self) -> String { self.color(YELLOW) } + fn lavender(&self) -> String { self.color(LAVENDER) } } pub fn when(cond: bool, text: T, when_color: &str) -> String { @@ -65,22 +69,24 @@ pub trait DebugColor { fn debug_red(&self) -> String; fn debug_white(&self) -> String; fn debug_yellow(&self) -> String; + fn debug_lavender(&self) -> String; } #[rustfmt::skip] impl DebugColor for T where T: Debug { fn debug_color(&self, color: &str) -> String { - format!("{}{:?}{}", color, self, CLEAR) + format!("{color}{:?}{CLEAR}", self) } - fn debug_blue(&self) -> String { self.debug_color(BLUE) } - fn debug_dim(&self) -> String { self.debug_color(DIM) } - fn debug_clear(&self) -> String { self.debug_color(CLEAR) } - fn debug_grey(&self) -> String { self.debug_color(GREY) } - fn debug_mint(&self) -> String { self.debug_color(MINT) } - fn debug_pink(&self) -> String { self.debug_color(PINK) } - fn debug_red(&self) -> String { self.debug_color(RED) } - fn debug_white(&self) -> String { self.debug_color(WHITE) } - fn debug_yellow(&self) -> String { self.debug_color(YELLOW) } + fn debug_blue(&self) -> String { self.debug_color(BLUE) } + fn debug_dim(&self) -> String { self.debug_color(DIM) } + fn debug_clear(&self) -> String { self.debug_color(CLEAR) } + fn debug_grey(&self) -> String { self.debug_color(GREY) } + fn debug_mint(&self) -> String { self.debug_color(MINT) } + fn debug_pink(&self) -> String { self.debug_color(PINK) } + fn debug_red(&self) -> String { self.debug_color(RED) } + fn debug_white(&self) -> String { self.debug_color(WHITE) } + fn debug_yellow(&self) -> String { self.debug_color(YELLOW) } + fn debug_lavender(&self) -> String { self.debug_color(LAVENDER) } } diff --git a/src/c/mod.rs b/util/src/lib.rs similarity index 55% rename from src/c/mod.rs rename to util/src/lib.rs index dd261c3..523e2f6 100644 --- a/src/c/mod.rs +++ b/util/src/lib.rs @@ -1,4 +1,6 @@ -// Copyright 2023, Offchain Labs, Inc. +// Copyright 2024, Offchain Labs, Inc. // For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md -pub mod gen; +pub mod color; +pub mod sys; +pub mod text; diff --git a/src/util.rs b/util/src/sys.rs similarity index 58% rename from src/util.rs rename to util/src/sys.rs index a3acb03..d6421ee 100644 --- a/src/util.rs +++ b/util/src/sys.rs @@ -1,19 +1,19 @@ -// Copyright 2023, Offchain Labs, Inc. +// Copyright 2023-2024, Offchain Labs, Inc. // For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md +use ethers::{prelude::*, providers::Provider}; +use eyre::{Context, Result}; use std::{ ffi::OsStr, + fs::File, + io::{self, Write}, + path::PathBuf, process::{Command, Stdio}, time::Duration, }; -use ethers::{prelude::*, providers::Provider}; -use eyre::{eyre, Context, Result}; - pub fn new_provider(url: &str) -> Result> { - let mut provider = - Provider::::try_from(url).wrap_err_with(|| eyre!("failed to init http provider"))?; - + let mut provider = Provider::::try_from(url).wrap_err("failed to init http provider")?; provider.set_interval(Duration::from_millis(250)); Ok(provider) } @@ -33,3 +33,15 @@ pub fn command_exists>(program: S) -> bool { .map(|x| x.status.success()) .unwrap_or_default() } + +pub fn host_arch() -> Result { + rustc_host::from_cli().wrap_err_with(|| "failed to get host arch") +} + +/// Opens a file for writing, or stdout. +pub fn file_or_stdout(path: Option) -> Result> { + Ok(match path { + Some(file) => Box::new(File::create(file)?), + None => Box::new(io::stdout().lock()), + }) +} diff --git a/util/src/text.rs b/util/src/text.rs new file mode 100644 index 0000000..c4dd11c --- /dev/null +++ b/util/src/text.rs @@ -0,0 +1,10 @@ +// Copyright 2024, Offchain Labs, Inc. +// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md + +use eyre::Result; + +pub fn decode0x>(text: T) -> Result> { + let text = text.as_ref(); + let text = text.strip_prefix("0x").unwrap_or(text); + Ok(hex::decode(text)?) +} From df28337c422787652dbab2b05e69ce6a787ddd4e Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Mon, 3 Jun 2024 12:14:41 -0500 Subject: [PATCH 08/35] bump versions (#39) --- Cargo.lock | 12 ++++++------ Cargo.toml | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c6a17c5..28373f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -634,7 +634,7 @@ dependencies = [ [[package]] name = "cargo-stylus" -version = "0.2.1" +version = "0.3.1" dependencies = [ "cargo-stylus-util", "clap", @@ -643,7 +643,7 @@ dependencies = [ [[package]] name = "cargo-stylus-cgen" -version = "0.2.1" +version = "0.3.1" dependencies = [ "alloy-json-abi", "clap", @@ -654,7 +654,7 @@ dependencies = [ [[package]] name = "cargo-stylus-check" -version = "0.2.1" +version = "0.3.1" dependencies = [ "alloy-ethers-typecast", "alloy-json-abi", @@ -680,14 +680,14 @@ dependencies = [ [[package]] name = "cargo-stylus-example" -version = "0.2.1" +version = "0.3.1" dependencies = [ "clap", ] [[package]] name = "cargo-stylus-replay" -version = "0.2.1" +version = "0.3.1" dependencies = [ "alloy-primitives 0.7.2", "cargo-stylus-util", @@ -706,7 +706,7 @@ dependencies = [ [[package]] name = "cargo-stylus-util" -version = "0.2.1" +version = "0.3.1" dependencies = [ "ethers", "eyre", diff --git a/Cargo.toml b/Cargo.toml index ab9efed..122c4d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ resolver = "2" [workspace.package] authors = ["Offchain Labs"] -version = "0.2.1" +version = "0.3.1" edition = "2021" homepage = "https://arbitrum.io" license = "MIT OR Apache-2.0" @@ -34,4 +34,4 @@ parking_lot = "0.12.1" sneks = "0.1.2" # members -cargo-stylus-util = { path = "util", version = "0.2.1" } +cargo-stylus-util = { path = "util", version = "0.3.1" } From b69c2c434eb8cdb5b16e1e2b6af1b00685475d63 Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Mon, 3 Jun 2024 12:24:38 -0500 Subject: [PATCH 09/35] cgen info (#40) --- cgen/Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cgen/Cargo.toml b/cgen/Cargo.toml index 5e47211..050f3b8 100644 --- a/cgen/Cargo.toml +++ b/cgen/Cargo.toml @@ -1,5 +1,8 @@ [package] name = "cargo-stylus-cgen" +keywords = ["arbitrum", "ethereum", "stylus", "alloy", "gdb"] +description = "CLI tool generating C bindings for Arbitrum Stylus ABIs" + authors.workspace = true version.workspace = true edition.workspace = true From 663616c7504d54499d289d6429469e599742567a Mon Sep 17 00:00:00 2001 From: Chris Buckland Date: Tue, 4 Jun 2024 15:30:49 +0100 Subject: [PATCH 10/35] Updated wat example (#41) * Updated wat example * Updated another reference to wasm-file-path --- README.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 09525bb..970a82c 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,7 @@ See `--help` for all available flags and default values. ## Deploying Non-Rust WASM Projects -The Stylus tool can also be used to deploy non-Rust, WASM projects to Stylus by specifying the WASM file directly with the `--wasm-file-path` flag to any of the cargo stylus commands. +The Stylus tool can also be used to deploy non-Rust, WASM projects to Stylus by specifying the WASM file directly with the `--wasm-file` flag to any of the cargo stylus commands. Even WebAssembly Text [(WAT)](https://www.webassemblyman.com/wat_webassembly_text_format.html) files are supported. This means projects that are just individual WASM files can be deployed onchain without needing to have been compiled by Rust. WASMs produced by other languages, such as C, can be used with the tool this way. @@ -164,14 +164,19 @@ For example: ```js (module + (memory 0 0) + (export "memory" (memory 0)) (type $t0 (func (param i32) (result i32))) (func $add_one (export "add_one") (type $t0) (param $p0 i32) (result i32) - get_local $p0 + local.get $p0 i32.const 1 - i32.add)) + i32.add) + (func (export "user_entrypoint") (param $args_len i32) (result i32) + (i32.const 0) + )) ``` -can be saved as `add.wat` and used as `cargo stylus check --wasm-file-path=add.wat` or `cargo stylus deploy --wasm-file-path=add.wat`. +can be saved as `add.wat` and used as `cargo stylus check --wasm-file=add.wat` or `cargo stylus deploy --wasm-file=add.wat`. ## Exporting Solidity ABIs From 95ff2723159005b3afe645e28a048759d4a363d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20FP?= <105675159+TucksonDev@users.noreply.github.com> Date: Thu, 6 Jun 2024 17:47:24 +0100 Subject: [PATCH 11/35] Fix links in README.md (#42) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 970a82c..7e0e7b1 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ Location: prover/src/binary.rs:493:9, data: None) ``` -To read more about what counts as valid vs. invalid user WASM programs, see [VALID_WASM](./VALID_WASM.md). +To read more about what counts as valid vs. invalid user WASM programs, see [VALID_WASM](./check/VALID_WASM.md). If your program succeeds, you'll see the following message: @@ -192,7 +192,7 @@ Brotli-compressed, Stylus program WASM binaries must fit within the **24Kb** [co We recommend optimizing your Stylus program's sizes to smaller sizes, but keep in mind the safety tradeoffs of using some of the more advanced optimizations. However, some small programs when compiled to much smaller sizes can suffer performance penalties. -For a deep-dive into the different options for optimizing binary sizes using cargo stylus, see [OPTIMIZING_BINARIES.md](./OPTIMIZING_BINARIES.md). +For a deep-dive into the different options for optimizing binary sizes using cargo stylus, see [OPTIMIZING_BINARIES.md](./check/OPTIMIZING_BINARIES.md). ## License From 729c18c6ec782aae60a88ac6c390905bd05c1ef2 Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Fri, 14 Jun 2024 07:40:09 -0500 Subject: [PATCH 12/35] trace err (#44) --- Cargo.lock | 9 +++++---- replay/Cargo.toml | 1 + replay/src/trace.rs | 19 ++++++++++++++++++- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 28373f4..6bfee2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -700,6 +700,7 @@ dependencies = [ "libloading", "parking_lot", "rustc-host", + "serde", "sneks", "tokio", ] @@ -3629,9 +3630,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.195" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] @@ -3649,9 +3650,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", diff --git a/replay/Cargo.toml b/replay/Cargo.toml index 63e2d16..6f9487c 100644 --- a/replay/Cargo.toml +++ b/replay/Cargo.toml @@ -22,5 +22,6 @@ libc.workspace = true libloading.workspace = true parking_lot.workspace = true rustc-host.workspace = true +serde = { version = "1.0.203", features = ["derive"] } sneks.workspace = true tokio.workspace = true diff --git a/replay/src/trace.rs b/replay/src/trace.rs index b30c4de..8fe63b3 100644 --- a/replay/src/trace.rs +++ b/replay/src/trace.rs @@ -10,9 +10,10 @@ use ethers::{ types::{ GethDebugTracerType, GethDebugTracingOptions, GethTrace, Transaction, TransactionReceipt, }, - utils::__serde_json::Value, + utils::__serde_json::{from_value, Value}, }; use eyre::{bail, Result}; +use serde::{Deserialize, Serialize}; use sneks::SimpleSnakeNames; use std::{collections::VecDeque, mem}; @@ -44,6 +45,17 @@ impl Trace { bail!("malformed tracing result") }; + if let Value::Array(arr) = json.clone() { + if arr.is_empty() { + bail!("No trace frames found, perhaps you are attempting to trace the program deployment transaction"); + } + } + + let maybe_activation_trace: Result, _> = from_value(json.clone()); + if maybe_activation_trace.is_ok() { + bail!("Your tx was a program activation transaction. It has no trace frames"); + } + let to = receipt.to.map(|x| Address::from(x.0)); let top_frame = TraceFrame::parse_frame(to, json.clone())?; @@ -63,6 +75,11 @@ impl Trace { } } +#[derive(Serialize, Deserialize)] +pub struct ActivationTraceFrame { + address: Value, +} + #[derive(Clone, Debug)] pub struct TraceFrame { steps: Vec, From 7d013b9b9b5d1c045ddeca70bccf2ba16c769e5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20FP?= <105675159+TucksonDev@users.noreply.github.com> Date: Tue, 18 Jun 2024 16:36:47 +0100 Subject: [PATCH 13/35] Change default RPC to Arbitrum Sepolia (#46) --- check/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check/src/main.rs b/check/src/main.rs index 4de49b2..25b49eb 100644 --- a/check/src/main.rs +++ b/check/src/main.rs @@ -57,7 +57,7 @@ enum Apis { #[derive(Args, Clone, Debug)] struct CheckConfig { /// Arbitrum RPC endpoint. - #[arg(short, long, default_value = "https://stylusv2.arbitrum.io/rpc")] + #[arg(short, long, default_value = "https://sepolia-rollup.arbitrum.io/rpc")] endpoint: String, /// The WASM to check (defaults to any found in the current directory). #[arg(long)] From 5fac3dadaeecd1dc1d9ac68ee7f06a0a3a2991bc Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Mon, 1 Jul 2024 16:59:16 -0500 Subject: [PATCH 14/35] Reproducible Verification of Stylus Programs (#43) * port over verify repro * verify working * add items * bump versions * add arch * get toolchains out * empty private key done * provide paths * clippy * clippy * added info * Update check/src/verify.rs Co-authored-by: Joshua Colvin * ci * Revert "ci" This reverts commit 2e8d785a715227aec6ad60ec537aede7ee738829. --------- Co-authored-by: Joshua Colvin --- .github/workflows/check.yml | 2 +- Cargo.lock | 27 +++--- Cargo.toml | 4 +- README.md | 21 ++++ check/Cargo.toml | 2 + check/src/check.rs | 56 +++++++---- check/src/deploy.rs | 63 +++++++----- check/src/docker.rs | 85 +++++++++++++++++ check/src/main.rs | 67 +++++++++++-- check/src/project.rs | 184 +++++++++++++++++++++++++++++++++++- check/src/verify.rs | 71 ++++++++++++++ check/src/wallet.rs | 3 + main/src/main.rs | 20 +++- 13 files changed, 537 insertions(+), 68 deletions(-) create mode 100644 check/src/docker.rs create mode 100644 check/src/verify.rs diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 562d891..7780c2f 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -27,7 +27,7 @@ jobs: strategy: fail-fast: false matrix: - toolchain: [stable, beta] + toolchain: [stable] steps: - uses: actions/checkout@v3 with: diff --git a/Cargo.lock b/Cargo.lock index 6bfee2a..6739b34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -634,7 +634,7 @@ dependencies = [ [[package]] name = "cargo-stylus" -version = "0.3.1" +version = "0.3.2" dependencies = [ "cargo-stylus-util", "clap", @@ -643,7 +643,7 @@ dependencies = [ [[package]] name = "cargo-stylus-cgen" -version = "0.3.1" +version = "0.3.2" dependencies = [ "alloy-json-abi", "clap", @@ -654,7 +654,7 @@ dependencies = [ [[package]] name = "cargo-stylus-check" -version = "0.3.1" +version = "0.3.2" dependencies = [ "alloy-ethers-typecast", "alloy-json-abi", @@ -668,10 +668,12 @@ dependencies = [ "clap", "ethers", "eyre", + "glob", "hex", "lazy_static", "serde", "serde_json", + "tempfile", "thiserror", "tiny-keccak", "tokio", @@ -680,14 +682,14 @@ dependencies = [ [[package]] name = "cargo-stylus-example" -version = "0.3.1" +version = "0.3.2" dependencies = [ "clap", ] [[package]] name = "cargo-stylus-replay" -version = "0.3.1" +version = "0.3.2" dependencies = [ "alloy-primitives 0.7.2", "cargo-stylus-util", @@ -707,7 +709,7 @@ dependencies = [ [[package]] name = "cargo-stylus-util" -version = "0.3.1" +version = "0.3.2" dependencies = [ "ethers", "eyre", @@ -2430,9 +2432,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.152" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libloading" @@ -3433,9 +3435,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.30" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags 2.4.2", "errno", @@ -3993,13 +3995,12 @@ checksum = "69758bda2e78f098e4ccb393021a0963bb3442eac05f135c30f61b7370bbafae" [[package]] name = "tempfile" -version = "3.9.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", "rustix", "windows-sys 0.52.0", ] diff --git a/Cargo.toml b/Cargo.toml index 122c4d0..87e2cec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ resolver = "2" [workspace.package] authors = ["Offchain Labs"] -version = "0.3.1" +version = "0.3.2" edition = "2021" homepage = "https://arbitrum.io" license = "MIT OR Apache-2.0" @@ -34,4 +34,4 @@ parking_lot = "0.12.1" sneks = "0.1.2" # members -cargo-stylus-util = { path = "util", version = "0.3.1" } +cargo-stylus-util = { path = "util", version = "0.3.2" } diff --git a/README.md b/README.md index 7e0e7b1..6f9ee6c 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,27 @@ Usage: cargo stylus deploy [OPTIONS] See `--help` for all available flags and default values. +## Verifying Stylus Programs + +**cargo stylus verify** + +Verifies that a deployed smart contract is identical to that produced by the +current project. Since Stylus smart contracts include a hash of all project +files, this additionally verifies that code comments and other files are +identical. To ensure build reproducibility, if a program is to be verified, +it should be both deployed and verified using `cargo stylus reproducible`. + +See `--help` for all available flags and default values. + +## Reproducibly Deploying and Verifying + +**cargo stylus reproducible** + +Runs a `cargo stylus` command in a Docker container to ensure build +reproducibility. + +See `--help` for all available flags and default values. + ## Deploying Non-Rust WASM Projects The Stylus tool can also be used to deploy non-Rust, WASM projects to Stylus by specifying the WASM file directly with the `--wasm-file` flag to any of the cargo stylus commands. diff --git a/check/Cargo.toml b/check/Cargo.toml index f223bc1..c428200 100644 --- a/check/Cargo.toml +++ b/check/Cargo.toml @@ -31,3 +31,5 @@ tiny-keccak = { version = "2.0.2", features = ["keccak"] } thiserror = "1.0.47" tokio.workspace = true wasmer = "3.1.0" +glob = "0.3.1" +tempfile = "3.10.1" diff --git a/check/src/check.rs b/check/src/check.rs index 771168f..c0e8bac 100644 --- a/check/src/check.rs +++ b/check/src/check.rs @@ -47,13 +47,13 @@ sol! { /// Checks that a program is valid and can be deployed onchain. /// Returns whether the WASM is already up-to-date and activated onchain, and the data fee. pub async fn check(cfg: &CheckConfig) -> Result { - if cfg.endpoint == "https://stylus-testnet.arbitrum.io/rpc" { + if cfg.common_cfg.endpoint == "https://stylus-testnet.arbitrum.io/rpc" { let version = "cargo stylus version 0.2.1".to_string().red(); bail!("The old Stylus testnet is no longer supported.\nPlease downgrade to {version}",); } - let verbose = cfg.verbose; - let wasm = cfg.build_wasm().wrap_err("failed to build wasm")?; + let verbose = cfg.common_cfg.verbose; + let (wasm, project_hash) = cfg.build_wasm().wrap_err("failed to build wasm")?; if verbose { greyln!("reading wasm file at {}", wasm.to_string_lossy().lavender()); @@ -65,55 +65,79 @@ pub async fn check(cfg: &CheckConfig) -> Result { if verbose { greyln!("wasm size: {}", format_file_size(wasm.len(), 96, 128)); - greyln!("connecting to RPC: {}", &cfg.endpoint.lavender()); + greyln!("connecting to RPC: {}", &cfg.common_cfg.endpoint.lavender()); } // check if the program already exists - let provider = sys::new_provider(&cfg.endpoint)?; + let provider = sys::new_provider(&cfg.common_cfg.endpoint)?; let codehash = alloy_primitives::keccak256(&code); if program_exists(codehash, &provider).await? { - return Ok(ProgramCheck::Active(code)); + return Ok(ProgramCheck::Active { code, project_hash }); } let address = cfg.program_address.unwrap_or(H160::random()); let fee = check_activate(code.clone().into(), address, &provider).await?; let visual_fee = format_data_fee(fee).unwrap_or("???".red()); greyln!("wasm data fee: {visual_fee}"); - Ok(ProgramCheck::Ready(code, fee)) + Ok(ProgramCheck::Ready { + code, + fee, + project_hash, + }) } /// Whether a program is active, or needs activation. #[derive(PartialEq)] pub enum ProgramCheck { /// Program already exists onchain. - Active(Vec), + Active { + code: Vec, + project_hash: [u8; 32], + }, /// Program can be activated with the given data fee. - Ready(Vec, U256), + Ready { + code: Vec, + fee: U256, + project_hash: [u8; 32], + }, } impl ProgramCheck { pub fn code(&self) -> &[u8] { match self { - Self::Active(code) => code, - Self::Ready(code, _) => code, + Self::Active { code, .. } => code, + Self::Ready { code, .. } => code, + } + } + + pub fn project_hash(&self) -> &[u8; 32] { + match self { + Self::Active { project_hash, .. } => project_hash, + Self::Ready { project_hash, .. } => project_hash, } } pub fn suggest_fee(&self) -> U256 { match self { - Self::Active(_) => U256::default(), - Self::Ready(_, data_fee) => data_fee * U256::from(120) / U256::from(100), + Self::Active { .. } => U256::default(), + Self::Ready { fee, .. } => fee * U256::from(120) / U256::from(100), } } } impl CheckConfig { - fn build_wasm(&self) -> Result { + fn build_wasm(&self) -> Result<(PathBuf, [u8; 32])> { if let Some(wasm) = self.wasm_file.clone() { - return Ok(wasm); + return Ok((wasm, [0u8; 32])); } - project::build_dylib(BuildConfig::new(self.rust_stable)) + let cfg = BuildConfig::new(self.common_cfg.rust_stable); + let project_hash = project::hash_files( + self.common_cfg.source_files_for_project_hash.clone(), + cfg.clone(), + )?; + let wasm = project::build_dylib(cfg)?; + Ok((wasm, project_hash)) } } diff --git a/check/src/deploy.rs b/check/src/deploy.rs index 7f2792d..8326dfb 100644 --- a/check/src/deploy.rs +++ b/check/src/deploy.rs @@ -49,9 +49,9 @@ pub async fn deploy(cfg: DeployConfig) -> Result<()> { } let program = run!(check::check(&cfg.check_config), "cargo stylus check failed"); - let verbose = cfg.check_config.verbose; + let verbose = cfg.check_config.common_cfg.verbose; - let client = sys::new_provider(&cfg.check_config.endpoint)?; + let client = sys::new_provider(&cfg.check_config.common_cfg.endpoint)?; let chain_id = run!(client.get_chainid(), "failed to get chain id"); let wallet = cfg.auth.wallet().wrap_err("failed to load wallet")?; @@ -65,7 +65,7 @@ pub async fn deploy(cfg: DeployConfig) -> Result<()> { let data_fee = program.suggest_fee(); - if let ProgramCheck::Ready(..) = &program { + if let ProgramCheck::Ready { .. } = &program { // check balance early let balance = run!(client.get_balance(sender, None), "failed to get balance"); let balance = alloy_ethers_typecast::ethers_u256_to_alloy(balance); @@ -83,11 +83,13 @@ pub async fn deploy(cfg: DeployConfig) -> Result<()> { } } - let contract = cfg.deploy_contract(program.code(), sender, &client).await?; + let contract = cfg + .deploy_contract(program.code(), program.project_hash(), sender, &client) + .await?; match program { - ProgramCheck::Ready(..) => cfg.activate(sender, contract, data_fee, &client).await?, - ProgramCheck::Active(_) => greyln!("wasm already activated!"), + ProgramCheck::Ready { .. } => cfg.activate(sender, contract, data_fee, &client).await?, + ProgramCheck::Active { .. } => greyln!("wasm already activated!"), } Ok(()) } @@ -96,33 +98,22 @@ impl DeployConfig { async fn deploy_contract( &self, code: &[u8], + project_hash: &[u8; 32], sender: H160, client: &SignerClient, ) -> Result { - let mut init_code = Vec::with_capacity(42 + code.len()); - init_code.push(0x7f); // PUSH32 - init_code.extend(AU256::from(code.len()).to_be_bytes::<32>()); - init_code.push(0x80); // DUP1 - init_code.push(0x60); // PUSH1 - init_code.push(0x2a); // 42 the prelude length - init_code.push(0x60); // PUSH1 - init_code.push(0x00); - init_code.push(0x39); // CODECOPY - init_code.push(0x60); // PUSH1 - init_code.push(0x00); - init_code.push(0xf3); // RETURN - init_code.extend(code); + let init_code = program_deployment_calldata(code, project_hash); let tx = Eip1559TransactionRequest::new() .from(sender) .data(init_code); - let verbose = self.check_config.verbose; + let verbose = self.check_config.common_cfg.verbose; let gas = client .estimate_gas(&TypedTransaction::Eip1559(tx.clone()), None) .await?; - if self.check_config.verbose || self.estimate_gas { + if self.check_config.common_cfg.verbose || self.estimate_gas { greyln!("deploy gas estimate: {}", format_gas(gas)); } if self.estimate_gas { @@ -143,6 +134,8 @@ impl DeployConfig { } else { greyln!("deployed code at address: {address}"); } + let tx_hash = receipt.transaction_hash.debug_lavender(); + greyln!("Deployment tx hash: {tx_hash}"); Ok(contract) } @@ -153,7 +146,7 @@ impl DeployConfig { data_fee: AU256, client: &SignerClient, ) -> Result<()> { - let verbose = self.check_config.verbose; + let verbose = self.check_config.common_cfg.verbose; let data_fee = alloy_ethers_typecast::alloy_u256_to_ethers(data_fee); let program: Address = contract.to_fixed_bytes().into(); @@ -170,7 +163,7 @@ impl DeployConfig { .await .map_err(|e| eyre!("did not estimate correctly: {e}"))?; - if self.check_config.verbose || self.estimate_gas { + if self.check_config.common_cfg.verbose || self.estimate_gas { greyln!("activation gas estimate: {}", format_gas(gas)); } if self.estimate_gas { @@ -204,7 +197,7 @@ impl DeployConfig { let tx = client.send_transaction(tx, None).await?; let tx_hash = tx.tx_hash(); - let verbose = self.check_config.verbose; + let verbose = self.check_config.common_cfg.verbose; if verbose { greyln!("sent {name} tx: {}", tx_hash.debug_lavender()); @@ -219,6 +212,28 @@ impl DeployConfig { } } +/// Prepares an EVM bytecode prelude for contract creation. +pub fn program_deployment_calldata(code: &[u8], hash: &[u8; 32]) -> Vec { + let mut code_len = [0u8; 32]; + U256::from(code.len()).to_big_endian(&mut code_len); + let mut deploy: Vec = vec![]; + deploy.push(0x7f); // PUSH32 + deploy.extend(code_len); + deploy.push(0x80); // DUP1 + deploy.push(0x60); // PUSH1 + deploy.push(42 + 1 + 32); // prelude + version + hash + deploy.push(0x60); // PUSH1 + deploy.push(0x00); + deploy.push(0x39); // CODECOPY + deploy.push(0x60); // PUSH1 + deploy.push(0x00); + deploy.push(0xf3); // RETURN + deploy.push(0x00); // version + deploy.extend(hash); + deploy.extend(code); + deploy +} + fn format_gas(gas: U256) -> String { let gas: u64 = gas.try_into().unwrap_or(u64::MAX); let text = format!("{gas} gas"); diff --git a/check/src/docker.rs b/check/src/docker.rs new file mode 100644 index 0000000..1b17e90 --- /dev/null +++ b/check/src/docker.rs @@ -0,0 +1,85 @@ +// Copyright 2023-2024, Offchain Labs, Inc. +// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md + +use std::io::Write; +use std::process::{Command, Stdio}; + +use eyre::{bail, eyre, Result}; + +fn version_to_image_name(version: &str) -> String { + format!("cargo-stylus-{}", version) +} + +fn image_exists(name: &str) -> Result { + let output = Command::new("docker") + .arg("images") + .arg(name) + .output() + .map_err(|e| eyre!("failed to execute Docker command: {e}"))?; + Ok(output.stdout.iter().filter(|c| **c == b'\n').count() > 1) +} + +fn create_image(version: &str) -> Result<()> { + let name = version_to_image_name(version); + if image_exists(&name)? { + return Ok(()); + } + let mut child = Command::new("docker") + .arg("build") + .arg("-t") + .arg(name) + .arg(".") + .arg("-f-") + .stdin(Stdio::piped()) + .spawn() + .map_err(|e| eyre!("failed to execure Docker command: {e}"))?; + write!( + child.stdin.as_mut().unwrap(), + "\ + FROM rust:{} as builder\n\ + RUN rustup target add wasm32-unknown-unknown + RUN rustup target add wasm32-wasi + RUN rustup target add aarch64-unknown-linux-gnu + RUN cargo install cargo-stylus + RUN cargo install --force cargo-stylus-check + RUN cargo install --force cargo-stylus-replay + RUN cargo install --force cargo-stylus-cgen + ", + version + )?; + child.wait().map_err(|e| eyre!("wait failed: {e}"))?; + Ok(()) +} + +fn run_in_docker_container(version: &str, command_line: &[&str]) -> Result<()> { + let name = version_to_image_name(version); + if !image_exists(&name)? { + bail!("Docker image {name} doesn't exist"); + } + let dir = + std::env::current_dir().map_err(|e| eyre!("failed to find current directory: {e}"))?; + Command::new("docker") + .arg("run") + .arg("--network") + .arg("host") + .arg("-w") + .arg("/source") + .arg("-v") + .arg(format!("{}:/source", dir.as_os_str().to_str().unwrap())) + .arg(name) + .args(command_line) + .spawn() + .map_err(|e| eyre!("failed to execure Docker command: {e}"))? + .wait() + .map_err(|e| eyre!("wait failed: {e}"))?; + Ok(()) +} + +pub fn run_reproducible(version: &str, command_line: &[String]) -> Result<()> { + let mut command = vec!["cargo", "stylus"]; + for s in command_line.iter() { + command.push(s); + } + create_image(version)?; + run_in_docker_container(version, &command) +} diff --git a/check/src/main.rs b/check/src/main.rs index 25b49eb..18d1c26 100644 --- a/check/src/main.rs +++ b/check/src/main.rs @@ -10,10 +10,12 @@ use tokio::runtime::Builder; mod check; mod constants; mod deploy; +mod docker; mod export_abi; mod macros; mod new; mod project; +mod verify; mod wallet; #[derive(Parser, Debug)] @@ -52,25 +54,54 @@ enum Apis { /// Deploy a contract. #[command(alias = "d")] Deploy(DeployConfig), + /// Build in a Docker container to ensure reproducibility. + /// + /// Specify the Rust version to use, followed by the cargo stylus subcommand. + /// Example: `cargo stylus reproducible 1.77 check` + Reproducible { + /// Rust version to use. + #[arg()] + rust_version: String, + + /// Stylus subcommand. + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] + stylus: Vec, + }, + /// Verify the deployment of a Stylus program. + #[command(alias = "v")] + Verify(VerifyConfig), } #[derive(Args, Clone, Debug)] -struct CheckConfig { +struct CommonConfig { /// Arbitrum RPC endpoint. #[arg(short, long, default_value = "https://sepolia-rollup.arbitrum.io/rpc")] endpoint: String, - /// The WASM to check (defaults to any found in the current directory). - #[arg(long)] - wasm_file: Option, - /// Where to deploy and activate the program (defaults to a random address). - #[arg(long)] - program_address: Option, /// Whether to use stable Rust. #[arg(long)] rust_stable: bool, /// Whether to print debug info. #[arg(long)] verbose: bool, + /// The path to source files to include in the project hash, which + /// is included in the contract deployment init code transaction + /// to be used for verification of deployment integrity. + /// If not provided, all .rs files and Cargo.toml and Cargo.lock files + /// in project's directory tree are included. + #[arg(long)] + source_files_for_project_hash: Vec, +} + +#[derive(Args, Clone, Debug)] +pub struct CheckConfig { + #[command(flatten)] + common_cfg: CommonConfig, + /// The WASM to check (defaults to any found in the current directory). + #[arg(long)] + wasm_file: Option, + /// Where to deploy and activate the program (defaults to a random address). + #[arg(long)] + program_address: Option, } #[derive(Args, Clone, Debug)] @@ -85,6 +116,16 @@ struct DeployConfig { estimate_gas: bool, } +#[derive(Args, Clone, Debug)] +pub struct VerifyConfig { + #[command(flatten)] + common_cfg: CommonConfig, + + /// Hash of the deployment transaction. + #[arg(long)] + deployment_tx: String, +} + #[derive(Clone, Debug, Args)] #[clap(group(ArgGroup::new("key").required(true).args(&["private_key_path", "private_key", "keystore_path"])))] struct AuthOpts { @@ -128,6 +169,18 @@ async fn main_impl(args: Opts) -> Result<()> { Apis::Deploy(config) => { run!(deploy::deploy(config).await, "failed to deploy"); } + Apis::Reproducible { + rust_version, + stylus, + } => { + run!( + docker::run_reproducible(&rust_version, &stylus), + "failed reproducible run" + ); + } + Apis::Verify(config) => { + run!(verify::verify(config).await, "failed to verify"); + } } Ok(()) } diff --git a/check/src/project.rs b/check/src/project.rs index fce5bcf..7a06dab 100644 --- a/check/src/project.rs +++ b/check/src/project.rs @@ -7,17 +7,26 @@ use crate::{ }; use brotli2::read::BrotliEncoder; use cargo_stylus_util::{color::Color, sys}; -use eyre::{eyre, Result, WrapErr}; -use std::{env::current_dir, fs, io::Read, path::PathBuf, process}; +use eyre::{bail, eyre, Result, WrapErr}; +use glob::glob; +use std::process::Command; +use std::{ + env::current_dir, + fs, + io::Read, + path::{Path, PathBuf}, + process, +}; +use tiny_keccak::{Hasher, Keccak}; -#[derive(Default, PartialEq)] +#[derive(Default, Clone, PartialEq)] pub enum OptLevel { #[default] S, Z, } -#[derive(Default)] +#[derive(Default, Clone)] pub struct BuildConfig { pub opt_level: OptLevel, pub stable: bool, @@ -112,6 +121,120 @@ pub fn build_dylib(cfg: BuildConfig) -> Result { Ok(wasm_file_path) } +fn all_paths(root_dir: &Path, source_file_patterns: Vec) -> Result> { + let mut files = Vec::::new(); + let mut directories = Vec::::new(); + directories.push(root_dir.to_path_buf()); // Using `from` directly + + let glob_paths = expand_glob_patterns(source_file_patterns)?; + + while let Some(dir) = directories.pop() { + for entry in fs::read_dir(&dir) + .map_err(|e| eyre!("Unable to read directory {}: {e}", dir.display()))? + { + let entry = entry.map_err(|e| eyre!("Error finding file in {}: {e}", dir.display()))?; + let path = entry.path(); + + if path.is_dir() { + if path.ends_with("target") || path.ends_with(".git") { + continue; // Skip "target" and ".git" directories + } + directories.push(path); + } else if path.file_name().map_or(false, |f| { + // If the user has has specified a list of source file patterns, check if the file + // matches the pattern. + if !glob_paths.is_empty() { + for glob_path in glob_paths.iter() { + if glob_path == &path { + return true; + } + } + false + } else { + // Otherwise, by default include all rust files, Cargo.toml and Cargo.lock files. + f == "Cargo.toml" || f == "Cargo.lock" || f.to_string_lossy().ends_with(".rs") + } + }) { + files.push(path); + } + } + } + Ok(files) +} + +pub fn hash_files(source_file_patterns: Vec, cfg: BuildConfig) -> Result<[u8; 32]> { + let mut keccak = Keccak::v256(); + let mut cmd = Command::new("cargo"); + if !cfg.stable { + cmd.arg("+nightly"); + } + cmd.arg("--version"); + let output = cmd + .output() + .map_err(|e| eyre!("failed to execute cargo command: {e}"))?; + if !output.status.success() { + bail!("cargo version command failed"); + } + keccak.update(&output.stdout); + if cfg.opt_level == OptLevel::Z { + keccak.update(&[0]); + } else { + keccak.update(&[1]); + } + + let mut buf = vec![0u8; 0x100000]; + + let mut hash_file = |filename: &Path| -> Result<()> { + keccak.update(&(filename.as_os_str().len() as u64).to_be_bytes()); + keccak.update(filename.as_os_str().as_encoded_bytes()); + let mut file = std::fs::File::open(filename) + .map_err(|e| eyre!("failed to open file {}: {e}", filename.display()))?; + keccak.update(&file.metadata().unwrap().len().to_be_bytes()); + loop { + let bytes_read = file + .read(&mut buf) + .map_err(|e| eyre!("Unable to read file {}: {e}", filename.display()))?; + if bytes_read == 0 { + break; + } + keccak.update(&buf[..bytes_read]); + } + Ok(()) + }; + + let mut paths = all_paths(PathBuf::from(".").as_path(), source_file_patterns)?; + paths.sort(); + + for filename in paths.iter() { + println!( + "File used for deployment hash: {}", + filename.as_os_str().to_string_lossy() + ); + hash_file(filename)?; + } + + let mut hash = [0u8; 32]; + keccak.finalize(&mut hash); + println!( + "Project hash computed on deployment: {:?}", + hex::encode(hash) + ); + Ok(hash) +} + +fn expand_glob_patterns(patterns: Vec) -> Result> { + let mut files_to_include = Vec::new(); + for pattern in patterns { + let paths = glob(&pattern) + .map_err(|e| eyre!("Failed to read glob pattern '{}': {}", pattern, e))?; + for path_result in paths { + let path = path_result.map_err(|e| eyre!("Error processing path: {}", e))?; + files_to_include.push(path); + } + } + Ok(files_to_include) +} + /// Reads a WASM file at a specified path and returns its brotli compressed bytes. pub fn compress_wasm(wasm: &PathBuf) -> Result<(Vec, Vec)> { let wasm = @@ -130,3 +253,56 @@ pub fn compress_wasm(wasm: &PathBuf) -> Result<(Vec, Vec)> { Ok((wasm.to_vec(), contract_code)) } + +#[cfg(test)] +mod test { + use super::*; + use std::fs::{self, File}; + use std::io::Write; + use tempfile::tempdir; + + #[test] + fn test_all_paths() -> Result<()> { + let dir = tempdir()?; + let dir_path = dir.path(); + + let files = vec!["file.rs", "ignore.me", "Cargo.toml", "Cargo.lock"]; + for file in files.iter() { + let file_path = dir_path.join(file); + let mut file = File::create(&file_path)?; + writeln!(file, "Test content")?; + } + + let dirs = vec!["nested", ".git", "target"]; + for d in dirs.iter() { + let subdir_path = dir_path.join(d); + if !subdir_path.exists() { + fs::create_dir(&subdir_path)?; + } + } + + let nested_dir = dir_path.join("nested"); + let nested_file = nested_dir.join("nested.rs"); + if !nested_file.exists() { + File::create(&nested_file)?; + } + + let found_files = all_paths( + dir_path, + vec![format!( + "{}/{}", + dir_path.as_os_str().to_string_lossy(), + "**/*.rs" + )], + )?; + + // Check that the correct files are included + assert!(found_files.contains(&dir_path.join("file.rs"))); + assert!(found_files.contains(&nested_dir.join("nested.rs"))); + assert!(!found_files.contains(&dir_path.join("ignore.me"))); + assert!(!found_files.contains(&dir_path.join("Cargo.toml"))); // Not matching *.rs + assert_eq!(found_files.len(), 2, "Should only find 2 Rust files."); + + Ok(()) + } +} diff --git a/check/src/verify.rs b/check/src/verify.rs new file mode 100644 index 0000000..aa73713 --- /dev/null +++ b/check/src/verify.rs @@ -0,0 +1,71 @@ +// Copyright 2023-2024, Offchain Labs, Inc. +// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md + +#![allow(clippy::println_empty_string)] + +use std::path::PathBuf; + +use eyre::{bail, eyre}; + +use ethers::middleware::Middleware; +use ethers::types::H256; + +use serde::{Deserialize, Serialize}; + +use crate::{check, deploy, project, CheckConfig, VerifyConfig}; +use cargo_stylus_util::{color::Color, sys}; + +#[derive(Debug, Deserialize, Serialize)] +struct RpcResult { + input: String, +} + +pub async fn verify(cfg: VerifyConfig) -> eyre::Result<()> { + let provider = sys::new_provider(&cfg.common_cfg.endpoint)?; + let hash = cargo_stylus_util::text::decode0x(cfg.deployment_tx)?; + if hash.len() != 32 { + bail!("Invalid hash"); + } + let Some(result) = provider + .get_transaction(H256::from_slice(&hash)) + .await + .map_err(|e| eyre!("RPC failed: {e}"))? + else { + bail!("No code at address"); + }; + + let output = sys::new_command("cargo") + .arg("clean") + .output() + .map_err(|e| eyre!("failed to execute cargo clean: {e}"))?; + if !output.status.success() { + bail!("cargo clean command failed"); + } + let check_cfg = CheckConfig { + common_cfg: cfg.common_cfg.clone(), + wasm_file: None, + program_address: None, + }; + let _ = check::check(&check_cfg) + .await + .map_err(|e| eyre!("Stylus checks failed: {e}"))?; + let build_cfg = project::BuildConfig { + opt_level: project::OptLevel::default(), + stable: cfg.common_cfg.rust_stable, + rebuild: false, + }; + let wasm_file: PathBuf = project::build_dylib(build_cfg.clone()) + .map_err(|e| eyre!("could not build project to WASM: {e}"))?; + let (_, init_code) = project::compress_wasm(&wasm_file)?; + let hash = project::hash_files(cfg.common_cfg.source_files_for_project_hash, build_cfg)?; + let deployment_data = deploy::program_deployment_calldata(&init_code, &hash); + if deployment_data == *result.input { + println!("Verified - program matches local project's file hashes"); + } else { + println!( + "{} - program deployment did not verify against local project's file hashes", + "FAILED".red() + ); + } + Ok(()) +} diff --git a/check/src/wallet.rs b/check/src/wallet.rs index 55fb461..adcda45 100644 --- a/check/src/wallet.rs +++ b/check/src/wallet.rs @@ -18,6 +18,9 @@ impl AuthOpts { } if let Some(key) = &self.private_key { + if key.is_empty() { + return Err(eyre!("empty private key")); + } return wallet!(key); } diff --git a/main/src/main.rs b/main/src/main.rs index 601afb0..2759935 100644 --- a/main/src/main.rs +++ b/main/src/main.rs @@ -38,6 +38,12 @@ enum Subcommands { /// Trace a transaction. #[command()] Trace, + /// Verify the deployment of a Stylus program against a local project. + #[command(alias = "v")] + Verify, + /// Run cargo stylus commands in a Docker container for reproducibility. + #[command()] + Reproducible, /// Generate C code. #[command()] CGen, @@ -52,7 +58,19 @@ struct Binary<'a> { const COMMANDS: &[Binary] = &[ Binary { name: "cargo-stylus-check", - apis: &["new", "export-abi", "check", "deploy", "n", "x", "c", "d"], + apis: &[ + "new", + "export-abi", + "check", + "deploy", + "verify", + "reproducible", + "n", + "x", + "c", + "d", + "v", + ], rust_flags: None, }, Binary { From 02507c507a368d2a468af28db8dfc3af1ce6e99b Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Tue, 2 Jul 2024 09:39:32 -0500 Subject: [PATCH 15/35] Add Support for Caching Stylus Programs in Cargo Stylus (#49) * port over verify repro * verify working * add items * bump versions * add arch * get toolchains out * empty private key done * provide paths * clippy * clippy * added info * cargo stylus cache program * add in * cache with bid working * cache method done * all done * rev * clippy * lint * deadcode * edit * import * no dead --- check/src/cache.rs | 109 +++++++++++++++++++++++++++++++++++++++++ check/src/check.rs | 25 ++++++---- check/src/constants.rs | 5 ++ check/src/deploy.rs | 70 +++++++++++++++----------- check/src/main.rs | 21 ++++++++ check/src/project.rs | 1 - check/src/verify.rs | 1 - main/src/main.rs | 4 ++ replay/src/trace.rs | 7 +-- 9 files changed, 198 insertions(+), 45 deletions(-) create mode 100644 check/src/cache.rs diff --git a/check/src/cache.rs b/check/src/cache.rs new file mode 100644 index 0000000..d76a36d --- /dev/null +++ b/check/src/cache.rs @@ -0,0 +1,109 @@ +// Copyright 2023-2024, Offchain Labs, Inc. +// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/stylus/licenses/COPYRIGHT.md + +use alloy_primitives::FixedBytes; +use alloy_sol_macro::sol; +use alloy_sol_types::{SolCall, SolInterface}; +use cargo_stylus_util::color::{Color, DebugColor}; +use cargo_stylus_util::sys; +use ethers::middleware::{Middleware, SignerMiddleware}; +use ethers::signers::Signer; +use ethers::types::spoof::State; +use ethers::types::{Eip1559TransactionRequest, U256}; +use ethers::utils::keccak256; +use eyre::{bail, Context, Result}; + +use crate::check::{eth_call, EthCallError}; +use crate::constants::{CACHE_MANAGER_H160, EOF_PREFIX_NO_DICT}; +use crate::deploy::{format_gas, run_tx}; +use crate::macros::greyln; +use crate::CacheConfig; + +sol! { + interface CacheManager { + function placeBid(bytes32 codehash) external payable; + + error AsmTooLarge(uint256 asm, uint256 queueSize, uint256 cacheSize); + error AlreadyCached(bytes32 codehash); + error BidTooSmall(uint192 bid, uint192 min); + error BidsArePaused(); + } +} + +pub async fn cache_program(cfg: &CacheConfig) -> Result<()> { + let provider = sys::new_provider(&cfg.common_cfg.endpoint)?; + let chain_id = provider + .get_chainid() + .await + .wrap_err("failed to get chain id")?; + + let wallet = cfg.auth.wallet().wrap_err("failed to load wallet")?; + let wallet = wallet.with_chain_id(chain_id.as_u64()); + let client = SignerMiddleware::new(provider.clone(), wallet); + + let program_code = client + .get_code(cfg.program_address, None) + .await + .wrap_err("failed to fetch program code")?; + + if !program_code.starts_with(hex::decode(EOF_PREFIX_NO_DICT).unwrap().as_slice()) { + bail!( + "program code does not start with Stylus prefix {}", + EOF_PREFIX_NO_DICT + ); + } + let codehash = FixedBytes::<32>::from(keccak256(&program_code)); + greyln!( + "Program codehash {}", + hex::encode(codehash).debug_lavender() + ); + let codehash = FixedBytes::<32>::from(keccak256(&program_code)); + + let data = CacheManager::placeBidCall { codehash }.abi_encode(); + let mut tx = Eip1559TransactionRequest::new() + .to(*CACHE_MANAGER_H160) + .data(data); + + // If a bid is set, specify it. Otherwise, a zero bid will be sent. + if let Some(bid) = cfg.bid { + tx = tx.value(U256::from(bid)); + greyln!("Setting bid value of {} wei", bid.debug_mint()); + } + + if let Err(EthCallError { data, msg }) = + eth_call(tx.clone(), State::default(), &provider).await? + { + let error = match CacheManager::CacheManagerErrors::abi_decode(&data, true) { + Ok(err) => err, + Err(err_details) => bail!("unknown CacheManager error: {msg} and {:?}", err_details), + }; + use CacheManager::CacheManagerErrors as C; + match error { + C::AsmTooLarge(_) => bail!("program too large"), + C::AlreadyCached(_) => bail!("program already cached"), + C::BidsArePaused(_) => { + bail!("bidding is currently paused for the Stylus cache manager") + } + C::BidTooSmall(_) => { + bail!("bid amount {} (wei) too small", cfg.bid.unwrap_or_default()) + } + } + } + let verbose = cfg.common_cfg.verbose; + let receipt = run_tx("cache", tx, None, &client, verbose).await?; + + let address = cfg.program_address.debug_lavender(); + + if verbose { + let gas = format_gas(receipt.gas_used.unwrap_or_default()); + greyln!( + "Successfully cached program at address: {address} {} {gas}", + "with".grey() + ); + } else { + greyln!("Successfully cached program at address: {address}"); + } + let tx_hash = receipt.transaction_hash.debug_lavender(); + greyln!("Sent Stylus cache tx with hash: {tx_hash}"); + Ok(()) +} diff --git a/check/src/check.rs b/check/src/check.rs index c0e8bac..fe3fa0d 100644 --- a/check/src/check.rs +++ b/check/src/check.rs @@ -169,9 +169,9 @@ fn format_data_fee(fee: U256) -> Result { }) } -struct EthCallError { - data: Vec, - msg: String, +pub struct EthCallError { + pub data: Vec, + pub msg: String, } impl From for ErrReport { @@ -180,13 +180,13 @@ impl From for ErrReport { } } -/// A funded eth_call to ArbWasm. -async fn eth_call( +/// A funded eth_call. +pub async fn eth_call( tx: Eip1559TransactionRequest, mut state: State, provider: &Provider, ) -> Result, EthCallError>> { - let tx = TypedTransaction::Eip1559(tx.to(*ARB_WASM_H160)); + let tx = TypedTransaction::Eip1559(tx); state.account(Default::default()).balance = Some(ethers::types::U256::MAX); // infinite balance match provider.call_raw(&tx).state(&state).await { @@ -211,7 +211,9 @@ async fn eth_call( /// Checks whether a program has already been activated with the most recent version of Stylus. async fn program_exists(codehash: B256, provider: &Provider) -> Result { let data = ArbWasm::codehashVersionCall { codehash }.abi_encode(); - let tx = Eip1559TransactionRequest::new().data(data); + let tx = Eip1559TransactionRequest::new() + .to(*ARB_WASM_H160) + .data(data); let outs = eth_call(tx, State::default(), provider).await?; let program_version = match outs { @@ -236,7 +238,9 @@ async fn program_exists(codehash: B256, provider: &Provider) -> Result) -> Result) -> Result { let program = Address::from(address.to_fixed_bytes()); let data = ArbWasm::activateProgramCall { program }.abi_encode(); - let tx = Eip1559TransactionRequest::new().data(data).value(ONE_ETH); + let tx = Eip1559TransactionRequest::new() + .to(*ARB_WASM_H160) + .data(data) + .value(ONE_ETH); let state = spoof::code(address, code); let outs = eth_call(tx, state, provider).await??; let ArbWasm::activateProgramReturn { dataFee, .. } = diff --git a/check/src/constants.rs b/check/src/constants.rs index 9c7b9a8..25aa4c1 100644 --- a/check/src/constants.rs +++ b/check/src/constants.rs @@ -14,11 +14,16 @@ pub const BROTLI_COMPRESSION_LEVEL: u32 = 11; lazy_static! { /// Address of the ArbWasm precompile. pub static ref ARB_WASM_H160: H160 = H160(*ARB_WASM_ADDRESS.0); + /// Address of the Stylus program cache manager. + pub static ref CACHE_MANAGER_H160: H160 = H160(*CACHE_MANAGER_ADDRESS.0); } /// Address of the ArbWasm precompile. pub const ARB_WASM_ADDRESS: Address = address!("0000000000000000000000000000000000000071"); +/// Address of the Stylus program cache manager for Arbitrum chains. +pub const CACHE_MANAGER_ADDRESS: Address = address!("d1bbd579988f394a26d6ec16e77b3fa8a5e8fcee"); + /// Target for compiled WASM folder in a Rust project pub const RUST_TARGET: &str = "wasm32-unknown-unknown"; diff --git a/check/src/deploy.rs b/check/src/deploy.rs index 8326dfb..b5d8fc0 100644 --- a/check/src/deploy.rs +++ b/check/src/deploy.rs @@ -35,7 +35,7 @@ sol! { } } -type SignerClient = SignerMiddleware, Wallet>; +pub type SignerClient = SignerMiddleware, Wallet>; /// Deploys a stylus program, activating if needed. pub async fn deploy(cfg: DeployConfig) -> Result<()> { @@ -121,7 +121,14 @@ impl DeployConfig { return Ok(ethers::utils::get_contract_address(sender, nonce)); } - let receipt = self.run_tx("deploy", tx, Some(gas), client).await?; + let receipt = run_tx( + "deploy", + tx, + Some(gas), + client, + self.check_config.common_cfg.verbose, + ) + .await?; let contract = receipt.contract_address.ok_or(eyre!("missing address"))?; let address = contract.debug_lavender(); @@ -170,7 +177,14 @@ impl DeployConfig { return Ok(()); } - let receipt = self.run_tx("activate", tx, Some(gas), client).await?; + let receipt = run_tx( + "activate", + tx, + Some(gas), + client, + self.check_config.common_cfg.verbose, + ) + .await?; if verbose { let gas = format_gas(receipt.gas_used.unwrap_or_default()); @@ -182,34 +196,32 @@ impl DeployConfig { ); Ok(()) } +} - async fn run_tx( - &self, - name: &str, - tx: Eip1559TransactionRequest, - gas: Option, - client: &SignerClient, - ) -> Result { - let mut tx = TypedTransaction::Eip1559(tx); - if let Some(gas) = gas { - tx.set_gas(gas); - } - - let tx = client.send_transaction(tx, None).await?; - let tx_hash = tx.tx_hash(); - let verbose = self.check_config.common_cfg.verbose; +pub async fn run_tx( + name: &str, + tx: Eip1559TransactionRequest, + gas: Option, + client: &SignerClient, + verbose: bool, +) -> Result { + let mut tx = TypedTransaction::Eip1559(tx); + if let Some(gas) = gas { + tx.set_gas(gas); + } - if verbose { - greyln!("sent {name} tx: {}", tx_hash.debug_lavender()); - } - let Some(receipt) = tx.await.wrap_err("tx failed to complete")? else { - bail!("failed to get receipt for tx {}", tx_hash.lavender()); - }; - if receipt.status != Some(U64::from(1)) { - bail!("{name} tx reverted {}", tx_hash.debug_red()); - } - Ok(receipt) + let tx = client.send_transaction(tx, None).await?; + let tx_hash = tx.tx_hash(); + if verbose { + greyln!("sent {name} tx: {}", tx_hash.debug_lavender()); + } + let Some(receipt) = tx.await.wrap_err("tx failed to complete")? else { + bail!("failed to get receipt for tx {}", tx_hash.lavender()); + }; + if receipt.status != Some(U64::from(1)) { + bail!("{name} tx reverted {}", tx_hash.debug_red()); } + Ok(receipt) } /// Prepares an EVM bytecode prelude for contract creation. @@ -234,7 +246,7 @@ pub fn program_deployment_calldata(code: &[u8], hash: &[u8; 32]) -> Vec { deploy } -fn format_gas(gas: U256) -> String { +pub fn format_gas(gas: U256) -> String { let gas: u64 = gas.try_into().unwrap_or(u64::MAX); let text = format!("{gas} gas"); if gas <= 3_000_000 { diff --git a/check/src/main.rs b/check/src/main.rs index 18d1c26..ff2eb7d 100644 --- a/check/src/main.rs +++ b/check/src/main.rs @@ -7,6 +7,7 @@ use eyre::{eyre, Context, Result}; use std::path::PathBuf; use tokio::runtime::Builder; +mod cache; mod check; mod constants; mod deploy; @@ -48,6 +49,8 @@ enum Apis { #[arg(long)] json: bool, }, + /// Cache a contract using the Stylus CacheManager for Arbitrum chains. + Cache(CacheConfig), /// Check a contract. #[command(alias = "c")] Check(CheckConfig), @@ -92,6 +95,21 @@ struct CommonConfig { source_files_for_project_hash: Vec, } +#[derive(Args, Clone, Debug)] +pub struct CacheConfig { + #[command(flatten)] + common_cfg: CommonConfig, + /// Wallet source to use. + #[command(flatten)] + auth: AuthOpts, + /// Deployed and activated program address to cache. + #[arg(long)] + program_address: H160, + /// Bid, in wei, to place on the desired program to cache + #[arg(short, long, hide(true))] + bid: Option, +} + #[derive(Args, Clone, Debug)] pub struct CheckConfig { #[command(flatten)] @@ -163,6 +181,9 @@ async fn main_impl(args: Opts) -> Result<()> { Apis::ExportAbi { json, output } => { run!(export_abi::export_abi(output, json), "failed to export abi"); } + Apis::Cache(config) => { + run!(cache::cache_program(&config).await, "stylus cache failed"); + } Apis::Check(config) => { run!(check::check(&config).await, "stylus checks failed"); } diff --git a/check/src/project.rs b/check/src/project.rs index 7a06dab..774499a 100644 --- a/check/src/project.rs +++ b/check/src/project.rs @@ -30,7 +30,6 @@ pub enum OptLevel { pub struct BuildConfig { pub opt_level: OptLevel, pub stable: bool, - pub rebuild: bool, } impl BuildConfig { diff --git a/check/src/verify.rs b/check/src/verify.rs index aa73713..9cb4faf 100644 --- a/check/src/verify.rs +++ b/check/src/verify.rs @@ -52,7 +52,6 @@ pub async fn verify(cfg: VerifyConfig) -> eyre::Result<()> { let build_cfg = project::BuildConfig { opt_level: project::OptLevel::default(), stable: cfg.common_cfg.rust_stable, - rebuild: false, }; let wasm_file: PathBuf = project::build_dylib(build_cfg.clone()) .map_err(|e| eyre!("could not build project to WASM: {e}"))?; diff --git a/main/src/main.rs b/main/src/main.rs index 2759935..47e285d 100644 --- a/main/src/main.rs +++ b/main/src/main.rs @@ -26,6 +26,9 @@ enum Subcommands { #[command(alias = "x")] /// Export a Solidity ABI. ExportAbi, + /// Cache a contract. + #[command(alias = "c")] + Cache, /// Check a contract. #[command(alias = "c")] Check, @@ -61,6 +64,7 @@ const COMMANDS: &[Binary] = &[ apis: &[ "new", "export-abi", + "cache", "check", "deploy", "verify", diff --git a/replay/src/trace.rs b/replay/src/trace.rs index 8fe63b3..fecd5c6 100644 --- a/replay/src/trace.rs +++ b/replay/src/trace.rs @@ -7,9 +7,7 @@ use alloy_primitives::{Address, FixedBytes, TxHash, B256, U256}; use cargo_stylus_util::color::{Color, DebugColor}; use ethers::{ providers::{JsonRpcClient, Middleware, Provider}, - types::{ - GethDebugTracerType, GethDebugTracingOptions, GethTrace, Transaction, TransactionReceipt, - }, + types::{GethDebugTracerType, GethDebugTracingOptions, GethTrace, Transaction}, utils::__serde_json::{from_value, Value}, }; use eyre::{bail, Result}; @@ -20,7 +18,6 @@ use std::{collections::VecDeque, mem}; #[derive(Debug)] pub struct Trace { pub top_frame: TraceFrame, - pub receipt: TransactionReceipt, pub tx: Transaction, pub json: Value, } @@ -61,7 +58,6 @@ impl Trace { Ok(Self { top_frame, - receipt, tx, json, }) @@ -399,6 +395,7 @@ pub struct Hostio { pub end_ink: u64, } +#[allow(dead_code)] #[derive(Clone, Debug, SimpleSnakeNames)] pub enum HostioKind { UserEntrypoint { From 695f074702d466045a73f3f36f3676955b770647 Mon Sep 17 00:00:00 2001 From: Joe Wanga Date: Tue, 2 Jul 2024 17:43:45 +0300 Subject: [PATCH 16/35] Add Windows Support (#48) * Add Windows support * Added conditional import for Windows * Apply format * Apply cargo format & debug output --- main/src/main.rs | 29 +++++++++++++++++++++++++---- replay/src/main.rs | 14 +++++++++++++- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/main/src/main.rs b/main/src/main.rs index 47e285d..7ffa008 100644 --- a/main/src/main.rs +++ b/main/src/main.rs @@ -4,8 +4,15 @@ use cargo_stylus_util::{color::Color, sys}; use clap::Parser; use eyre::{bail, Result}; + +// Conditional import for Unix-specific `CommandExt` +#[cfg(unix)] use std::{env, os::unix::process::CommandExt}; +// Conditional import for Windows +#[cfg(windows)] +use std::env; + #[derive(Parser, Debug)] #[command(name = "stylus")] #[command(bin_name = "cargo stylus")] @@ -124,8 +131,15 @@ fn main() -> Result<()> { // see if custom extension exists let custom = format!("cargo-stylus-{arg}"); if sys::command_exists(&custom) { - let err = sys::new_command(&custom).arg(arg).args(args).exec(); - bail!("failed to invoke {}: {err}", custom.red()); + let mut command = sys::new_command(&custom); + command.arg(arg).args(args); + + // Execute command conditionally based on the platform + #[cfg(unix)] + let err = command.exec(); // Unix-specific execution + #[cfg(windows)] + let err = command.status(); // Windows-specific execution + bail!("failed to invoke {:?}: {:?}", custom.red(), err); } eprintln!("Unknown subcommand {}.", arg.red()); @@ -148,6 +162,13 @@ fn main() -> Result<()> { } // should never return - let err = sys::new_command(name).arg(arg).args(args).exec(); - bail!("failed to invoke {}: {err}", name.red()); + let mut command = sys::new_command(name); + command.arg(arg).args(args); + + // Execute command conditionally based on the platform + #[cfg(unix)] + let err = command.exec(); // Unix-specific execution + #[cfg(windows)] + let err = command.status(); // Windows-specific execution + bail!("failed to invoke {:?}: {:?}", name.red(), err); } diff --git a/replay/src/main.rs b/replay/src/main.rs index 485d822..e74b465 100644 --- a/replay/src/main.rs +++ b/replay/src/main.rs @@ -6,10 +6,19 @@ use alloy_primitives::TxHash; use cargo_stylus_util::{color::Color, sys}; use clap::{Args, Parser}; use eyre::{bail, eyre, Context, Result}; +// Conditional import for Unix-specific `CommandExt` +#[cfg(unix)] use std::{ os::unix::process::CommandExt, path::{Path, PathBuf}, }; + +// Conditional import for Windows +#[cfg(windows)] +use std::{ + env, + path::{Path, PathBuf}, +}; use tokio::runtime::Builder; mod hostio; @@ -127,9 +136,12 @@ async fn replay(args: ReplayArgs) -> Result<()> { cmd.arg(arg); } cmd.arg("--child"); + #[cfg(unix)] let err = cmd.exec(); + #[cfg(windows)] + let err = cmd.status(); - bail!("failed to exec gdb {}", err); + bail!("failed to exec gdb {:?}", err); } let provider = sys::new_provider(&args.endpoint)?; From c199292155fdcc88e01564aaa1bdef1f6570c13c Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Tue, 2 Jul 2024 09:57:53 -0500 Subject: [PATCH 17/35] Allow Configurable Max Fee Per Gas in Tx Sending (#45) * max fee per gas config * no deps clippy * custom --- .github/workflows/check.yml | 3 ++- check/src/cache.rs | 10 +++++++++- check/src/deploy.rs | 20 +++++++++++++++++--- check/src/main.rs | 5 ++++- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 7780c2f..e5169d6 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -40,4 +40,5 @@ jobs: - name: cargo clippy uses: actions-rs/clippy-check@v1 with: - token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + token: ${{ secrets.GITHUB_TOKEN }} + args: -- --no-deps \ No newline at end of file diff --git a/check/src/cache.rs b/check/src/cache.rs index d76a36d..ab6899d 100644 --- a/check/src/cache.rs +++ b/check/src/cache.rs @@ -90,7 +90,15 @@ pub async fn cache_program(cfg: &CacheConfig) -> Result<()> { } } let verbose = cfg.common_cfg.verbose; - let receipt = run_tx("cache", tx, None, &client, verbose).await?; + let receipt = run_tx( + "cache", + tx, + None, + cfg.common_cfg.max_fee_per_gas_gwei, + &client, + verbose, + ) + .await?; let address = cfg.program_address.debug_lavender(); diff --git a/check/src/deploy.rs b/check/src/deploy.rs index b5d8fc0..df54bdd 100644 --- a/check/src/deploy.rs +++ b/check/src/deploy.rs @@ -125,6 +125,7 @@ impl DeployConfig { "deploy", tx, Some(gas), + self.check_config.common_cfg.max_fee_per_gas_gwei, client, self.check_config.common_cfg.verbose, ) @@ -181,6 +182,7 @@ impl DeployConfig { "activate", tx, Some(gas), + self.check_config.common_cfg.max_fee_per_gas_gwei, client, self.check_config.common_cfg.verbose, ) @@ -202,14 +204,18 @@ pub async fn run_tx( name: &str, tx: Eip1559TransactionRequest, gas: Option, + max_fee_per_gas_gwei: Option, client: &SignerClient, verbose: bool, ) -> Result { - let mut tx = TypedTransaction::Eip1559(tx); + let mut tx = tx; if let Some(gas) = gas { - tx.set_gas(gas); + tx.gas = Some(gas); } - + if let Some(max_fee) = max_fee_per_gas_gwei { + tx.max_fee_per_gas = Some(gwei_to_wei(max_fee)?); + } + let tx = TypedTransaction::Eip1559(tx); let tx = client.send_transaction(tx, None).await?; let tx_hash = tx.tx_hash(); if verbose { @@ -257,3 +263,11 @@ pub fn format_gas(gas: U256) -> String { text.pink() } } + +fn gwei_to_wei(gwei: U256) -> Result { + let wei_per_gwei: U256 = U256::from(10u64.pow(9)); + match gwei.checked_mul(wei_per_gwei) { + Some(wei) => Ok(wei), + None => bail!("overflow occurred while converting gwei to wei"), + } +} diff --git a/check/src/main.rs b/check/src/main.rs index ff2eb7d..2a3b097 100644 --- a/check/src/main.rs +++ b/check/src/main.rs @@ -2,7 +2,7 @@ // For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md use clap::{ArgGroup, Args, Parser}; -use ethers::types::H160; +use ethers::types::{H160, U256}; use eyre::{eyre, Context, Result}; use std::path::PathBuf; use tokio::runtime::Builder; @@ -93,6 +93,9 @@ struct CommonConfig { /// in project's directory tree are included. #[arg(long)] source_files_for_project_hash: Vec, + #[arg(long)] + /// Optional max fee per gas in gwei units. + max_fee_per_gas_gwei: Option, } #[derive(Args, Clone, Debug)] From 884f8d8282d5383fc296adc2c488c40bb36f1a01 Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Tue, 2 Jul 2024 10:04:44 -0500 Subject: [PATCH 18/35] Bump to Version 4.0 (#50) * version bump * build --- Cargo.lock | 12 ++++++------ Cargo.toml | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6739b34..b85b2e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -634,7 +634,7 @@ dependencies = [ [[package]] name = "cargo-stylus" -version = "0.3.2" +version = "0.4.0" dependencies = [ "cargo-stylus-util", "clap", @@ -643,7 +643,7 @@ dependencies = [ [[package]] name = "cargo-stylus-cgen" -version = "0.3.2" +version = "0.4.0" dependencies = [ "alloy-json-abi", "clap", @@ -654,7 +654,7 @@ dependencies = [ [[package]] name = "cargo-stylus-check" -version = "0.3.2" +version = "0.4.0" dependencies = [ "alloy-ethers-typecast", "alloy-json-abi", @@ -682,14 +682,14 @@ dependencies = [ [[package]] name = "cargo-stylus-example" -version = "0.3.2" +version = "0.4.0" dependencies = [ "clap", ] [[package]] name = "cargo-stylus-replay" -version = "0.3.2" +version = "0.4.0" dependencies = [ "alloy-primitives 0.7.2", "cargo-stylus-util", @@ -709,7 +709,7 @@ dependencies = [ [[package]] name = "cargo-stylus-util" -version = "0.3.2" +version = "0.4.0" dependencies = [ "ethers", "eyre", diff --git a/Cargo.toml b/Cargo.toml index 87e2cec..55aed5d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ resolver = "2" [workspace.package] authors = ["Offchain Labs"] -version = "0.3.2" +version = "0.4.0" edition = "2021" homepage = "https://arbitrum.io" license = "MIT OR Apache-2.0" @@ -34,4 +34,4 @@ parking_lot = "0.12.1" sneks = "0.1.2" # members -cargo-stylus-util = { path = "util", version = "0.3.2" } +cargo-stylus-util = { path = "util", version = "0.4.0" } From be51b58b5ec182906d21fc7c17be64e0848add62 Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Tue, 16 Jul 2024 13:39:40 -0500 Subject: [PATCH 19/35] Major Changes to Reproducible Builds (#53) * include project hash as custom section in wasm * proper project hash inclusion in wasm * add more details about what went wrong * co * edits * edit * verification and include toolchain * edit * edit * toolchain * patch up * update version * sanitize version --- Cargo.lock | 196 +++++++++++++++++++++++++++++++---------- Cargo.toml | 12 +-- check/Cargo.toml | 4 + check/src/check.rs | 49 ++++------- check/src/constants.rs | 7 ++ check/src/deploy.rs | 26 ++++-- check/src/docker.rs | 20 ++++- check/src/project.rs | 133 ++++++++++++++++++++++++++-- check/src/verify.rs | 33 ++++++- 9 files changed, 379 insertions(+), 101 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b85b2e1..e16de6c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,6 +49,18 @@ dependencies = [ "version_check", ] +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.2" @@ -70,11 +82,11 @@ dependencies = [ [[package]] name = "alloy-json-abi" -version = "0.7.2" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786689872ec4e7d354810ab0dffd48bb40b838c047522eb031cbd47d15634849" +checksum = "bc05b04ac331a9f07e3a4036ef7926e49a8bf84a99a1ccfc7e2ab55a5fcbb372" dependencies = [ - "alloy-primitives 0.7.2", + "alloy-primitives 0.7.7", "alloy-sol-type-parser", "serde", "serde_json", @@ -104,9 +116,9 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.7.2" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525448f6afc1b70dd0f9d0a8145631bf2f5e434678ab23ab18409ca264cae6b3" +checksum = "ccb3ead547f4532bc8af961649942f0b9c16ee9226e26caa3f38420651cc0bf4" dependencies = [ "alloy-rlp", "bytes", @@ -136,13 +148,27 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.7.2" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89c80a2cb97e7aa48611cbb63950336f9824a174cdf670527cc6465078a26ea1" +checksum = "2b40397ddcdcc266f59f959770f601ce1280e699a91fc1862f29cef91707cd09" +dependencies = [ + "alloy-sol-macro-expander", + "alloy-sol-macro-input", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "alloy-sol-macro-expander" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "867a5469d61480fea08c7333ffeca52d5b621f5ca2e44f271b117ec1fc9a0525" dependencies = [ "alloy-sol-macro-input", "const-hex", - "heck 0.4.1", + "heck 0.5.0", "indexmap 2.1.0", "proc-macro-error", "proc-macro2", @@ -154,9 +180,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-input" -version = "0.7.2" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c58894b58ac50979eeac6249661991ac40b9d541830d9a725f7714cc9ef08c23" +checksum = "2e482dc33a32b6fadbc0f599adea520bd3aaa585c141a80b404d0a3e3fa72528" dependencies = [ "const-hex", "dunce", @@ -169,20 +195,21 @@ dependencies = [ [[package]] name = "alloy-sol-type-parser" -version = "0.7.2" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8e71ea68e780cc203919e03f69f59e7afe92d2696fb1dcb6662f61e4031b6" +checksum = "cbcba3ca07cf7975f15d871b721fb18031eec8bce51103907f6dcce00b255d98" dependencies = [ + "serde", "winnow 0.6.7", ] [[package]] name = "alloy-sol-types" -version = "0.7.2" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "399287f68d1081ed8b1f4903c49687658b95b142207d7cb4ae2f4813915343ef" +checksum = "a91ca40fa20793ae9c3841b83e74569d1cc9af29a2f5237314fd3452d51e38c7" dependencies = [ - "alloy-primitives 0.7.2", + "alloy-primitives 0.7.7", "alloy-sol-macro", "const-hex", "serde", @@ -572,6 +599,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "byteorder" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" + [[package]] name = "byteorder" version = "1.5.0" @@ -634,7 +667,7 @@ dependencies = [ [[package]] name = "cargo-stylus" -version = "0.4.0" +version = "0.4.1" dependencies = [ "cargo-stylus-util", "clap", @@ -643,7 +676,7 @@ dependencies = [ [[package]] name = "cargo-stylus-cgen" -version = "0.4.0" +version = "0.4.1" dependencies = [ "alloy-json-abi", "clap", @@ -654,11 +687,11 @@ dependencies = [ [[package]] name = "cargo-stylus-check" -version = "0.4.0" +version = "0.4.1" dependencies = [ "alloy-ethers-typecast", "alloy-json-abi", - "alloy-primitives 0.7.2", + "alloy-primitives 0.7.7", "alloy-sol-macro", "alloy-sol-types", "brotli2", @@ -677,21 +710,25 @@ dependencies = [ "thiserror", "tiny-keccak", "tokio", + "toml", + "wasm-encoder 0.213.0", + "wasm-gen", "wasmer", + "wasmparser 0.213.0", ] [[package]] name = "cargo-stylus-example" -version = "0.4.0" +version = "0.4.1" dependencies = [ "clap", ] [[package]] name = "cargo-stylus-replay" -version = "0.4.0" +version = "0.4.1" dependencies = [ - "alloy-primitives 0.7.2", + "alloy-primitives 0.7.7", "cargo-stylus-util", "clap", "ethers", @@ -709,7 +746,7 @@ dependencies = [ [[package]] name = "cargo-stylus-util" -version = "0.4.0" +version = "0.4.1" dependencies = [ "ethers", "eyre", @@ -1766,7 +1803,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ - "byteorder", + "byteorder 1.5.0", "rand", "rustc-hex", "static_assertions", @@ -1949,7 +1986,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" dependencies = [ - "byteorder", + "byteorder 1.5.0", ] [[package]] @@ -2045,7 +2082,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash", + "ahash 0.7.7", ] [[package]] @@ -2053,6 +2090,10 @@ name = "hashbrown" version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash 0.8.11", + "serde", +] [[package]] name = "hashers" @@ -2264,6 +2305,7 @@ checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", "hashbrown 0.14.3", + "serde", ] [[package]] @@ -3366,9 +3408,9 @@ dependencies = [ [[package]] name = "ruint" -version = "1.11.1" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608a5726529f2f0ef81b8fde9873c4bb829d6b5b5ca6be4d97345ddf0749c825" +checksum = "2c3cc4c2511671f327125da14133d0c5c5d137f006a1017a16f557bc85b16286" dependencies = [ "alloy-rlp", "ark-ff 0.3.0", @@ -3390,9 +3432,9 @@ dependencies = [ [[package]] name = "ruint-macro" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" [[package]] name = "rustc-demangle" @@ -3674,9 +3716,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" dependencies = [ "serde", ] @@ -3950,9 +3992,9 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.7.2" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa0cefd02f532035d83cfec82647c6eb53140b0485220760e669f4bad489e36" +checksum = "c837dc8852cb7074e46b444afb81783140dab12c58867b49fb3898fbafedf7ea" dependencies = [ "paste", "proc-macro2", @@ -4158,21 +4200,21 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.8" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" +checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.21.0", + "toml_edit 0.22.15", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" dependencies = [ "serde", ] @@ -4204,12 +4246,23 @@ name = "toml_edit" version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +dependencies = [ + "indexmap 2.1.0", + "toml_datetime", + "winnow 0.5.34", +] + +[[package]] +name = "toml_edit" +version = "0.22.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59a3a72298453f564e2b111fa896f8d07fabb36f51f06d7e875fc5e0b5a3ef1" dependencies = [ "indexmap 2.1.0", "serde", "serde_spanned", "toml_datetime", - "winnow 0.5.34", + "winnow 0.6.7", ] [[package]] @@ -4271,7 +4324,7 @@ version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" dependencies = [ - "byteorder", + "byteorder 1.5.0", "bytes", "data-encoding", "http", @@ -4303,7 +4356,7 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" dependencies = [ - "byteorder", + "byteorder 1.5.0", "crunchy", "hex", "static_assertions", @@ -4549,6 +4602,25 @@ dependencies = [ "leb128", ] +[[package]] +name = "wasm-encoder" +version = "0.213.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "850e4e6a56413a8f33567741a2388c8f6dafd841a939d945c7248671a8739dd8" +dependencies = [ + "leb128", +] + +[[package]] +name = "wasm-gen" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b854b1461005a7b3365742310f7faa3cac3add809d66928c64a40c7e9e842ebb" +dependencies = [ + "byteorder 0.5.3", + "leb128", +] + [[package]] name = "wasmer" version = "3.3.0" @@ -4596,7 +4668,7 @@ dependencies = [ "thiserror", "wasmer-types", "wasmer-vm", - "wasmparser", + "wasmparser 0.95.0", "winapi", ] @@ -4684,6 +4756,20 @@ dependencies = [ "url", ] +[[package]] +name = "wasmparser" +version = "0.213.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48e5a90a9e0afc2990437f5600b8de682a32b18cbaaf6f2b5db185352868b6b" +dependencies = [ + "ahash 0.8.11", + "bitflags 2.4.2", + "hashbrown 0.14.3", + "indexmap 2.1.0", + "semver 1.0.21", + "serde", +] + [[package]] name = "wast" version = "70.0.0" @@ -4693,7 +4779,7 @@ dependencies = [ "leb128", "memchr", "unicode-width", - "wasm-encoder", + "wasm-encoder 0.39.0", ] [[package]] @@ -4989,6 +5075,26 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "zeroize" version = "1.7.0" @@ -5016,7 +5122,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" dependencies = [ "aes", - "byteorder", + "byteorder 1.5.0", "bzip2", "constant_time_eq", "crc32fast", diff --git a/Cargo.toml b/Cargo.toml index 55aed5d..4cd4354 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,17 +4,17 @@ resolver = "2" [workspace.package] authors = ["Offchain Labs"] -version = "0.4.0" +version = "0.4.1" edition = "2021" homepage = "https://arbitrum.io" license = "MIT OR Apache-2.0" repository = "https://github.com/OffchainLabs/cargo-stylus" [workspace.dependencies] -alloy-primitives = "0.7.2" -alloy-json-abi = "0.7.2" -alloy-sol-macro = "0.7.2" -alloy-sol-types = "0.7.2" +alloy-primitives = "0.7.6" +alloy-json-abi = "0.7.6" +alloy-sol-macro = "0.7.6" +alloy-sol-types = "0.7.6" alloy-ethers-typecast = "0.2.0" clap = { version = "4.5.4", features = [ "derive", "color" ] } ethers = "2.0.10" @@ -34,4 +34,4 @@ parking_lot = "0.12.1" sneks = "0.1.2" # members -cargo-stylus-util = { path = "util", version = "0.4.0" } +cargo-stylus-util = { path = "util", version = "0.4.1" } diff --git a/check/Cargo.toml b/check/Cargo.toml index c428200..1cd89e4 100644 --- a/check/Cargo.toml +++ b/check/Cargo.toml @@ -33,3 +33,7 @@ tokio.workspace = true wasmer = "3.1.0" glob = "0.3.1" tempfile = "3.10.1" +wasmparser = "0.213.0" +wasm-encoder = "0.213.0" +wasm-gen = "0.1.4" +toml = "0.8.14" diff --git a/check/src/check.rs b/check/src/check.rs index fe3fa0d..f893c9e 100644 --- a/check/src/check.rs +++ b/check/src/check.rs @@ -59,12 +59,22 @@ pub async fn check(cfg: &CheckConfig) -> Result { greyln!("reading wasm file at {}", wasm.to_string_lossy().lavender()); } - let (wasm, code) = project::compress_wasm(&wasm).wrap_err("failed to compress WASM")?; + // Next, we include the project's hash as a custom section + // in the user's WASM so it can be verified by Cargo stylus' + // reproducible verification. This hash is added as a section that is + // ignored by WASM runtimes, so it will only exist in the file + // for metadata purposes. + // add_project_hash_to_wasm_file(wasm, project_hash) + let (wasm_file_bytes, code) = + project::compress_wasm(&wasm, project_hash).wrap_err("failed to compress WASM")?; greyln!("contract size: {}", format_file_size(code.len(), 16, 24)); if verbose { - greyln!("wasm size: {}", format_file_size(wasm.len(), 96, 128)); + greyln!( + "wasm size: {}", + format_file_size(wasm_file_bytes.len(), 96, 128) + ); greyln!("connecting to RPC: {}", &cfg.common_cfg.endpoint.lavender()); } @@ -73,34 +83,23 @@ pub async fn check(cfg: &CheckConfig) -> Result { let codehash = alloy_primitives::keccak256(&code); if program_exists(codehash, &provider).await? { - return Ok(ProgramCheck::Active { code, project_hash }); + return Ok(ProgramCheck::Active { code }); } let address = cfg.program_address.unwrap_or(H160::random()); let fee = check_activate(code.clone().into(), address, &provider).await?; let visual_fee = format_data_fee(fee).unwrap_or("???".red()); greyln!("wasm data fee: {visual_fee}"); - Ok(ProgramCheck::Ready { - code, - fee, - project_hash, - }) + Ok(ProgramCheck::Ready { code, fee }) } /// Whether a program is active, or needs activation. #[derive(PartialEq)] pub enum ProgramCheck { /// Program already exists onchain. - Active { - code: Vec, - project_hash: [u8; 32], - }, + Active { code: Vec }, /// Program can be activated with the given data fee. - Ready { - code: Vec, - fee: U256, - project_hash: [u8; 32], - }, + Ready { code: Vec, fee: U256 }, } impl ProgramCheck { @@ -110,14 +109,6 @@ impl ProgramCheck { Self::Ready { code, .. } => code, } } - - pub fn project_hash(&self) -> &[u8; 32] { - match self { - Self::Active { project_hash, .. } => project_hash, - Self::Ready { project_hash, .. } => project_hash, - } - } - pub fn suggest_fee(&self) -> U256 { match self { Self::Active { .. } => U256::default(), @@ -132,11 +123,9 @@ impl CheckConfig { return Ok((wasm, [0u8; 32])); } let cfg = BuildConfig::new(self.common_cfg.rust_stable); - let project_hash = project::hash_files( - self.common_cfg.source_files_for_project_hash.clone(), - cfg.clone(), - )?; - let wasm = project::build_dylib(cfg)?; + let wasm = project::build_dylib(cfg.clone())?; + let project_hash = + project::hash_files(self.common_cfg.source_files_for_project_hash.clone(), cfg)?; Ok((wasm, project_hash)) } } diff --git a/check/src/constants.rs b/check/src/constants.rs index 25aa4c1..ca30860 100644 --- a/check/src/constants.rs +++ b/check/src/constants.rs @@ -36,3 +36,10 @@ pub const GITHUB_TEMPLATE_REPO_MINIMAL: &str = /// One ether in wei. pub const ONE_ETH: U256 = U256([1000000000000000000, 0, 0, 0]); + +/// Name of the custom wasm section that is added to contracts deployed with cargo stylus +/// to include a hash of the Rust project's source files for reproducible verification of builds. +pub const PROJECT_HASH_SECTION_NAME: &str = "project_hash"; + +/// Name of the toolchain file used to specify the Rust toolchain version for a project. +pub const TOOLCHAIN_FILE_NAME: &str = "rust-toolchain.toml"; diff --git a/check/src/deploy.rs b/check/src/deploy.rs index df54bdd..e8dc8b7 100644 --- a/check/src/deploy.rs +++ b/check/src/deploy.rs @@ -83,9 +83,7 @@ pub async fn deploy(cfg: DeployConfig) -> Result<()> { } } - let contract = cfg - .deploy_contract(program.code(), program.project_hash(), sender, &client) - .await?; + let contract = cfg.deploy_contract(program.code(), sender, &client).await?; match program { ProgramCheck::Ready { .. } => cfg.activate(sender, contract, data_fee, &client).await?, @@ -98,11 +96,10 @@ impl DeployConfig { async fn deploy_contract( &self, code: &[u8], - project_hash: &[u8; 32], sender: H160, client: &SignerClient, ) -> Result { - let init_code = program_deployment_calldata(code, project_hash); + let init_code = program_deployment_calldata(code); let tx = Eip1559TransactionRequest::new() .from(sender) @@ -231,7 +228,7 @@ pub async fn run_tx( } /// Prepares an EVM bytecode prelude for contract creation. -pub fn program_deployment_calldata(code: &[u8], hash: &[u8; 32]) -> Vec { +pub fn program_deployment_calldata(code: &[u8]) -> Vec { let mut code_len = [0u8; 32]; U256::from(code.len()).to_big_endian(&mut code_len); let mut deploy: Vec = vec![]; @@ -239,7 +236,7 @@ pub fn program_deployment_calldata(code: &[u8], hash: &[u8; 32]) -> Vec { deploy.extend(code_len); deploy.push(0x80); // DUP1 deploy.push(0x60); // PUSH1 - deploy.push(42 + 1 + 32); // prelude + version + hash + deploy.push(42 + 1); // prelude + version deploy.push(0x60); // PUSH1 deploy.push(0x00); deploy.push(0x39); // CODECOPY @@ -247,11 +244,24 @@ pub fn program_deployment_calldata(code: &[u8], hash: &[u8; 32]) -> Vec { deploy.push(0x00); deploy.push(0xf3); // RETURN deploy.push(0x00); // version - deploy.extend(hash); deploy.extend(code); deploy } +pub fn extract_program_evm_deployment_prelude(calldata: &[u8]) -> Vec { + // The length of the prelude, version part is 42 + 1 as per the code + let metadata_length = 42 + 1; + // Extract and return the metadata part + calldata[0..metadata_length].to_vec() +} + +pub fn extract_compressed_wasm(calldata: &[u8]) -> Vec { + // The length of the prelude, version part is 42 + 1 as per the code + let metadata_length = 42 + 1; + // Extract and return the metadata part + calldata[metadata_length..].to_vec() +} + pub fn format_gas(gas: U256) -> String { let gas: u64 = gas.try_into().unwrap_or(u64::MAX); let text = format!("{gas} gas"); diff --git a/check/src/docker.rs b/check/src/docker.rs index 1b17e90..5a18e4a 100644 --- a/check/src/docker.rs +++ b/check/src/docker.rs @@ -2,10 +2,14 @@ // For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md use std::io::Write; +use std::path::PathBuf; use std::process::{Command, Stdio}; use eyre::{bail, eyre, Result}; +use crate::constants::TOOLCHAIN_FILE_NAME; +use crate::project::extract_toolchain_channel; + fn version_to_image_name(version: &str) -> String { format!("cargo-stylus-{}", version) } @@ -24,6 +28,8 @@ fn create_image(version: &str) -> Result<()> { if image_exists(&name)? { return Ok(()); } + let toolchain_file_path = PathBuf::from(".").as_path().join(TOOLCHAIN_FILE_NAME); + let toolchain_channel = extract_toolchain_channel(&toolchain_file_path)?; let mut child = Command::new("docker") .arg("build") .arg("-t") @@ -37,15 +43,19 @@ fn create_image(version: &str) -> Result<()> { child.stdin.as_mut().unwrap(), "\ FROM rust:{} as builder\n\ + RUN rustup toolchain install {} && rustup default {} RUN rustup target add wasm32-unknown-unknown RUN rustup target add wasm32-wasi RUN rustup target add aarch64-unknown-linux-gnu + RUN rustup target add x86_64-unknown-linux-gnu RUN cargo install cargo-stylus RUN cargo install --force cargo-stylus-check RUN cargo install --force cargo-stylus-replay RUN cargo install --force cargo-stylus-cgen ", - version + version, + toolchain_channel, + toolchain_channel, )?; child.wait().map_err(|e| eyre!("wait failed: {e}"))?; Ok(()) @@ -76,10 +86,14 @@ fn run_in_docker_container(version: &str, command_line: &[&str]) -> Result<()> { } pub fn run_reproducible(version: &str, command_line: &[String]) -> Result<()> { + let version: String = version + .chars() + .filter(|c| c.is_alphanumeric() || *c == '.') + .collect(); let mut command = vec!["cargo", "stylus"]; for s in command_line.iter() { command.push(s); } - create_image(version)?; - run_in_docker_container(version, &command) + create_image(&version)?; + run_in_docker_container(&version, &command) } diff --git a/check/src/project.rs b/check/src/project.rs index 774499a..eab27f8 100644 --- a/check/src/project.rs +++ b/check/src/project.rs @@ -2,7 +2,10 @@ // For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md use crate::{ - constants::{BROTLI_COMPRESSION_LEVEL, EOF_PREFIX_NO_DICT, RUST_TARGET}, + constants::{ + BROTLI_COMPRESSION_LEVEL, EOF_PREFIX_NO_DICT, PROJECT_HASH_SECTION_NAME, RUST_TARGET, + TOOLCHAIN_FILE_NAME, + }, macros::*, }; use brotli2::read::BrotliEncoder; @@ -18,6 +21,7 @@ use std::{ process, }; use tiny_keccak::{Hasher, Keccak}; +use toml::Value; #[derive(Default, Clone, PartialEq)] pub enum OptLevel { @@ -107,7 +111,8 @@ pub fn build_dylib(cfg: BuildConfig) -> Result { }) .ok_or(BuildError::NoWasmFound { path: release_path })?; - let (wasm, code) = compress_wasm(&wasm_file_path).wrap_err("failed to compress WASM")?; + let (wasm, code) = + compress_wasm(&wasm_file_path, [0u8; 32]).wrap_err("failed to compress WASM")?; greyln!( "contract size: {}", @@ -161,6 +166,32 @@ fn all_paths(root_dir: &Path, source_file_patterns: Vec) -> Result Result { + let toolchain_file_contents = std::fs::read_to_string(toolchain_file_path).wrap_err( + "expected to find a rust-toolchain.toml file in project directory \ + to specify your Rust toolchain for reproducible verification", + )?; + let toolchain_toml: Value = + toml::from_str(&toolchain_file_contents).wrap_err("failed to parse rust-toolchain.toml")?; + + // Extract the channel from the toolchain section + let Some(toolchain) = toolchain_toml.get("toolchain") else { + bail!("toolchain section not found in rust-toolchain.toml"); + }; + let Some(channel) = toolchain.get("channel") else { + bail!("could not find channel in rust-toolchain.toml's toolchain section"); + }; + let Some(channel) = channel.as_str() else { + bail!("channel in rust-toolchain.toml's toolchain section is not a string"); + }; + // Next, parse the Rust version from the toolchain project, only allowing alphanumeric chars and dashes. + let channel = channel + .chars() + .filter(|c| c.is_alphanumeric() || *c == '-' || *c == '.') + .collect(); + Ok(channel) +} + pub fn hash_files(source_file_patterns: Vec, cfg: BuildConfig) -> Result<[u8; 32]> { let mut keccak = Keccak::v256(); let mut cmd = Command::new("cargo"); @@ -201,11 +232,20 @@ pub fn hash_files(source_file_patterns: Vec, cfg: BuildConfig) -> Result Ok(()) }; + // Fetch the Rust toolchain toml file from the project root. Assert that it exists and add it to the + // files in the directory to hash. + let toolchain_file_path = PathBuf::from(".").as_path().join(TOOLCHAIN_FILE_NAME); + let _ = std::fs::metadata(&toolchain_file_path).wrap_err( + "expected to find a rust-toolchain.toml file in project directory \ + to specify your Rust toolchain for reproducible verification", + )?; + let mut paths = all_paths(PathBuf::from(".").as_path(), source_file_patterns)?; + paths.push(toolchain_file_path); paths.sort(); for filename in paths.iter() { - println!( + greyln!( "File used for deployment hash: {}", filename.as_os_str().to_string_lossy() ); @@ -214,7 +254,7 @@ pub fn hash_files(source_file_patterns: Vec, cfg: BuildConfig) -> Result let mut hash = [0u8; 32]; keccak.finalize(&mut hash); - println!( + greyln!( "Project hash computed on deployment: {:?}", hex::encode(hash) ); @@ -235,10 +275,12 @@ fn expand_glob_patterns(patterns: Vec) -> Result> { } /// Reads a WASM file at a specified path and returns its brotli compressed bytes. -pub fn compress_wasm(wasm: &PathBuf) -> Result<(Vec, Vec)> { +pub fn compress_wasm(wasm: &PathBuf, project_hash: [u8; 32]) -> Result<(Vec, Vec)> { let wasm = fs::read(wasm).wrap_err_with(|| eyre!("failed to read Wasm {}", wasm.to_string_lossy()))?; + let wasm = add_project_hash_to_wasm_file(&wasm, project_hash) + .wrap_err("failed to add project hash to wasm file as custom section")?; let wasm = wasmer::wat2wasm(&wasm).wrap_err("failed to parse Wasm")?; let mut compressor = BrotliEncoder::new(&*wasm, BROTLI_COMPRESSION_LEVEL); @@ -253,6 +295,44 @@ pub fn compress_wasm(wasm: &PathBuf) -> Result<(Vec, Vec)> { Ok((wasm.to_vec(), contract_code)) } +// Adds the hash of the project's source files to the wasm as a custom section +// if it does not already exist. This allows for reproducible builds by cargo stylus +// for all Rust stylus programs. See `cargo stylus verify --help` for more information. +fn add_project_hash_to_wasm_file( + wasm_file_bytes: &[u8], + project_hash: [u8; 32], +) -> Result> { + let section_exists = has_project_hash_section(wasm_file_bytes)?; + if section_exists { + greyln!("Wasm file bytes already contains a custom section with a project hash, not overwriting'"); + return Ok(wasm_file_bytes.to_vec()); + } + Ok(add_custom_section(wasm_file_bytes, project_hash)) +} + +pub fn has_project_hash_section(wasm_file_bytes: &[u8]) -> Result { + let parser = wasmparser::Parser::new(0); + for payload in parser.parse_all(wasm_file_bytes) { + if let wasmparser::Payload::CustomSection(reader) = payload? { + if reader.name() == PROJECT_HASH_SECTION_NAME { + println!( + "Found the project hash custom section name {}", + hex::encode(reader.data()) + ); + return Ok(true); + } + } + } + Ok(false) +} + +fn add_custom_section(wasm_file_bytes: &[u8], project_hash: [u8; 32]) -> Vec { + let mut bytes = vec![]; + bytes.extend_from_slice(wasm_file_bytes); + wasm_gen::write_custom_section(&mut bytes, PROJECT_HASH_SECTION_NAME, &project_hash); + bytes +} + #[cfg(test)] mod test { use super::*; @@ -260,6 +340,49 @@ mod test { use std::io::Write; use tempfile::tempdir; + #[test] + fn test_extract_toolchain_channel() -> Result<()> { + let dir = tempdir()?; + let dir_path = dir.path(); + + let toolchain_file_path = dir_path.join(TOOLCHAIN_FILE_NAME); + let toolchain_contents = r#" + [toolchain] + "#; + std::fs::write(&toolchain_file_path, toolchain_contents)?; + + let channel = extract_toolchain_channel(&toolchain_file_path); + let Err(err_details) = channel else { + panic!("expected an error"); + }; + assert!(err_details.to_string().contains("could not find channel"),); + + let toolchain_contents = r#" + [toolchain] + channel = 32390293 + "#; + std::fs::write(&toolchain_file_path, toolchain_contents)?; + + let channel = extract_toolchain_channel(&toolchain_file_path); + let Err(err_details) = channel else { + panic!("expected an error"); + }; + assert!(err_details.to_string().contains("is not a string"),); + + let toolchain_contents = r#" + [toolchain] + channel = "nightly-2020-07-10" + components = [ "rustfmt", "rustc-dev" ] + targets = [ "wasm32-unknown-unknown", "thumbv2-none-eabi" ] + profile = "minimal" + "#; + std::fs::write(&toolchain_file_path, toolchain_contents)?; + + let channel = extract_toolchain_channel(&toolchain_file_path)?; + assert_eq!(channel, "nightly-2020-07-10"); + Ok(()) + } + #[test] fn test_all_paths() -> Result<()> { let dir = tempdir()?; diff --git a/check/src/verify.rs b/check/src/verify.rs index 9cb4faf..f3e0ca0 100644 --- a/check/src/verify.rs +++ b/check/src/verify.rs @@ -12,7 +12,11 @@ use ethers::types::H256; use serde::{Deserialize, Serialize}; -use crate::{check, deploy, project, CheckConfig, VerifyConfig}; +use crate::{ + check, + deploy::{self, extract_compressed_wasm, extract_program_evm_deployment_prelude}, + project, CheckConfig, VerifyConfig, +}; use cargo_stylus_util::{color::Color, sys}; #[derive(Debug, Deserialize, Serialize)] @@ -55,16 +59,37 @@ pub async fn verify(cfg: VerifyConfig) -> eyre::Result<()> { }; let wasm_file: PathBuf = project::build_dylib(build_cfg.clone()) .map_err(|e| eyre!("could not build project to WASM: {e}"))?; - let (_, init_code) = project::compress_wasm(&wasm_file)?; - let hash = project::hash_files(cfg.common_cfg.source_files_for_project_hash, build_cfg)?; - let deployment_data = deploy::program_deployment_calldata(&init_code, &hash); + let project_hash = + project::hash_files(cfg.common_cfg.source_files_for_project_hash, build_cfg)?; + let (_, init_code) = project::compress_wasm(&wasm_file, project_hash)?; + let deployment_data = deploy::program_deployment_calldata(&init_code); if deployment_data == *result.input { println!("Verified - program matches local project's file hashes"); } else { + let tx_prelude = extract_program_evm_deployment_prelude(&*result.input); + let reconstructed_prelude = extract_program_evm_deployment_prelude(&deployment_data); println!( "{} - program deployment did not verify against local project's file hashes", "FAILED".red() ); + if tx_prelude != reconstructed_prelude { + println!("Prelude mismatch"); + println!("Deployment tx prelude {}", hex::encode(tx_prelude)); + println!( + "Reconstructed prelude {}", + hex::encode(reconstructed_prelude) + ); + } else { + println!("Compressed WASM bytecode mismatch"); + } + println!( + "Compressed code length of locally reconstructed {}", + init_code.len() + ); + println!( + "Compressed code length of deployment tx {}", + extract_compressed_wasm(&*result.input).len() + ); } Ok(()) } From 938b1564024730ddf0d174dc1807c8e94dec8920 Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Thu, 25 Jul 2024 13:04:06 -0500 Subject: [PATCH 20/35] Update Deps And Cargo Stylus Cache With Latest Contract ABI (#58) * cache updates working * arg comment * cargo update deps --- Cargo.lock | 1017 +++++++++++++++++++--------------------- check/src/cache.rs | 31 +- check/src/constants.rs | 5 - check/src/main.rs | 5 +- 4 files changed, 502 insertions(+), 556 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e16de6c..f536651 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,11 +14,11 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ - "gimli 0.28.1", + "gimli 0.29.0", ] [[package]] @@ -29,9 +29,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aes" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", @@ -40,9 +40,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom", "once_cell", @@ -63,9 +63,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -138,9 +138,9 @@ dependencies = [ [[package]] name = "alloy-rlp" -version = "0.3.4" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d58d9f5da7b40e9bfff0b7e7816700be4019db97d4b6359fe7f94a9e22e42ac" +checksum = "a43b18702501396fa9bcdeecd533bc85fac75150d308fc0f6800a01e6234a003" dependencies = [ "arrayvec", "bytes", @@ -157,7 +157,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -168,12 +168,12 @@ checksum = "867a5469d61480fea08c7333ffeca52d5b621f5ca2e44f271b117ec1fc9a0525" dependencies = [ "alloy-sol-macro-input", "const-hex", - "heck 0.5.0", - "indexmap 2.1.0", + "heck", + "indexmap 2.2.6", "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", "syn-solidity", "tiny-keccak", ] @@ -186,10 +186,10 @@ checksum = "2e482dc33a32b6fadbc0f599adea520bd3aaa585c141a80b404d0a3e3fa72528" dependencies = [ "const-hex", "dunce", - "heck 0.5.0", + "heck", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", "syn-solidity", ] @@ -200,7 +200,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cbcba3ca07cf7975f15d871b721fb18031eec8bce51103907f6dcce00b255d98" dependencies = [ "serde", - "winnow 0.6.7", + "winnow 0.6.15", ] [[package]] @@ -217,47 +217,48 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.11" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -404,13 +405,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -426,27 +427,26 @@ dependencies = [ [[package]] name = "auto_impl" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ - "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.72", ] [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", @@ -510,9 +510,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bitvec" @@ -557,9 +557,9 @@ dependencies = [ [[package]] name = "bs58" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" dependencies = [ "sha2", "tinyvec", @@ -567,9 +567,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byte-slice-cast" @@ -579,9 +579,9 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytecheck" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" dependencies = [ "bytecheck_derive", "ptr_meta", @@ -590,9 +590,9 @@ dependencies = [ [[package]] name = "bytecheck_derive" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" dependencies = [ "proc-macro2", "quote", @@ -613,9 +613,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" dependencies = [ "serde", ] @@ -649,18 +649,18 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" dependencies = [ "serde", ] [[package]] name = "cargo-platform" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" dependencies = [ "serde", ] @@ -762,7 +762,7 @@ checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" dependencies = [ "camino", "cargo-platform", - "semver 1.0.21", + "semver 1.0.23", "serde", "serde_json", "thiserror", @@ -770,9 +770,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" dependencies = [ "jobserver", "libc", @@ -786,9 +786,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "num-traits", ] @@ -805,9 +805,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.4" +version = "4.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "35723e6a11662c2afb578bcf0b88bf6ea8e21282a953428f240574fcc3a2b5b3" dependencies = [ "clap_builder", "clap_derive", @@ -815,9 +815,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "49eb96cbfa7cfa35017b7cd548c75b14c3118c98b423041d70562665e07fb0fa" dependencies = [ "anstream", "anstyle", @@ -827,21 +827,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.4" +version = "4.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +checksum = "5d029b67f89d30bbb547c89fd5161293c0aec155fc691d7924b64550662db93e" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "coins-bip32" @@ -897,15 +897,15 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "const-hex" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557" +checksum = "94fb8a24a26d37e1ffd45343323dc9fe6654ceea44c12f2fcb3d7ac29e610bc6" dependencies = [ "cfg-if", "cpufeatures", @@ -1064,9 +1064,9 @@ checksum = "393bc73c451830ff8dbb3a07f61843d6cb41a084f9996319917c0b291ed785bb" [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] @@ -1092,9 +1092,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crunchy" @@ -1135,9 +1135,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.3" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ "darling_core", "darling_macro", @@ -1145,26 +1145,26 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.3" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "darling_macro" -version = "0.20.3" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -1174,7 +1174,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "lock_api", "once_cell", "parking_lot_core", @@ -1182,15 +1182,15 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "zeroize", @@ -1218,23 +1218,17 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case 0.4.0", "proc-macro2", "quote", "rustc_version 0.4.0", - "syn 1.0.109", + "syn 2.0.72", ] -[[package]] -name = "diff" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" - [[package]] name = "digest" version = "0.9.0" @@ -1320,9 +1314,9 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "elliptic-curve" @@ -1345,27 +1339,27 @@ dependencies = [ [[package]] name = "ena" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1" +checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" dependencies = [ "log", ] [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] [[package]] name = "enr" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe81b5c06ecfdbc71dd845216f225f53b62a10cb8a16c946836a3467f701d05b" +checksum = "2a3d8dc56e02f954cac8eb489772c552c473346fc34f67412bb6244fd647f7e4" dependencies = [ "base64 0.21.7", "bytes", @@ -1401,23 +1395,23 @@ dependencies = [ [[package]] name = "enumset" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" +checksum = "d07a4b049558765cef5f0c1a273c3fc57084d768b44d2f98127aef4cceb17293" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" -version = "0.8.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" +checksum = "59c3b24c345d8c314966bdc1832f6c2635bfcce8e7cf363bd115987bba2ee242" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -1428,9 +1422,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1508,9 +1502,9 @@ dependencies = [ [[package]] name = "ethers" -version = "2.0.11" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5344eea9b20effb5efeaad29418215c4d27017639fd1f908260f59cbbd226e" +checksum = "816841ea989f0c69e459af1cf23a6b0033b19a55424a1ea3a30099becdb8dec0" dependencies = [ "ethers-addressbook", "ethers-contract", @@ -1524,9 +1518,9 @@ dependencies = [ [[package]] name = "ethers-addressbook" -version = "2.0.12" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bf35eb7d2e2092ad41f584951e08ec7c077b142dba29c4f1b8f52d2efddc49c" +checksum = "5495afd16b4faa556c3bba1f21b98b4983e53c1755022377051a975c3b021759" dependencies = [ "ethers-core", "once_cell", @@ -1536,9 +1530,9 @@ dependencies = [ [[package]] name = "ethers-contract" -version = "2.0.11" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0111ead599d17a7bff6985fd5756f39ca7033edc79a31b23026a8d5d64fa95cd" +checksum = "6fceafa3578c836eeb874af87abacfb041f92b4da0a78a5edd042564b8ecdaaa" dependencies = [ "const-hex", "ethers-contract-abigen", @@ -1555,9 +1549,9 @@ dependencies = [ [[package]] name = "ethers-contract-abigen" -version = "2.0.12" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbdfb952aafd385b31d316ed80d7b76215ce09743c172966d840e96924427e0c" +checksum = "04ba01fbc2331a38c429eb95d4a570166781f14290ef9fdb144278a90b5a739b" dependencies = [ "Inflector", "const-hex", @@ -1572,16 +1566,16 @@ dependencies = [ "reqwest", "serde", "serde_json", - "syn 2.0.48", + "syn 2.0.72", "toml", "walkdir", ] [[package]] name = "ethers-contract-derive" -version = "2.0.12" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7465c814a2ecd0de0442160da13584205d1cdc08f4717a6511cad455bd5d7dc4" +checksum = "87689dcabc0051cde10caaade298f9e9093d65f6125c14575db3fd8c669a168f" dependencies = [ "Inflector", "const-hex", @@ -1590,14 +1584,14 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "ethers-core" -version = "2.0.12" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "918b1a9ba585ea61022647def2f27c29ba19f6d2a4a4c8f68a9ae97fd5769737" +checksum = "82d80cc6ad30b14a48ab786523af33b37f28a8623fc06afd55324816ef18fb1f" dependencies = [ "arrayvec", "bytes", @@ -1616,7 +1610,7 @@ dependencies = [ "serde", "serde_json", "strum", - "syn 2.0.48", + "syn 2.0.72", "tempfile", "thiserror", "tiny-keccak", @@ -1625,14 +1619,14 @@ dependencies = [ [[package]] name = "ethers-etherscan" -version = "2.0.12" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "facabf8551b4d1a3c08cb935e7fca187804b6c2525cc0dafb8e5a6dd453a24de" +checksum = "e79e5973c26d4baf0ce55520bd732314328cabe53193286671b47144145b9649" dependencies = [ "chrono", "ethers-core", "reqwest", - "semver 1.0.21", + "semver 1.0.23", "serde", "serde_json", "thiserror", @@ -1641,9 +1635,9 @@ dependencies = [ [[package]] name = "ethers-middleware" -version = "2.0.11" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681ece6eb1d10f7cf4f873059a77c04ff1de4f35c63dd7bccde8f438374fcb93" +checksum = "48f9fdf09aec667c099909d91908d5eaf9be1bd0e2500ba4172c1d28bfaa43de" dependencies = [ "async-trait", "auto_impl", @@ -1668,9 +1662,9 @@ dependencies = [ [[package]] name = "ethers-providers" -version = "2.0.11" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25d6c0c9455d93d4990c06e049abf9b30daf148cf461ee939c11d88907c60816" +checksum = "6434c9a33891f1effc9c75472e12666db2fa5a0fec4b29af6221680a6fe83ab2" dependencies = [ "async-trait", "auto_impl", @@ -1705,9 +1699,9 @@ dependencies = [ [[package]] name = "ethers-signers" -version = "2.0.11" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb1b714e227bbd2d8c53528adb580b203009728b17d0d0e4119353aa9bc5532" +checksum = "228875491c782ad851773b652dd8ecac62cda8571d3bc32a5853644dd26766c2" dependencies = [ "async-trait", "coins-bip32", @@ -1724,9 +1718,9 @@ dependencies = [ [[package]] name = "ethers-solc" -version = "2.0.12" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2e46e3ec8ef0c986145901fa9864205dc4dcee701f9846be2d56112d34bdea" +checksum = "66244a771d9163282646dbeffe0e6eca4dda4146b6498644e678ac6089b11edd" dependencies = [ "cfg-if", "const-hex", @@ -1741,7 +1735,7 @@ dependencies = [ "path-slash", "rayon", "regex", - "semver 1.0.21", + "semver 1.0.23", "serde", "serde_json", "solang-parser", @@ -1756,9 +1750,9 @@ dependencies = [ [[package]] name = "eyre" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ "indenter", "once_cell", @@ -1772,9 +1766,9 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fastrlp" @@ -1817,9 +1811,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "miniz_oxide", @@ -1937,7 +1931,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -1954,9 +1948,9 @@ checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-timer" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" dependencies = [ "gloo-timers", "send_wrapper 0.4.0", @@ -2002,9 +1996,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -2024,9 +2018,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "glob" @@ -2059,9 +2053,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.24" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", @@ -2069,7 +2063,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.1.0", + "indexmap 2.2.6", "slab", "tokio", "tokio-util", @@ -2082,14 +2076,14 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash 0.7.7", + "ahash 0.7.8", ] [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash 0.8.11", "serde", @@ -2104,12 +2098,6 @@ dependencies = [ "fxhash", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -2118,9 +2106,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.4" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -2157,9 +2145,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -2179,9 +2167,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -2191,9 +2179,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.28" +version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ "bytes", "futures-channel", @@ -2299,12 +2287,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "serde", ] @@ -2319,9 +2307,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -2333,15 +2321,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] -name = "is-terminal" -version = "0.4.10" +name = "is_terminal_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys 0.52.0", -] +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" @@ -2363,24 +2346,24 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -2424,9 +2407,9 @@ dependencies = [ [[package]] name = "keccak-asm" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb8515fff80ed850aea4a1595f2e519c003e2a00a82fe168ebf5269196caf444" +checksum = "47a3633291834c4fbebf8673acbc1b04ec9d151418ff9b8e26dcd79129928758" dependencies = [ "digest 0.10.7", "sha3-asm", @@ -2434,37 +2417,39 @@ dependencies = [ [[package]] name = "lalrpop" -version = "0.20.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da4081d44f4611b66c6dd725e6de3169f9f63905421e8626fcb86b6a898998b8" +checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" dependencies = [ "ascii-canvas", "bit-set", - "diff", "ena", - "is-terminal", - "itertools 0.10.5", + "itertools 0.11.0", "lalrpop-util", "petgraph", "regex", - "regex-syntax 0.7.5", + "regex-syntax", "string_cache", "term", "tiny-keccak", "unicode-xid", + "walkdir", ] [[package]] name = "lalrpop-util" -version = "0.20.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f35c735096c0293d313e8f2a641627472b83d01b937177fe76e5e2708d31e0d" +checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" +dependencies = [ + "regex-automata", +] [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "leb128" @@ -2480,12 +2465,12 @@ checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libloading" -version = "0.8.1" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-sys 0.48.0", + "windows-targets 0.52.6", ] [[package]] @@ -2496,26 +2481,25 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libredox" -version = "0.0.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "libc", - "redox_syscall", ] [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -2523,9 +2507,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "mach" @@ -2536,6 +2520,15 @@ dependencies = [ "libc", ] +[[package]] +name = "mach2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +dependencies = [ + "libc", +] + [[package]] name = "md-5" version = "0.10.6" @@ -2548,9 +2541,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memmap2" @@ -2578,22 +2571,23 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.10" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" dependencies = [ + "hermit-abi", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2604,36 +2598,40 @@ checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" [[package]] name = "new_debug_unreachable" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -2664,17 +2662,17 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "object" -version = "0.32.2" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e" dependencies = [ "memchr", ] @@ -2718,9 +2716,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "parity-scale-codec" -version = "3.6.9" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ "arrayvec", "bitvec", @@ -2732,11 +2730,11 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.9" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate 2.0.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", @@ -2744,9 +2742,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -2754,15 +2752,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -2778,9 +2776,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "path-slash" @@ -2827,9 +2825,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.6" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" +checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" dependencies = [ "memchr", "thiserror", @@ -2838,12 +2836,12 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.1.0", + "indexmap 2.2.6", ] [[package]] @@ -2886,7 +2884,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -2909,29 +2907,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -2951,9 +2949,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "powerfmt" @@ -2975,12 +2973,12 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "prettyplease" -version = "0.2.16" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -2997,32 +2995,13 @@ dependencies = [ "uint", ] -[[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 0.19.15", -] - -[[package]] -name = "proc-macro-crate" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" -dependencies = [ - "toml_edit 0.20.7", -] - [[package]] name = "proc-macro-crate" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ - "toml_edit 0.21.0", + "toml_edit 0.21.1", ] [[package]] @@ -3051,28 +3030,28 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "proptest" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.4.2", + "bitflags 2.6.0", "lazy_static", "num-traits", "rand", "rand_chacha", "rand_xorshift", - "regex-syntax 0.8.2", + "regex-syntax", "rusty-fork", "tempfile", "unarray", @@ -3106,9 +3085,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -3160,9 +3139,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -3180,18 +3159,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", ] [[package]] name = "redox_users" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ "getrandom", "libredox", @@ -3212,65 +3191,59 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", "regex-automata", - "regex-syntax 0.8.2", + "regex-syntax", ] [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.7.5" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - -[[package]] -name = "regex-syntax" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "region" -version = "3.0.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76e189c2369884dce920945e2ddf79b3dff49e071a167dd1817fa9c4c00d512e" +checksum = "e6b6ebd13bc009aef9cd476c1310d49ac354d36e240cf1bd753290f3dc7199a7" dependencies = [ "bitflags 1.3.2", "libc", - "mach", - "winapi", + "mach2", + "windows-sys 0.52.0", ] [[package]] name = "rend" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" dependencies = [ "bytecheck", ] [[package]] name = "reqwest" -version = "0.11.23" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "base64 0.21.7", "bytes", @@ -3294,6 +3267,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", "system-configuration", "tokio", "tokio-rustls", @@ -3333,16 +3307,17 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", "getrandom", "libc", "spin 0.9.8", "untrusted 0.9.0", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -3356,9 +3331,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.7.43" +version = "0.7.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527a97cdfef66f65998b5f3b637c26f5a5ec09cc52a3f9932313ac645f4190f5" +checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" dependencies = [ "bitvec", "bytecheck", @@ -3370,14 +3345,14 @@ dependencies = [ "rkyv_derive", "seahash", "tinyvec", - "uuid 1.7.0", + "uuid 1.10.0", ] [[package]] name = "rkyv_derive" -version = "0.7.43" +version = "0.7.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5c462a1328c8e67e4d6dbad1eb0355dd43e8ab432c6e227a43657f16ade5033" +checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" dependencies = [ "proc-macro2", "quote", @@ -3438,9 +3413,9 @@ checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hex" @@ -3472,7 +3447,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.21", + "semver 1.0.23", ] [[package]] @@ -3481,7 +3456,7 @@ version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -3490,12 +3465,12 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", - "ring 0.17.7", + "ring 0.17.8", "rustls-webpki", "sct", ] @@ -3515,15 +3490,15 @@ version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "untrusted 0.9.0", ] [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "rusty-fork" @@ -3539,9 +3514,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "salsa20" @@ -3563,9 +3538,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.10.0" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7d66a1128282b7ef025a8ead62a4a9fcf017382ec53b8ffbf4d7bf77bd3c60" +checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" dependencies = [ "cfg-if", "derive_more", @@ -3575,11 +3550,11 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.10.0" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf2c68b89cafb3b8d918dd07b42be0da66ff202cf1155c5739a4e0c1ea0dc19" +checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", @@ -3609,7 +3584,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "untrusted 0.9.0", ] @@ -3644,9 +3619,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] @@ -3674,9 +3649,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] @@ -3694,20 +3669,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "serde_json" -version = "1.0.111" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", @@ -3769,9 +3744,9 @@ dependencies = [ [[package]] name = "sha3-asm" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac61da6b35ad76b195eb4771210f947734321a8d81d7738e1580d953bc7a15e" +checksum = "a9b57fd861253bff08bb1919e995f90ba8f4889de2726091c8876f3a4e823b40" dependencies = [ "cc", "cfg-if", @@ -3828,29 +3803,29 @@ checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" [[package]] name = "smallvec" -version = "1.13.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b187f0231d56fe41bfb12034819dd2bf336422a5866de41bc3fec4b2e3883e8" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "sneks" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1754a9953937d149fb279d362241e4b92c4f237a491f4524835e8e78dd43810d" +checksum = "9659a8ce0c2f862add056dc8f43cb481176298f1df141ca16ea4d1fe3e6c8ad7" dependencies = [ "convert_case 0.6.0", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -3922,44 +3897,44 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" -version = "0.25.0" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" -version = "0.25.3" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "quote", "rustversion", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "svm-rs" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20689c7d03b6461b502d0b95d6c24874c7d24dea2688af80486a130a06af3b07" +checksum = "11297baafe5fa0c99d5722458eac6a5e25c01eb1b8e5cd137f54079093daa7a4" dependencies = [ "dirs", "fs2", "hex", "once_cell", "reqwest", - "semver 1.0.21", + "semver 1.0.23", "serde", "serde_json", "sha2", @@ -3981,9 +3956,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", @@ -3999,9 +3974,15 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "system-configuration" version = "0.5.1" @@ -4031,9 +4012,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-lexicon" -version = "0.12.13" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69758bda2e78f098e4ccb393021a0963bb3442eac05f135c30f61b7370bbafae" +checksum = "4873307b7c257eddcb50c9bedf158eb669578359fb28428bef438fec8e6ba7c2" [[package]] name = "tempfile" @@ -4060,32 +4041,33 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "time" -version = "0.3.31" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", @@ -4100,10 +4082,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] @@ -4118,9 +4101,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -4133,30 +4116,29 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.1" +version = "1.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "d040ac2b29ab03b09d4129c2f5bbd012a3ac2f79d38ff506a4bf8dd34b0eac8a" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "pin-project-lite", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -4186,28 +4168,27 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] name = "toml" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" +checksum = "ac2caab0bf757388c6c0ae23b3293fdb463fee59434529014f85e3263b995c28" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.15", + "toml_edit 0.22.16", ] [[package]] @@ -4221,48 +4202,26 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.6", "toml_datetime", - "winnow 0.5.34", + "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.20.7" +version = "0.22.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788" dependencies = [ - "indexmap 2.1.0", - "toml_datetime", - "winnow 0.5.34", -] - -[[package]] -name = "toml_edit" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" -dependencies = [ - "indexmap 2.1.0", - "toml_datetime", - "winnow 0.5.34", -] - -[[package]] -name = "toml_edit" -version = "0.22.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59a3a72298453f564e2b111fa896f8d07fabb36f51f06d7e875fc5e0b5a3ef1" -dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.7", + "winnow 0.6.15", ] [[package]] @@ -4290,7 +4249,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -4382,24 +4341,24 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unicode-xid" @@ -4421,9 +4380,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -4438,9 +4397,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" @@ -4454,9 +4413,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.7.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" [[package]] name = "valuable" @@ -4481,9 +4440,9 @@ dependencies = [ [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -4506,9 +4465,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -4516,16 +4475,16 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", "wasm-bindgen-shared", ] @@ -4554,9 +4513,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.40" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -4566,9 +4525,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4576,37 +4535,37 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wasm-encoder" -version = "0.39.0" +version = "0.213.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "111495d6204760238512f57a9af162f45086504da332af210f2f75dd80b34f1d" +checksum = "850e4e6a56413a8f33567741a2388c8f6dafd841a939d945c7248671a8739dd8" dependencies = [ "leb128", ] [[package]] name = "wasm-encoder" -version = "0.213.0" +version = "0.214.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "850e4e6a56413a8f33567741a2388c8f6dafd841a939d945c7248671a8739dd8" +checksum = "ff694f02a8d7a50b6922b197ae03883fbf18cdb2ae9fbee7b6148456f5f44041" dependencies = [ "leb128", ] @@ -4763,39 +4722,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48e5a90a9e0afc2990437f5600b8de682a32b18cbaaf6f2b5db185352868b6b" dependencies = [ "ahash 0.8.11", - "bitflags 2.4.2", - "hashbrown 0.14.3", - "indexmap 2.1.0", - "semver 1.0.21", + "bitflags 2.6.0", + "hashbrown 0.14.5", + "indexmap 2.2.6", + "semver 1.0.23", "serde", ] [[package]] name = "wast" -version = "70.0.0" +version = "214.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee4bc54bbe1c6924160b9f75e374a1d07532e7580eb632c0ee6cdd109bb217e" +checksum = "694bcdb24c49c8709bd8713768b71301a11e823923eee355d530f1d8d0a7f8e9" dependencies = [ + "bumpalo", "leb128", "memchr", "unicode-width", - "wasm-encoder 0.39.0", + "wasm-encoder 0.214.0", ] [[package]] name = "wat" -version = "1.0.83" +version = "1.214.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f0dce8cdc288c717cf01e461a1e451a7b8445d53451123536ba576e423a101a" +checksum = "347249eb56773fa728df2656cfe3a8c19437ded61a922a0b5e0839d9790e278e" dependencies = [ "wast", ] [[package]] name = "web-sys" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -4803,9 +4763,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.3" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "winapi" @@ -4825,11 +4785,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -4866,7 +4826,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -4886,17 +4846,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -4907,9 +4868,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -4925,9 +4886,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -4943,9 +4904,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -4961,9 +4928,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -4979,9 +4946,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -4991,9 +4958,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -5009,24 +4976,24 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.5.34" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] [[package]] name = "winnow" -version = "0.6.7" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14b9415ee827af173ebb3f15f9083df5a122eb93572ec28741fb153356ea2578" +checksum = "557404e450152cd6795bb558bca69e43c585055f4606e3bcae5894fc6dac9ba0" dependencies = [ "memchr", ] @@ -5092,14 +5059,14 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] @@ -5112,7 +5079,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.72", ] [[package]] @@ -5156,9 +5123,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" +version = "2.0.12+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +checksum = "0a4e40c320c3cb459d9a9ff6de98cff88f4751ee9275d140e2be94a2b74e4c13" dependencies = [ "cc", "pkg-config", diff --git a/check/src/cache.rs b/check/src/cache.rs index ab6899d..dddaf11 100644 --- a/check/src/cache.rs +++ b/check/src/cache.rs @@ -1,7 +1,7 @@ // Copyright 2023-2024, Offchain Labs, Inc. // For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/stylus/licenses/COPYRIGHT.md -use alloy_primitives::FixedBytes; +use alloy_primitives::Address; use alloy_sol_macro::sol; use alloy_sol_types::{SolCall, SolInterface}; use cargo_stylus_util::color::{Color, DebugColor}; @@ -10,18 +10,16 @@ use ethers::middleware::{Middleware, SignerMiddleware}; use ethers::signers::Signer; use ethers::types::spoof::State; use ethers::types::{Eip1559TransactionRequest, U256}; -use ethers::utils::keccak256; use eyre::{bail, Context, Result}; use crate::check::{eth_call, EthCallError}; -use crate::constants::{CACHE_MANAGER_H160, EOF_PREFIX_NO_DICT}; use crate::deploy::{format_gas, run_tx}; use crate::macros::greyln; use crate::CacheConfig; sol! { interface CacheManager { - function placeBid(bytes32 codehash) external payable; + function placeBid(address program) external payable; error AsmTooLarge(uint256 asm, uint256 queueSize, uint256 cacheSize); error AlreadyCached(bytes32 codehash); @@ -41,27 +39,10 @@ pub async fn cache_program(cfg: &CacheConfig) -> Result<()> { let wallet = wallet.with_chain_id(chain_id.as_u64()); let client = SignerMiddleware::new(provider.clone(), wallet); - let program_code = client - .get_code(cfg.program_address, None) - .await - .wrap_err("failed to fetch program code")?; - - if !program_code.starts_with(hex::decode(EOF_PREFIX_NO_DICT).unwrap().as_slice()) { - bail!( - "program code does not start with Stylus prefix {}", - EOF_PREFIX_NO_DICT - ); - } - let codehash = FixedBytes::<32>::from(keccak256(&program_code)); - greyln!( - "Program codehash {}", - hex::encode(codehash).debug_lavender() - ); - let codehash = FixedBytes::<32>::from(keccak256(&program_code)); - - let data = CacheManager::placeBidCall { codehash }.abi_encode(); + let program: Address = cfg.address.to_fixed_bytes().into(); + let data = CacheManager::placeBidCall { program }.abi_encode(); let mut tx = Eip1559TransactionRequest::new() - .to(*CACHE_MANAGER_H160) + .to(cfg.cache_manager_address) .data(data); // If a bid is set, specify it. Otherwise, a zero bid will be sent. @@ -100,7 +81,7 @@ pub async fn cache_program(cfg: &CacheConfig) -> Result<()> { ) .await?; - let address = cfg.program_address.debug_lavender(); + let address = cfg.address.debug_lavender(); if verbose { let gas = format_gas(receipt.gas_used.unwrap_or_default()); diff --git a/check/src/constants.rs b/check/src/constants.rs index ca30860..2bc3492 100644 --- a/check/src/constants.rs +++ b/check/src/constants.rs @@ -14,16 +14,11 @@ pub const BROTLI_COMPRESSION_LEVEL: u32 = 11; lazy_static! { /// Address of the ArbWasm precompile. pub static ref ARB_WASM_H160: H160 = H160(*ARB_WASM_ADDRESS.0); - /// Address of the Stylus program cache manager. - pub static ref CACHE_MANAGER_H160: H160 = H160(*CACHE_MANAGER_ADDRESS.0); } /// Address of the ArbWasm precompile. pub const ARB_WASM_ADDRESS: Address = address!("0000000000000000000000000000000000000071"); -/// Address of the Stylus program cache manager for Arbitrum chains. -pub const CACHE_MANAGER_ADDRESS: Address = address!("d1bbd579988f394a26d6ec16e77b3fa8a5e8fcee"); - /// Target for compiled WASM folder in a Rust project pub const RUST_TARGET: &str = "wasm32-unknown-unknown"; diff --git a/check/src/main.rs b/check/src/main.rs index 2a3b097..5d6adb3 100644 --- a/check/src/main.rs +++ b/check/src/main.rs @@ -107,7 +107,10 @@ pub struct CacheConfig { auth: AuthOpts, /// Deployed and activated program address to cache. #[arg(long)] - program_address: H160, + address: H160, + /// Address of the Stylus program cache manager on Arbitrum chains. + #[arg(long, default_value = "0c9043d042ab52cfa8d0207459260040cca54253")] + cache_manager_address: H160, /// Bid, in wei, to place on the desired program to cache #[arg(short, long, hide(true))] bid: Option, From a4679a17b91cfc22d63733f64462025dc2b955ce Mon Sep 17 00:00:00 2001 From: Joe Wanga <66113453+joewnga@users.noreply.github.com> Date: Fri, 26 Jul 2024 20:18:41 +0300 Subject: [PATCH 21/35] Fix: Ensure --version flag works correctly for cargo stylus (#55) * Fix: Ensure --version flag works correctly for cargo stylus - Resolved duplication of command 'check' alias 'c' * added documentation comments for the help and version info functions * Apply suggestions from code review --------- Co-authored-by: Raul Jordan --- main/src/main.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/main/src/main.rs b/main/src/main.rs index 7ffa008..43da340 100644 --- a/main/src/main.rs +++ b/main/src/main.rs @@ -2,7 +2,7 @@ // For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md use cargo_stylus_util::{color::Color, sys}; -use clap::Parser; +use clap::{CommandFactory, Parser}; use eyre::{bail, Result}; // Conditional import for Unix-specific `CommandExt` @@ -34,7 +34,6 @@ enum Subcommands { /// Export a Solidity ABI. ExportAbi, /// Cache a contract. - #[command(alias = "c")] Cache, /// Check a contract. #[command(alias = "c")] @@ -101,14 +100,16 @@ const COMMANDS: &[Binary] = &[ }, ]; +// prints help message and exits fn exit_with_help_msg() -> ! { - Opts::parse_from(["--help"]); - unreachable!() + Opts::command().print_help().unwrap(); + std::process::exit(0); } +// prints version information and exits fn exit_with_version() -> ! { - Opts::parse_from(["--version"]); - unreachable!() + println!("{}", Opts::command().render_version()); + std::process::exit(0); } fn main() -> Result<()> { From 2465c89c823a03eb7e36caeccd81d11d293b7426 Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Fri, 26 Jul 2024 12:39:39 -0500 Subject: [PATCH 22/35] cache improvements --- check/src/cache.rs | 24 ++++++++++++++++++++++-- check/src/constants.rs | 5 +++++ check/src/deploy.rs | 3 +++ check/src/main.rs | 3 --- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/check/src/cache.rs b/check/src/cache.rs index dddaf11..b270587 100644 --- a/check/src/cache.rs +++ b/check/src/cache.rs @@ -9,15 +9,20 @@ use cargo_stylus_util::sys; use ethers::middleware::{Middleware, SignerMiddleware}; use ethers::signers::Signer; use ethers::types::spoof::State; -use ethers::types::{Eip1559TransactionRequest, U256}; +use ethers::types::transaction::eip2718::TypedTransaction; +use ethers::types::{Eip1559TransactionRequest, H160, U256}; use eyre::{bail, Context, Result}; use crate::check::{eth_call, EthCallError}; +use crate::constants::ARB_WASM_CACHE_H160; use crate::deploy::{format_gas, run_tx}; use crate::macros::greyln; use crate::CacheConfig; sol! { + interface ArbWasmCache { + function allCacheManagers() external view returns (address[] memory managers); + } interface CacheManager { function placeBid(address program) external payable; @@ -39,10 +44,25 @@ pub async fn cache_program(cfg: &CacheConfig) -> Result<()> { let wallet = wallet.with_chain_id(chain_id.as_u64()); let client = SignerMiddleware::new(provider.clone(), wallet); + let data = ArbWasmCache::allCacheManagersCall {}.abi_encode(); + let tx = Eip1559TransactionRequest::new() + .to(*ARB_WASM_CACHE_H160) + .data(data); + let tx = TypedTransaction::Eip1559(tx); + let result = client.call(&tx, None).await?; + let cache_managers_result = + ArbWasmCache::allCacheManagersCall::abi_decode_returns(&result, true)?; + let cache_manager_addrs = cache_managers_result.managers; + if cache_manager_addrs.is_empty() { + bail!("no cache managers found in ArbWasmCache, perhaps the Stylus cache is not yet enabled on this chain"); + } + let cache_manager = cache_manager_addrs.last().unwrap().clone(); + let cache_manager = H160::from_slice(cache_manager.as_slice()); + let program: Address = cfg.address.to_fixed_bytes().into(); let data = CacheManager::placeBidCall { program }.abi_encode(); let mut tx = Eip1559TransactionRequest::new() - .to(cfg.cache_manager_address) + .to(cache_manager) .data(data); // If a bid is set, specify it. Otherwise, a zero bid will be sent. diff --git a/check/src/constants.rs b/check/src/constants.rs index 2bc3492..b564876 100644 --- a/check/src/constants.rs +++ b/check/src/constants.rs @@ -14,11 +14,16 @@ pub const BROTLI_COMPRESSION_LEVEL: u32 = 11; lazy_static! { /// Address of the ArbWasm precompile. pub static ref ARB_WASM_H160: H160 = H160(*ARB_WASM_ADDRESS.0); + /// Address of the ArbWasmCache precompile. + pub static ref ARB_WASM_CACHE_H160: H160 = H160(*ARB_WASM_CACHE_ADDRESS.0); } /// Address of the ArbWasm precompile. pub const ARB_WASM_ADDRESS: Address = address!("0000000000000000000000000000000000000071"); +/// Address of the ArbWasmCache precompile. +pub const ARB_WASM_CACHE_ADDRESS: Address = address!("0000000000000000000000000000000000000072"); + /// Target for compiled WASM folder in a Rust project pub const RUST_TARGET: &str = "wasm32-unknown-unknown"; diff --git a/check/src/deploy.rs b/check/src/deploy.rs index e8dc8b7..5801258 100644 --- a/check/src/deploy.rs +++ b/check/src/deploy.rs @@ -141,6 +141,9 @@ impl DeployConfig { } let tx_hash = receipt.transaction_hash.debug_lavender(); greyln!("Deployment tx hash: {tx_hash}"); + greyln!("We recommend running cargo stylus cache --program={} to cache your activated program in ArbOS \ + Cache programs benefit from cheaper calls to them. To read more about the Stylus program cache, see \ + https://docs.arbitrum.io/stylus/concepts/stylus-cache-manager", address); Ok(contract) } diff --git a/check/src/main.rs b/check/src/main.rs index 5d6adb3..da3c0b6 100644 --- a/check/src/main.rs +++ b/check/src/main.rs @@ -108,9 +108,6 @@ pub struct CacheConfig { /// Deployed and activated program address to cache. #[arg(long)] address: H160, - /// Address of the Stylus program cache manager on Arbitrum chains. - #[arg(long, default_value = "0c9043d042ab52cfa8d0207459260040cca54253")] - cache_manager_address: H160, /// Bid, in wei, to place on the desired program to cache #[arg(short, long, hide(true))] bid: Option, From fd829c73a6e31d43ec4c8bb7cb7d957d23b6914d Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Fri, 26 Jul 2024 12:44:50 -0500 Subject: [PATCH 23/35] cache fixes --- check/src/deploy.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/check/src/deploy.rs b/check/src/deploy.rs index 5801258..db3c93f 100644 --- a/check/src/deploy.rs +++ b/check/src/deploy.rs @@ -141,9 +141,12 @@ impl DeployConfig { } let tx_hash = receipt.transaction_hash.debug_lavender(); greyln!("Deployment tx hash: {tx_hash}"); - greyln!("We recommend running cargo stylus cache --program={} to cache your activated program in ArbOS \ - Cache programs benefit from cheaper calls to them. To read more about the Stylus program cache, see \ - https://docs.arbitrum.io/stylus/concepts/stylus-cache-manager", address); + println!( + r#"we recommend running cargo stylus cache --address={} to cache your activated program in ArbOS. +Cached programs benefit from cheaper calls. To read more about the Stylus program cache, see +https://docs.arbitrum.io/stylus/concepts/stylus-cache-manager"#, + hex::encode(contract) + ); Ok(contract) } From ce44f668b5bc5c05ed09f223ca38f3be3a1b004e Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Fri, 26 Jul 2024 15:21:29 -0500 Subject: [PATCH 24/35] Revamp Reproducible Builds (#56) * standardize to x86 * rem rust stable tag * macro * macro * cache updates working * arg comment * cargo update deps * Update check/src/main.rs Co-authored-by: Joshua Colvin * detect host os * standardize to x86 toolchain * docker * edits * edits * source * edits * edits * edits * edits * edits * edits * edits * edit * edit * edit * edits * arg * fix * use toolchain as source of truth * edits to no verify * better error * Update check/src/main.rs Co-authored-by: Joshua Colvin * Update check/src/main.rs Co-authored-by: Joshua Colvin * edit * edit * edits * build --------- Co-authored-by: Joshua Colvin --- Cargo.lock | 37 +++++--- check/Cargo.toml | 1 + check/src/check.rs | 9 +- check/src/constants.rs | 5 ++ check/src/deploy.rs | 3 +- check/src/docker.rs | 92 +++++++++++++++----- check/src/main.rs | 193 ++++++++++++++++++++++++++++++++++------- check/src/project.rs | 23 +++-- check/src/verify.rs | 10 ++- main/src/main.rs | 4 - 10 files changed, 298 insertions(+), 79 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f536651..d9529ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -200,7 +200,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cbcba3ca07cf7975f15d871b721fb18031eec8bce51103907f6dcce00b255d98" dependencies = [ "serde", - "winnow 0.6.15", + "winnow 0.6.16", ] [[package]] @@ -706,6 +706,7 @@ dependencies = [ "lazy_static", "serde", "serde_json", + "sys-info", "tempfile", "thiserror", "tiny-keccak", @@ -3691,9 +3692,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.6" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" dependencies = [ "serde", ] @@ -3983,6 +3984,16 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "sys-info" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b3a0d0aba8bf96a0e1ddfdc352fc53b3df7f39318c71854910c3c4b024ae52c" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -4181,21 +4192,21 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac2caab0bf757388c6c0ae23b3293fdb463fee59434529014f85e3263b995c28" +checksum = "81967dd0dd2c1ab0bc3468bd7caecc32b8a4aa47d0c8c695d8c2b2108168d62c" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.16", + "toml_edit 0.22.17", ] [[package]] name = "toml_datetime" -version = "0.6.6" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +checksum = "f8fb9f64314842840f1d940ac544da178732128f1c78c21772e876579e0da1db" dependencies = [ "serde", ] @@ -4213,15 +4224,15 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.16" +version = "0.22.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788" +checksum = "8d9f8729f5aea9562aac1cc0441f5d6de3cff1ee0c5d67293eeca5eb36ee7c16" dependencies = [ "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.15", + "winnow 0.6.16", ] [[package]] @@ -4991,9 +5002,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.15" +version = "0.6.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "557404e450152cd6795bb558bca69e43c585055f4606e3bcae5894fc6dac9ba0" +checksum = "b480ae9340fc261e6be3e95a1ba86d54ae3f9171132a73ce8d4bbaf68339507c" dependencies = [ "memchr", ] diff --git a/check/Cargo.toml b/check/Cargo.toml index 1cd89e4..d94052f 100644 --- a/check/Cargo.toml +++ b/check/Cargo.toml @@ -37,3 +37,4 @@ wasmparser = "0.213.0" wasm-encoder = "0.213.0" wasm-gen = "0.1.4" toml = "0.8.14" +sys-info = "0.9.1" diff --git a/check/src/check.rs b/check/src/check.rs index f893c9e..ebe2626 100644 --- a/check/src/check.rs +++ b/check/src/check.rs @@ -3,9 +3,9 @@ use crate::{ check::ArbWasm::ArbWasmErrors, - constants::{ARB_WASM_H160, ONE_ETH}, + constants::{ARB_WASM_H160, ONE_ETH, TOOLCHAIN_FILE_NAME}, macros::*, - project::{self, BuildConfig}, + project::{self, extract_toolchain_channel, BuildConfig}, CheckConfig, }; use alloy_primitives::{Address, B256, U256}; @@ -122,7 +122,10 @@ impl CheckConfig { if let Some(wasm) = self.wasm_file.clone() { return Ok((wasm, [0u8; 32])); } - let cfg = BuildConfig::new(self.common_cfg.rust_stable); + let toolchain_file_path = PathBuf::from(".").as_path().join(TOOLCHAIN_FILE_NAME); + let toolchain_channel = extract_toolchain_channel(&toolchain_file_path)?; + let rust_stable = !toolchain_channel.contains("nightly"); + let cfg = BuildConfig::new(rust_stable); let wasm = project::build_dylib(cfg.clone())?; let project_hash = project::hash_files(self.common_cfg.source_files_for_project_hash.clone(), cfg)?; diff --git a/check/src/constants.rs b/check/src/constants.rs index b564876..d2bb12a 100644 --- a/check/src/constants.rs +++ b/check/src/constants.rs @@ -43,3 +43,8 @@ pub const PROJECT_HASH_SECTION_NAME: &str = "project_hash"; /// Name of the toolchain file used to specify the Rust toolchain version for a project. pub const TOOLCHAIN_FILE_NAME: &str = "rust-toolchain.toml"; + +/// Base Rust image version to be used for reproducible builds. This simply installs cargo and the Rust +/// compiler, but the user will specify the exact version of the Rust toolchain to use for building within +/// the docker container. +pub const RUST_BASE_IMAGE_VERSION: &str = "1.79.0"; diff --git a/check/src/deploy.rs b/check/src/deploy.rs index db3c93f..600de07 100644 --- a/check/src/deploy.rs +++ b/check/src/deploy.rs @@ -2,7 +2,6 @@ // For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md #![allow(clippy::println_empty_string)] - use crate::{ check::{self, ProgramCheck}, constants::ARB_WASM_H160, @@ -140,7 +139,7 @@ impl DeployConfig { greyln!("deployed code at address: {address}"); } let tx_hash = receipt.transaction_hash.debug_lavender(); - greyln!("Deployment tx hash: {tx_hash}"); + greyln!("deployment tx hash: {tx_hash}"); println!( r#"we recommend running cargo stylus cache --address={} to cache your activated program in ArbOS. Cached programs benefit from cheaper calls. To read more about the Stylus program cache, see diff --git a/check/src/docker.rs b/check/src/docker.rs index 5a18e4a..0c327d6 100644 --- a/check/src/docker.rs +++ b/check/src/docker.rs @@ -5,9 +5,11 @@ use std::io::Write; use std::path::PathBuf; use std::process::{Command, Stdio}; +use cargo_stylus_util::color::Color; use eyre::{bail, eyre, Result}; -use crate::constants::TOOLCHAIN_FILE_NAME; +use crate::constants::{RUST_BASE_IMAGE_VERSION, TOOLCHAIN_FILE_NAME}; +use crate::macros::greyln; use crate::project::extract_toolchain_channel; fn version_to_image_name(version: &str) -> String { @@ -20,16 +22,38 @@ fn image_exists(name: &str) -> Result { .arg(name) .output() .map_err(|e| eyre!("failed to execute Docker command: {e}"))?; + + if !output.status.success() { + let stderr = std::str::from_utf8(&output.stderr) + .map_err(|e| eyre!("failed to read Docker command stderr: {e}"))?; + if stderr.contains("Cannot connect to the Docker daemon") { + println!( + r#"Cargo stylus deploy|check|verify run in a Docker container by default to ensure deployments +are reproducible, but Docker is not found in your system. Please install Docker if you wish to create +a reproducible deployment, or opt out by using the --no-verify flag for local builds"# + ); + bail!("Docker not running"); + } + bail!(stderr.to_string()) + } + Ok(output.stdout.iter().filter(|c| **c == b'\n').count() > 1) } fn create_image(version: &str) -> Result<()> { - let name = version_to_image_name(version); + let name = version_to_image_name(&version); if image_exists(&name)? { return Ok(()); } - let toolchain_file_path = PathBuf::from(".").as_path().join(TOOLCHAIN_FILE_NAME); - let toolchain_channel = extract_toolchain_channel(&toolchain_file_path)?; + let cargo_stylus_version = env!("CARGO_PKG_VERSION"); + let cargo_stylus_version: String = cargo_stylus_version + .chars() + .filter(|c| c.is_alphanumeric() || *c == '-' || *c == '.') + .collect(); + println!( + "Building Docker image for cargo-stylus version {} and Rust toolchain {}", + cargo_stylus_version, version, + ); let mut child = Command::new("docker") .arg("build") .arg("-t") @@ -42,20 +66,20 @@ fn create_image(version: &str) -> Result<()> { write!( child.stdin.as_mut().unwrap(), "\ - FROM rust:{} as builder\n\ - RUN rustup toolchain install {} && rustup default {} + FROM --platform=linux/amd64 rust:{} as builder\n\ + RUN rustup toolchain install {}-x86_64-unknown-linux-gnu + RUN rustup default {}-x86_64-unknown-linux-gnu RUN rustup target add wasm32-unknown-unknown RUN rustup target add wasm32-wasi - RUN rustup target add aarch64-unknown-linux-gnu RUN rustup target add x86_64-unknown-linux-gnu - RUN cargo install cargo-stylus - RUN cargo install --force cargo-stylus-check - RUN cargo install --force cargo-stylus-replay - RUN cargo install --force cargo-stylus-cgen + RUN cargo install cargo-stylus-check --version {} --force + RUN cargo install cargo-stylus --version {} --force ", + RUST_BASE_IMAGE_VERSION, + version, version, - toolchain_channel, - toolchain_channel, + cargo_stylus_version, + cargo_stylus_version, )?; child.wait().map_err(|e| eyre!("wait failed: {e}"))?; Ok(()) @@ -79,21 +103,47 @@ fn run_in_docker_container(version: &str, command_line: &[&str]) -> Result<()> { .arg(name) .args(command_line) .spawn() - .map_err(|e| eyre!("failed to execure Docker command: {e}"))? + .map_err(|e| eyre!("failed to execute Docker command: {e}"))? .wait() .map_err(|e| eyre!("wait failed: {e}"))?; Ok(()) } -pub fn run_reproducible(version: &str, command_line: &[String]) -> Result<()> { - let version: String = version - .chars() - .filter(|c| c.is_alphanumeric() || *c == '.') - .collect(); +pub fn run_reproducible(command_line: &[String]) -> Result<()> { + verify_valid_host()?; + let toolchain_file_path = PathBuf::from(".").as_path().join(TOOLCHAIN_FILE_NAME); + let toolchain_channel = extract_toolchain_channel(&toolchain_file_path)?; + greyln!( + "Running reproducible Stylus command with toolchain {}", + toolchain_channel.mint() + ); let mut command = vec!["cargo", "stylus"]; for s in command_line.iter() { command.push(s); } - create_image(&version)?; - run_in_docker_container(&version, &command) + create_image(&toolchain_channel)?; + run_in_docker_container(&toolchain_channel, &command) +} + +fn verify_valid_host() -> Result<()> { + let Ok(os_type) = sys_info::os_type() else { + bail!("unable to determine host OS type"); + }; + if os_type == "Windows" { + // Check for WSL environment + let Ok(kernel_version) = sys_info::os_release() else { + bail!("unable to determine kernel version"); + }; + if kernel_version.contains("microsoft") || kernel_version.contains("WSL") { + greyln!("Detected Windows Linux Subsystem host"); + } else { + bail!( + "Reproducible cargo stylus commands on Windows are only supported \ + in Windows Linux Subsystem (WSL). Please install within WSL. \ + To instead opt out of reproducible builds, add the --no-verify \ + flag to your commands." + ); + } + } + Ok(()) } diff --git a/check/src/main.rs b/check/src/main.rs index da3c0b6..c7f60bf 100644 --- a/check/src/main.rs +++ b/check/src/main.rs @@ -4,6 +4,7 @@ use clap::{ArgGroup, Args, Parser}; use ethers::types::{H160, U256}; use eyre::{eyre, Context, Result}; +use std::fmt; use std::path::PathBuf; use tokio::runtime::Builder; @@ -57,19 +58,6 @@ enum Apis { /// Deploy a contract. #[command(alias = "d")] Deploy(DeployConfig), - /// Build in a Docker container to ensure reproducibility. - /// - /// Specify the Rust version to use, followed by the cargo stylus subcommand. - /// Example: `cargo stylus reproducible 1.77 check` - Reproducible { - /// Rust version to use. - #[arg()] - rust_version: String, - - /// Stylus subcommand. - #[arg(trailing_var_arg = true, allow_hyphen_values = true)] - stylus: Vec, - }, /// Verify the deployment of a Stylus program. #[command(alias = "v")] Verify(VerifyConfig), @@ -80,9 +68,6 @@ struct CommonConfig { /// Arbitrum RPC endpoint. #[arg(short, long, default_value = "https://sepolia-rollup.arbitrum.io/rpc")] endpoint: String, - /// Whether to use stable Rust. - #[arg(long)] - rust_stable: bool, /// Whether to print debug info. #[arg(long)] verbose: bool, @@ -123,6 +108,10 @@ pub struct CheckConfig { /// Where to deploy and activate the program (defaults to a random address). #[arg(long)] program_address: Option, + /// If specified, will not run the command in a reproducible docker container. Useful for local + /// builds, but at the risk of not having a reproducible contract for verification purposes. + #[arg(long)] + no_verify: bool, } #[derive(Args, Clone, Debug)] @@ -141,10 +130,13 @@ struct DeployConfig { pub struct VerifyConfig { #[command(flatten)] common_cfg: CommonConfig, - /// Hash of the deployment transaction. #[arg(long)] deployment_tx: String, + #[arg(long)] + /// If specified, will not run the command in a reproducible docker container. Useful for local + /// builds, but at the risk of not having a reproducible contract for verification purposes. + no_verify: bool, } #[derive(Clone, Debug, Args)] @@ -164,6 +156,110 @@ struct AuthOpts { keystore_password_path: Option, } +impl fmt::Display for CommonConfig { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Convert the vector of source files to a comma-separated string + let mut source_files: String = "".to_string(); + if !self.source_files_for_project_hash.is_empty() { + source_files = format!( + "--source-files-for-project-hash={}", + self.source_files_for_project_hash.join(", ") + ); + } + write!( + f, + "--endpoint={} {} {} {}", + self.endpoint, + match self.verbose { + true => "--verbose", + false => "", + }, + source_files, + match &self.max_fee_per_gas_gwei { + Some(fee) => format!("--max-fee-per-gas-gwei {}", fee), + None => "".to_string(), + } + ) + } +} + +impl fmt::Display for CheckConfig { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "{} {} {} {}", + self.common_cfg.to_string(), + match &self.wasm_file { + Some(path) => format!("--wasm-file={}", path.display().to_string()), + None => "".to_string(), + }, + match &self.program_address { + Some(addr) => format!("--program-address={:?}", addr), + None => "".to_string(), + }, + match self.no_verify { + true => "--no-verify".to_string(), + false => "".to_string(), + }, + ) + } +} + +impl fmt::Display for DeployConfig { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "{} {} {}", + self.check_config.to_string(), + self.auth.to_string(), + match self.estimate_gas { + true => "--estimate-gas".to_string(), + false => "".to_string(), + }, + ) + } +} + +impl fmt::Display for AuthOpts { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "{} {} {} {}", + match &self.private_key_path { + Some(path) => format!("--private-key-path={}", path.display().to_string()), + None => "".to_string(), + }, + match &self.private_key { + Some(key) => format!("--private-key={}", key.clone()), + None => "".to_string(), + }, + match &self.keystore_path { + Some(path) => format!("--keystore-path={}", path.clone()), + None => "".to_string(), + }, + match &self.keystore_password_path { + Some(path) => format!("--keystore-password-path={}", path.display().to_string()), + None => "".to_string(), + } + ) + } +} + +impl fmt::Display for VerifyConfig { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "{} --deployment-tx={} {}", + self.common_cfg.to_string(), + self.deployment_tx, + match self.no_verify { + true => "--no-verify".to_string(), + false => "".to_string(), + } + ) + } +} + fn main() -> Result<()> { let args = Opts::parse(); let runtime = Builder::new_multi_thread().enable_all().build()?; @@ -188,22 +284,61 @@ async fn main_impl(args: Opts) -> Result<()> { run!(cache::cache_program(&config).await, "stylus cache failed"); } Apis::Check(config) => { - run!(check::check(&config).await, "stylus checks failed"); + if config.no_verify { + run!(check::check(&config).await, "stylus checks failed"); + } else { + let mut commands: Vec = + vec![String::from("check"), String::from("--no-verify")]; + let config_args = config + .to_string() + .split(' ') + .map(|s| s.to_string()) + .filter(|s| !s.is_empty()) + .collect::>(); + commands.extend(config_args); + run!( + docker::run_reproducible(&commands), + "failed reproducible run" + ); + } } Apis::Deploy(config) => { - run!(deploy::deploy(config).await, "failed to deploy"); - } - Apis::Reproducible { - rust_version, - stylus, - } => { - run!( - docker::run_reproducible(&rust_version, &stylus), - "failed reproducible run" - ); + if config.check_config.no_verify { + run!(deploy::deploy(config).await, "stylus deploy failed"); + } else { + let mut commands: Vec = + vec![String::from("deploy"), String::from("--no-verify")]; + let config_args = config + .to_string() + .split(' ') + .map(|s| s.to_string()) + .filter(|s| !s.is_empty()) + .collect::>(); + commands.extend(config_args); + run!( + docker::run_reproducible(&commands), + "failed reproducible run" + ); + } } Apis::Verify(config) => { - run!(verify::verify(config).await, "failed to verify"); + if config.no_verify { + run!(verify::verify(config).await, "failed to verify"); + } else { + let mut commands: Vec = + vec![String::from("verify"), String::from("--no-verify")]; + let config_args = config + .to_string() + .split(' ') + .map(|s| s.to_string()) + .filter(|s| !s.is_empty()) + .collect::>(); + commands.extend(config_args); + run!( + docker::run_reproducible(&commands), + "failed reproducible run" + ); + } } } Ok(()) diff --git a/check/src/project.rs b/check/src/project.rs index eab27f8..0530ca6 100644 --- a/check/src/project.rs +++ b/check/src/project.rs @@ -167,12 +167,17 @@ fn all_paths(root_dir: &Path, source_file_patterns: Vec) -> Result Result { - let toolchain_file_contents = std::fs::read_to_string(toolchain_file_path).wrap_err( + let toolchain_file_contents = fs::read_to_string(toolchain_file_path).context( "expected to find a rust-toolchain.toml file in project directory \ - to specify your Rust toolchain for reproducible verification", + to specify your Rust toolchain for reproducible verification. The channel in your project's rust-toolchain.toml's \ + toolchain section must be a specific version e.g., '1.80.0' or 'nightly-YYYY-MM-DD'. \ + To ensure reproducibility, it cannot be a generic channel like 'stable', 'nightly', or 'beta'. Read more about \ + the toolchain file in https://rust-lang.github.io/rustup/overrides.html#the-toolchain-file or see \ + the file in https://github.com/OffchainLabs/stylus-hello-world for an example", )?; + let toolchain_toml: Value = - toml::from_str(&toolchain_file_contents).wrap_err("failed to parse rust-toolchain.toml")?; + toml::from_str(&toolchain_file_contents).context("failed to parse rust-toolchain.toml")?; // Extract the channel from the toolchain section let Some(toolchain) = toolchain_toml.get("toolchain") else { @@ -184,11 +189,19 @@ pub fn extract_toolchain_channel(toolchain_file_path: &PathBuf) -> Result, cfg: BuildConfig) -> Result let mut hash = [0u8; 32]; keccak.finalize(&mut hash); greyln!( - "Project hash computed on deployment: {:?}", + "project metadata hash computed on deployment: {:?}", hex::encode(hash) ); Ok(hash) diff --git a/check/src/verify.rs b/check/src/verify.rs index f3e0ca0..668deee 100644 --- a/check/src/verify.rs +++ b/check/src/verify.rs @@ -14,8 +14,10 @@ use serde::{Deserialize, Serialize}; use crate::{ check, + constants::TOOLCHAIN_FILE_NAME, deploy::{self, extract_compressed_wasm, extract_program_evm_deployment_prelude}, - project, CheckConfig, VerifyConfig, + project::{self, extract_toolchain_channel}, + CheckConfig, VerifyConfig, }; use cargo_stylus_util::{color::Color, sys}; @@ -30,6 +32,9 @@ pub async fn verify(cfg: VerifyConfig) -> eyre::Result<()> { if hash.len() != 32 { bail!("Invalid hash"); } + let toolchain_file_path = PathBuf::from(".").as_path().join(TOOLCHAIN_FILE_NAME); + let toolchain_channel = extract_toolchain_channel(&toolchain_file_path)?; + let rust_stable = !toolchain_channel.contains("nightly"); let Some(result) = provider .get_transaction(H256::from_slice(&hash)) .await @@ -49,13 +54,14 @@ pub async fn verify(cfg: VerifyConfig) -> eyre::Result<()> { common_cfg: cfg.common_cfg.clone(), wasm_file: None, program_address: None, + no_verify: cfg.no_verify, }; let _ = check::check(&check_cfg) .await .map_err(|e| eyre!("Stylus checks failed: {e}"))?; let build_cfg = project::BuildConfig { opt_level: project::OptLevel::default(), - stable: cfg.common_cfg.rust_stable, + stable: rust_stable, }; let wasm_file: PathBuf = project::build_dylib(build_cfg.clone()) .map_err(|e| eyre!("could not build project to WASM: {e}"))?; diff --git a/main/src/main.rs b/main/src/main.rs index 43da340..175ce04 100644 --- a/main/src/main.rs +++ b/main/src/main.rs @@ -50,9 +50,6 @@ enum Subcommands { /// Verify the deployment of a Stylus program against a local project. #[command(alias = "v")] Verify, - /// Run cargo stylus commands in a Docker container for reproducibility. - #[command()] - Reproducible, /// Generate C code. #[command()] CGen, @@ -74,7 +71,6 @@ const COMMANDS: &[Binary] = &[ "check", "deploy", "verify", - "reproducible", "n", "x", "c", From 851731db167c6ab5ce81cc94908379071fe54bd4 Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Fri, 26 Jul 2024 15:58:32 -0500 Subject: [PATCH 25/35] Standalone Command to Activate Already Deployed Programs (#60) * begin * activate works * default * build * fix clippy --- check/src/activate.rs | 87 +++++++++++++++++++++++++++++++++++++++++++ check/src/cache.rs | 2 +- check/src/check.rs | 2 +- check/src/docker.rs | 2 +- check/src/main.rs | 39 +++++++++++++++---- check/src/verify.rs | 4 +- main/src/main.rs | 4 ++ 7 files changed, 128 insertions(+), 12 deletions(-) create mode 100644 check/src/activate.rs diff --git a/check/src/activate.rs b/check/src/activate.rs new file mode 100644 index 0000000..8a80481 --- /dev/null +++ b/check/src/activate.rs @@ -0,0 +1,87 @@ +// Copyright 2023-2024, Offchain Labs, Inc. +// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/stylus/licenses/COPYRIGHT.md + +use alloy_primitives::Address; +use alloy_sol_macro::sol; +use alloy_sol_types::SolCall; +use cargo_stylus_util::color::{Color, DebugColor}; +use cargo_stylus_util::sys; +use ethers::middleware::{Middleware, SignerMiddleware}; +use ethers::signers::Signer; +use ethers::types::transaction::eip2718::TypedTransaction; +use ethers::types::{Eip1559TransactionRequest, U256}; +use ethers::utils::format_units; +use eyre::{bail, Context, Result}; + +use crate::check::check_activate; +use crate::constants::ARB_WASM_H160; +use crate::macros::greyln; + +use crate::ActivateConfig; + +sol! { + interface ArbWasm { + function activateProgram(address program) + external + payable + returns (uint16 version, uint256 dataFee); + } +} + +/// Activates an already deployed Stylus program by address. +pub async fn activate_program(cfg: &ActivateConfig) -> Result<()> { + let provider = sys::new_provider(&cfg.common_cfg.endpoint)?; + let chain_id = provider + .get_chainid() + .await + .wrap_err("failed to get chain id")?; + + let wallet = cfg.auth.wallet().wrap_err("failed to load wallet")?; + let wallet = wallet.with_chain_id(chain_id.as_u64()); + let client = SignerMiddleware::new(provider.clone(), wallet); + + let code = client.get_code(cfg.address, None).await?; + let data_fee = check_activate(code, cfg.address, &provider).await?; + let mut data_fee = alloy_ethers_typecast::alloy_u256_to_ethers(data_fee); + + greyln!( + "obtained estimated activation data fee {}", + format_units(data_fee, "ether")?.debug_lavender() + ); + greyln!( + "bumping estimated activation data fee by {}%", + cfg.data_fee_bump_percent.debug_lavender() + ); + data_fee = bump_data_fee(data_fee, cfg.data_fee_bump_percent); + + let program: Address = cfg.address.to_fixed_bytes().into(); + let data = ArbWasm::activateProgramCall { program }.abi_encode(); + let tx = Eip1559TransactionRequest::new() + .from(client.address()) + .to(*ARB_WASM_H160) + .value(data_fee) + .data(data); + let tx = TypedTransaction::Eip1559(tx); + let tx = client.send_transaction(tx, None).await?; + match tx.await? { + Some(receipt) => { + greyln!( + "successfully activated program 0x{} with tx {}", + hex::encode(cfg.address), + hex::encode(receipt.transaction_hash).debug_lavender() + ); + } + None => { + bail!( + "failed to fetch receipt for program activation {}", + cfg.address + ); + } + } + Ok(()) +} + +fn bump_data_fee(fee: U256, pct: u64) -> U256 { + let num = 100 + pct; + fee * U256::from(num) / U256::from(100) +} diff --git a/check/src/cache.rs b/check/src/cache.rs index b270587..607db6c 100644 --- a/check/src/cache.rs +++ b/check/src/cache.rs @@ -56,7 +56,7 @@ pub async fn cache_program(cfg: &CacheConfig) -> Result<()> { if cache_manager_addrs.is_empty() { bail!("no cache managers found in ArbWasmCache, perhaps the Stylus cache is not yet enabled on this chain"); } - let cache_manager = cache_manager_addrs.last().unwrap().clone(); + let cache_manager = *cache_manager_addrs.last().unwrap(); let cache_manager = H160::from_slice(cache_manager.as_slice()); let program: Address = cfg.address.to_fixed_bytes().into(); diff --git a/check/src/check.rs b/check/src/check.rs index ebe2626..137a14d 100644 --- a/check/src/check.rs +++ b/check/src/check.rs @@ -241,7 +241,7 @@ async fn program_exists(codehash: B256, provider: &Provider) -> Result) -> Result { +pub async fn check_activate(code: Bytes, address: H160, provider: &Provider) -> Result { let program = Address::from(address.to_fixed_bytes()); let data = ArbWasm::activateProgramCall { program }.abi_encode(); let tx = Eip1559TransactionRequest::new() diff --git a/check/src/docker.rs b/check/src/docker.rs index 0c327d6..89a433d 100644 --- a/check/src/docker.rs +++ b/check/src/docker.rs @@ -41,7 +41,7 @@ a reproducible deployment, or opt out by using the --no-verify flag for local bu } fn create_image(version: &str) -> Result<()> { - let name = version_to_image_name(&version); + let name = version_to_image_name(version); if image_exists(&name)? { return Ok(()); } diff --git a/check/src/main.rs b/check/src/main.rs index c7f60bf..a57b1c3 100644 --- a/check/src/main.rs +++ b/check/src/main.rs @@ -8,6 +8,7 @@ use std::fmt; use std::path::PathBuf; use tokio::runtime::Builder; +mod activate; mod cache; mod check; mod constants; @@ -50,6 +51,9 @@ enum Apis { #[arg(long)] json: bool, }, + /// Activate an already deployed contract. + #[command(alias = "a")] + Activate(ActivateConfig), /// Cache a contract using the Stylus CacheManager for Arbitrum chains. Cache(CacheConfig), /// Check a contract. @@ -98,6 +102,21 @@ pub struct CacheConfig { bid: Option, } +#[derive(Args, Clone, Debug)] +pub struct ActivateConfig { + #[command(flatten)] + common_cfg: CommonConfig, + /// Wallet source to use. + #[command(flatten)] + auth: AuthOpts, + /// Deployed Stylus program address to activate. + #[arg(long)] + address: H160, + /// Percent to bump the estimated activation data fee by. Default of 20% + #[arg(long, default_value = "20")] + data_fee_bump_percent: u64, +} + #[derive(Args, Clone, Debug)] pub struct CheckConfig { #[command(flatten)] @@ -188,9 +207,9 @@ impl fmt::Display for CheckConfig { write!( f, "{} {} {} {}", - self.common_cfg.to_string(), + self.common_cfg, match &self.wasm_file { - Some(path) => format!("--wasm-file={}", path.display().to_string()), + Some(path) => format!("--wasm-file={}", path.display()), None => "".to_string(), }, match &self.program_address { @@ -210,8 +229,8 @@ impl fmt::Display for DeployConfig { write!( f, "{} {} {}", - self.check_config.to_string(), - self.auth.to_string(), + self.check_config, + self.auth, match self.estimate_gas { true => "--estimate-gas".to_string(), false => "".to_string(), @@ -226,7 +245,7 @@ impl fmt::Display for AuthOpts { f, "{} {} {} {}", match &self.private_key_path { - Some(path) => format!("--private-key-path={}", path.display().to_string()), + Some(path) => format!("--private-key-path={}", path.display()), None => "".to_string(), }, match &self.private_key { @@ -238,7 +257,7 @@ impl fmt::Display for AuthOpts { None => "".to_string(), }, match &self.keystore_password_path { - Some(path) => format!("--keystore-password-path={}", path.display().to_string()), + Some(path) => format!("--keystore-password-path={}", path.display()), None => "".to_string(), } ) @@ -250,7 +269,7 @@ impl fmt::Display for VerifyConfig { write!( f, "{} --deployment-tx={} {}", - self.common_cfg.to_string(), + self.common_cfg, self.deployment_tx, match self.no_verify { true => "--no-verify".to_string(), @@ -280,6 +299,12 @@ async fn main_impl(args: Opts) -> Result<()> { Apis::ExportAbi { json, output } => { run!(export_abi::export_abi(output, json), "failed to export abi"); } + Apis::Activate(config) => { + run!( + activate::activate_program(&config).await, + "stylus activate failed" + ); + } Apis::Cache(config) => { run!(cache::cache_program(&config).await, "stylus cache failed"); } diff --git a/check/src/verify.rs b/check/src/verify.rs index 668deee..8eee240 100644 --- a/check/src/verify.rs +++ b/check/src/verify.rs @@ -72,7 +72,7 @@ pub async fn verify(cfg: VerifyConfig) -> eyre::Result<()> { if deployment_data == *result.input { println!("Verified - program matches local project's file hashes"); } else { - let tx_prelude = extract_program_evm_deployment_prelude(&*result.input); + let tx_prelude = extract_program_evm_deployment_prelude(&result.input); let reconstructed_prelude = extract_program_evm_deployment_prelude(&deployment_data); println!( "{} - program deployment did not verify against local project's file hashes", @@ -94,7 +94,7 @@ pub async fn verify(cfg: VerifyConfig) -> eyre::Result<()> { ); println!( "Compressed code length of deployment tx {}", - extract_compressed_wasm(&*result.input).len() + extract_compressed_wasm(&result.input).len() ); } Ok(()) diff --git a/main/src/main.rs b/main/src/main.rs index 175ce04..a6ee7d6 100644 --- a/main/src/main.rs +++ b/main/src/main.rs @@ -38,6 +38,9 @@ enum Subcommands { /// Check a contract. #[command(alias = "c")] Check, + /// Activate an already deployed program + #[command(alias = "a")] + Activate, /// Deploy a contract. #[command(alias = "d")] Deploy, @@ -71,6 +74,7 @@ const COMMANDS: &[Binary] = &[ "check", "deploy", "verify", + "a", "n", "x", "c", From 794221e183cdfd791a2b5be04ec2ab762b381269 Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Fri, 26 Jul 2024 16:36:21 -0500 Subject: [PATCH 26/35] bump version (#61) --- Cargo.lock | 12 ++++++------ Cargo.toml | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d9529ad..2fdf91d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -667,7 +667,7 @@ dependencies = [ [[package]] name = "cargo-stylus" -version = "0.4.1" +version = "0.4.2" dependencies = [ "cargo-stylus-util", "clap", @@ -676,7 +676,7 @@ dependencies = [ [[package]] name = "cargo-stylus-cgen" -version = "0.4.1" +version = "0.4.2" dependencies = [ "alloy-json-abi", "clap", @@ -687,7 +687,7 @@ dependencies = [ [[package]] name = "cargo-stylus-check" -version = "0.4.1" +version = "0.4.2" dependencies = [ "alloy-ethers-typecast", "alloy-json-abi", @@ -720,14 +720,14 @@ dependencies = [ [[package]] name = "cargo-stylus-example" -version = "0.4.1" +version = "0.4.2" dependencies = [ "clap", ] [[package]] name = "cargo-stylus-replay" -version = "0.4.1" +version = "0.4.2" dependencies = [ "alloy-primitives 0.7.7", "cargo-stylus-util", @@ -747,7 +747,7 @@ dependencies = [ [[package]] name = "cargo-stylus-util" -version = "0.4.1" +version = "0.4.2" dependencies = [ "ethers", "eyre", diff --git a/Cargo.toml b/Cargo.toml index 4cd4354..640811d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ resolver = "2" [workspace.package] authors = ["Offchain Labs"] -version = "0.4.1" +version = "0.4.2" edition = "2021" homepage = "https://arbitrum.io" license = "MIT OR Apache-2.0" @@ -34,4 +34,4 @@ parking_lot = "0.12.1" sneks = "0.1.2" # members -cargo-stylus-util = { path = "util", version = "0.4.1" } +cargo-stylus-util = { path = "util", version = "0.4.2" } From 8046a6a1fb6d1ef08a27611ef51e220b8036c286 Mon Sep 17 00:00:00 2001 From: Mark_Jeong <81726531+markjung96@users.noreply.github.com> Date: Thu, 8 Aug 2024 18:02:12 +0900 Subject: [PATCH 27/35] feat: migrate to 0.4.2 --- check/src/activate.rs | 13 +++++++------ check/src/check.rs | 16 +++++++--------- check/src/deploy.rs | 4 ++-- check/src/main.rs | 6 ++++-- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/check/src/activate.rs b/check/src/activate.rs index e018f91..2b11ca9 100644 --- a/check/src/activate.rs +++ b/check/src/activate.rs @@ -4,10 +4,10 @@ #![allow(clippy::println_empty_string)] use std::fs; -use std::io::{Read, Write}; +use std::io::Write; use std::path::PathBuf; -use alloy_primitives::{Address, U256 as AU256}; +use alloy_primitives::Address; use alloy_sol_macro::sol; use alloy_sol_types::SolCall; use ethers::{ @@ -15,7 +15,8 @@ use ethers::{ middleware::SignerMiddleware, prelude::*, providers::{Middleware, Provider}, - types::{Eip1559TransactionRequest, H160, TypedTransaction, U256, U64}, + types::transaction::eip2718::TypedTransaction, + types::{Eip1559TransactionRequest, H160, U256}, utils::format_units, }; use eyre::{bail, eyre, Context, Result, WrapErr}; @@ -23,9 +24,9 @@ use eyre::{bail, eyre, Context, Result, WrapErr}; use cargo_stylus_util::color::{Color, DebugColor}; use cargo_stylus_util::sys; -use crate::macros::greyln; use crate::check::check_activate; use crate::constants::ARB_WASM_H160; +use crate::macros::greyln; use crate::ActivateConfig; pub enum TxKind { @@ -56,7 +57,7 @@ type SignerClient = SignerMiddleware, Wallet>; /// Deploys a stylus program, activating if needed. pub async fn activate(cfg: ActivateConfig) -> Result<()> { greyln!("@@@ activate"); - let contract = cfg.contract_address.unwrap(); + let contract = cfg.address; let program: Address = contract.to_fixed_bytes().into(); let data = ArbWasm::activateProgramCall { program }.abi_encode(); write_tx_data(TxKind::Activation, &data)?; @@ -70,7 +71,7 @@ fn write_tx_data(tx_kind: TxKind, data: &[u8]) -> eyre::Result<()> { if !path.exists() { fs::create_dir_all(&path).map_err(|e| eyre!("could not create output directory: {e}"))?; } - + path = path.join(file_name); let path_str = path.as_os_str().to_string_lossy(); let hex: String = data diff --git a/check/src/check.rs b/check/src/check.rs index 2857699..d8d8d24 100644 --- a/check/src/check.rs +++ b/check/src/check.rs @@ -22,9 +22,9 @@ use ethers::{ }; use eyre::{bail, eyre, ErrReport, Result, WrapErr}; use serde_json::Value; +use std::fs::{self, File}; use std::io::Write; use std::path::PathBuf; -use std::fs::{self, File}; sol! { interface ArbWasm { @@ -62,12 +62,13 @@ pub async fn check(cfg: &CheckConfig) -> Result { greyln!("reading wasm file at {}", wasm.to_string_lossy().lavender()); } - let (wasm, code) = project::compress_wasm(&wasm).wrap_err("failed to compress WASM")?; - + let (wasm_file_bytes, code) = + project::compress_wasm(&wasm, project_hash).wrap_err("failed to compress WASM")?; + let code_copied = code.clone(); - + let mut code_len = [0u8; 32]; - + ethers::prelude::U256::from(code_copied.len()).to_big_endian(&mut code_len); let mut tx_code: Vec = vec![]; tx_code.push(0x7f); // PUSH32 @@ -85,9 +86,6 @@ pub async fn check(cfg: &CheckConfig) -> Result { tx_code.extend(project_hash); tx_code.extend(code_copied); write_tx_data(TxKind::Deployment, &tx_code)?; - - let (wasm_file_bytes, code) = - project::compress_wasm(&wasm, project_hash).wrap_err("failed to compress WASM")?; greyln!("contract size: {}", format_file_size(code.len(), 16, 24)); @@ -284,7 +282,7 @@ fn write_tx_data(tx_kind: TxKind, data: &[u8]) -> eyre::Result<()> { if !path.exists() { fs::create_dir_all(&path).map_err(|e| eyre!("could not create output directory: {e}"))?; } - + path = path.join(file_name); let path_str = path.as_os_str().to_string_lossy(); println!( diff --git a/check/src/deploy.rs b/check/src/deploy.rs index be5469c..e915c9c 100644 --- a/check/src/deploy.rs +++ b/check/src/deploy.rs @@ -3,7 +3,6 @@ #![allow(clippy::println_empty_string)] -use std::fs; use crate::{ check::{self, ProgramCheck}, constants::ARB_WASM_H160, @@ -26,6 +25,7 @@ use ethers::{ types::{transaction::eip2718::TypedTransaction, Eip1559TransactionRequest, H160, U256, U64}, }; use eyre::{bail, eyre, Result, WrapErr}; +use std::fs; use std::io::Write; use std::path::PathBuf; @@ -314,7 +314,7 @@ fn write_tx_data(tx_kind: TxKind, data: &[u8]) -> eyre::Result<()> { if !path.exists() { fs::create_dir_all(&path).map_err(|e| eyre!("could not create output directory: {e}"))?; } - + path = path.join(file_name); let path_str = path.as_os_str().to_string_lossy(); println!( diff --git a/check/src/main.rs b/check/src/main.rs index c61759f..d7f40ad 100644 --- a/check/src/main.rs +++ b/check/src/main.rs @@ -18,8 +18,8 @@ mod export_abi; mod macros; mod new; mod project; -mod verify; mod tx; +mod verify; mod wallet; #[derive(Parser, Debug)] @@ -380,8 +380,10 @@ async fn main_impl(args: Opts) -> Result<()> { rust_version, stylus, } => { + let mut commands: Vec = vec![rust_version]; + commands.extend(stylus); run!( - docker::run_reproducible(&rust_version, &stylus), + docker::run_reproducible(&commands), "failed reproducible run" ); } From f18c28e37a9d3be4f6fd342257018edac63cd282 Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Mon, 12 Aug 2024 11:33:36 -0500 Subject: [PATCH 28/35] standardize to contract --- README.md | 42 ++++++++++++++++++------------------ check/OPTIMIZING_BINARIES.md | 4 ++-- check/VALID_WASM.md | 8 +++---- check/src/activate.rs | 12 +++++------ check/src/cache.rs | 18 ++++++++-------- check/src/check.rs | 36 +++++++++++++++---------------- check/src/constants.rs | 2 +- check/src/deploy.rs | 42 +++++++++++++++++++++--------------- check/src/export_abi.rs | 4 ++-- check/src/main.rs | 22 +++++++++---------- check/src/project.rs | 2 +- check/src/verify.rs | 14 ++++++------ main/src/main.rs | 4 ++-- replay/src/hostio.rs | 28 ++++++++++++------------ replay/src/trace.rs | 4 ++-- 15 files changed, 125 insertions(+), 117 deletions(-) diff --git a/README.md b/README.md index 6f9ee6c..bdd0228 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![linux](https://github.com/OffchainLabs/cargo-stylus/actions/workflows/linux.yml/badge.svg)](https://github.com/OffchainLabs/cargo-stylus/actions/workflows/linux.yml) [![mac](https://github.com/OffchainLabs/cargo-stylus/actions/workflows/mac.yml/badge.svg)](https://github.com/OffchainLabs/cargo-stylus/actions/workflows/mac.yml) [![windows](https://github.com/OffchainLabs/cargo-stylus/actions/workflows/windows.yml/badge.svg)](https://github.com/OffchainLabs/cargo-stylus/actions/workflows/windows.yml) [![lint](https://github.com/OffchainLabs/cargo-stylus/actions/workflows/check.yml/badge.svg)](https://github.com/OffchainLabs/cargo-stylus/actions/workflows/check.yml) -A cargo subcommand for building, verifying, and deploying Arbitrum Stylus WASM programs in Rust. +A cargo subcommand for building, verifying, and deploying Arbitrum Stylus WASM contracts in Rust. ## Quick Start @@ -38,7 +38,7 @@ Usage: ### Overview -The cargo stylus command comes with useful commands such as `new`, `check` and `deploy`, and `export-abi` for developing and deploying Stylus programs to Arbitrum chains. Here's a common workflow: +The cargo stylus command comes with useful commands such as `new`, `check` and `deploy`, and `export-abi` for developing and deploying Stylus contracts to Arbitrum chains. Here's a common workflow: Start a new Stylus project with @@ -57,21 +57,21 @@ All testnet information, including faucets and RPC endpoints can be found [here] ### Developing With Stylus -Then, develop your Rust program normally and take advantage of all the features the [stylus-sdk](https://github.com/OffchainLabs/stylus-sdk-rs) has to offer. To check whether or not your program will successfully deploy and activate onchain, use the `cargo stylus check` subcommand: +Then, develop your Rust contract normally and take advantage of all the features the [stylus-sdk](https://github.com/OffchainLabs/stylus-sdk-rs) has to offer. To check whether or not your contract will successfully deploy and activate onchain, use the `cargo stylus check` subcommand: ``` cargo stylus check ``` -This command will attempt to verify that your program can be deployed and activated onchain without requiring a transaction by specifying a JSON-RPC endpoint. By default, it will use the public URL of the Stylus testnet as its endpoint. See [here](https://docs.arbitrum.io/stylus/reference/testnet-information) for available testnet RPC URLs. See `cargo stylus check --help` for more options. +This command will attempt to verify that your contract can be deployed and activated onchain without requiring a transaction by specifying a JSON-RPC endpoint. By default, it will use the public URL of the Stylus testnet as its endpoint. See [here](https://docs.arbitrum.io/stylus/reference/testnet-information) for available testnet RPC URLs. See `cargo stylus check --help` for more options. If the command above fails, you'll see detailed information about why your WASM will be rejected: ``` Reading WASM file at bad-export.wat Compressed WASM size: 55 B -Stylus checks failed: program predeployment check failed when checking against -ARB_WASM_ADDRESS 0x0000…0071: (code: -32000, message: program activation failed: failed to parse program) +Stylus checks failed: contract predeployment check failed when checking against +ARB_WASM_ADDRESS 0x0000…0071: (code: -32000, message: contract activation failed: failed to parse contract) Caused by: binary exports reserved symbol stylus_ink_left @@ -80,18 +80,18 @@ Location: prover/src/binary.rs:493:9, data: None) ``` -To read more about what counts as valid vs. invalid user WASM programs, see [VALID_WASM](./check/VALID_WASM.md). +To read more about what counts as valid vs. invalid user WASM contracts, see [VALID_WASM](./check/VALID_WASM.md). -If your program succeeds, you'll see the following message: +If your contract succeeds, you'll see the following message: ``` Finished release [optimized] target(s) in 1.88s Reading WASM file at hello-stylus/target/wasm32-unknown-unknown/release/hello-stylus.wasm Compressed WASM size: 3 KB -Program succeeded Stylus onchain activation checks with Stylus version: 1 +Contract succeeded Stylus onchain activation checks with Stylus version: 1 ``` -Once you're ready to deploy your program onchain, you can use the `cargo stylus deploy` subcommand as follows: +Once you're ready to deploy your contract onchain, you can use the `cargo stylus deploy` subcommand as follows: First, we can estimate the gas required to perform our deployment and activation with: @@ -105,7 +105,7 @@ and see: ``` Compressed WASM size: 3 KB -Deploying program to address 0x457b1ba688e9854bdbed2f473f7510c476a3da09 +Deploying contract to address 0x457b1ba688e9854bdbed2f473f7510c476a3da09 Estimated gas: 12756792 ``` @@ -120,21 +120,21 @@ and see: ``` Compressed WASM size: 3 KB -Deploying program to address 0x457b1ba688e9854bdbed2f473f7510c476a3da09 +Deploying contract to address 0x457b1ba688e9854bdbed2f473f7510c476a3da09 Estimated gas: 12756792 Submitting tx... Confirmed tx 0x42db…7311, gas used 11657164 -Activating program at address 0x457b1ba688e9854bdbed2f473f7510c476a3da09 +Activating contract at address 0x457b1ba688e9854bdbed2f473f7510c476a3da09 Estimated gas: 14251759 Submitting tx... Confirmed tx 0x0bdb…3307, gas used 14204908 ``` -## Compiling and Checking Stylus Programs +## Compiling and Checking Stylus Contracts **cargo stylus check** -Instruments a Rust project using Stylus. This command runs compiled WASM code through Stylus instrumentation checks and reports any failures. It **verifies the program can compile onchain** by making an eth_call to a Arbitrum chain RPC endpoint. +Instruments a Rust project using Stylus. This command runs compiled WASM code through Stylus instrumentation checks and reports any failures. It **verifies the contract can compile onchain** by making an eth_call to a Arbitrum chain RPC endpoint. ``` Usage: cargo stylus check [OPTIONS] @@ -142,11 +142,11 @@ Usage: cargo stylus check [OPTIONS] See `--help` for all available flags and default values. -## Deploying Stylus Programs +## Deploying Stylus Contracts **cargo stylus deploy** -Instruments a Rust project using Stylus and by outputting its brotli-compressed WASM code. Then, it submits **two transactions** by default: the first **deploys** the WASM program code to an address and the second triggers an **activation onchain**. Developers can choose to split up the deploy and activate steps via this command as desired. +Instruments a Rust project using Stylus and by outputting its brotli-compressed WASM code. Then, it submits **two transactions** by default: the first **deploys** the WASM contract code to an address and the second triggers an **activation onchain**. Developers can choose to split up the deploy and activate steps via this command as desired. ``` Usage: cargo stylus deploy [OPTIONS] @@ -154,14 +154,14 @@ Usage: cargo stylus deploy [OPTIONS] See `--help` for all available flags and default values. -## Verifying Stylus Programs +## Verifying Stylus Contracts **cargo stylus verify** Verifies that a deployed smart contract is identical to that produced by the current project. Since Stylus smart contracts include a hash of all project files, this additionally verifies that code comments and other files are -identical. To ensure build reproducibility, if a program is to be verified, +identical. To ensure build reproducibility, if a contract is to be verified, it should be both deployed and verified using `cargo stylus reproducible`. See `--help` for all available flags and default values. @@ -209,9 +209,9 @@ cargo stylus export-abi ## Optimizing Binary Sizes -Brotli-compressed, Stylus program WASM binaries must fit within the **24Kb** [code-size limit](https://ethereum.org/en/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/) of Ethereum smart contracts. By default, the `cargo stylus check` will attempt to compile a Rust program into WASM with reasonable optimizations and verify its compressed size fits within the limit. However, there are additional options available in case a program exceeds the 24Kb limit from using default settings. Deploying smaller binaries onchain is cheaper and better for the overall network, as deployed WASM programs will exist on the Arbitrum chain's storage forever. +Brotli-compressed, Stylus contract WASM binaries must fit within the **24Kb** [code-size limit](https://ethereum.org/en/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/) of Ethereum smart contracts. By default, the `cargo stylus check` will attempt to compile a Rust contract into WASM with reasonable optimizations and verify its compressed size fits within the limit. However, there are additional options available in case a contract exceeds the 24Kb limit from using default settings. Deploying smaller binaries onchain is cheaper and better for the overall network, as deployed WASM contracts will exist on the Arbitrum chain's storage forever. -We recommend optimizing your Stylus program's sizes to smaller sizes, but keep in mind the safety tradeoffs of using some of the more advanced optimizations. However, some small programs when compiled to much smaller sizes can suffer performance penalties. +We recommend optimizing your Stylus contract's sizes to smaller sizes, but keep in mind the safety tradeoffs of using some of the more advanced optimizations. However, some small contracts when compiled to much smaller sizes can suffer performance penalties. For a deep-dive into the different options for optimizing binary sizes using cargo stylus, see [OPTIMIZING_BINARIES.md](./check/OPTIMIZING_BINARIES.md). diff --git a/check/OPTIMIZING_BINARIES.md b/check/OPTIMIZING_BINARIES.md index 45c66b3..24e2240 100644 --- a/check/OPTIMIZING_BINARIES.md +++ b/check/OPTIMIZING_BINARIES.md @@ -1,6 +1,6 @@ -# Optimizing Stylus Program WASM Binaries +# Optimizing Stylus Contract WASM Binaries -WASM programs need to be small to be deployed onchain. Stylus applies [brotli compression](https://github.com/google/brotli), which empirically reduces the footprint of common Rust WASMs by over 50%, the Stylus runtime obeys the EVM contract size limit of 24KB. This means that, after compression, **all WASMs must not exceed 24KB**. +WASM contracts need to be small to be deployed onchain. Stylus applies [brotli compression](https://github.com/google/brotli), which empirically reduces the footprint of common Rust WASMs by over 50%, the Stylus runtime obeys the EVM contract size limit of 24KB. This means that, after compression, **all WASMs must not exceed 24KB**. **Uncompressed WASM** files also have an enforced limit of **128Kb**. diff --git a/check/VALID_WASM.md b/check/VALID_WASM.md index 219246b..95b7ff9 100644 --- a/check/VALID_WASM.md +++ b/check/VALID_WASM.md @@ -1,8 +1,8 @@ -# Invalid Stylus WASM Programs +# Invalid Stylus WASM Contracts -This document explains the limitations of Stylus WASM programs and why certain programs might fail `cargo stylus check`. Stylus programs are bound by similar rules to Ethereum smart contracts when it comes to bounded execution, bounded memory use, and determinism. +This document explains the limitations of Stylus WASM contracts and why certain contracts might fail `cargo stylus check`. Stylus contracts are bound by similar rules to Ethereum smart contracts when it comes to bounded execution, bounded memory use, and determinism. -WASM programs must fit within the **24Kb** code size limit of Arbitrum chains _after_ compression. Uncompressed WASMs must have a size less than **128Kb**. +WASM contracts must fit within the **24Kb** code size limit of Arbitrum chains _after_ compression. Uncompressed WASMs must have a size less than **128Kb**. While Stylus includes a large portion of available WASM opcodes, not all of them are supported. To see the set of allowed / disallowed opcodes, see [here](https://github.com/OffchainLabs/stylus/blob/stylus/arbitrator/prover/src/wavm.rs#L731). @@ -15,4 +15,4 @@ When a user WASM gets "activated" on chain, it goes through a series of checks t 5. Check for **disallowed opcodes**, such as SIMD or other features 6. Disallow WASMs with an enormous amount of **functions and exports** -Stylus programs should use `#[no_std]` to avoid including the Rust standard library and keep code small. Many crates that build without the standard library make for great dependencies to use in Stylus programs, as long as the total, compressed WASM size is within the 24Kb code size limit. +Stylus contracts should use `#[no_std]` to avoid including the Rust standard library and keep code small. Many crates that build without the standard library make for great dependencies to use in Stylus contracts, as long as the total, compressed WASM size is within the 24Kb code size limit. diff --git a/check/src/activate.rs b/check/src/activate.rs index 8a80481..c84f59f 100644 --- a/check/src/activate.rs +++ b/check/src/activate.rs @@ -28,8 +28,8 @@ sol! { } } -/// Activates an already deployed Stylus program by address. -pub async fn activate_program(cfg: &ActivateConfig) -> Result<()> { +/// Activates an already deployed Stylus contract by address. +pub async fn activate_contract(cfg: &ActivateConfig) -> Result<()> { let provider = sys::new_provider(&cfg.common_cfg.endpoint)?; let chain_id = provider .get_chainid() @@ -54,8 +54,8 @@ pub async fn activate_program(cfg: &ActivateConfig) -> Result<()> { ); data_fee = bump_data_fee(data_fee, cfg.data_fee_bump_percent); - let program: Address = cfg.address.to_fixed_bytes().into(); - let data = ArbWasm::activateProgramCall { program }.abi_encode(); + let contract: Address = cfg.address.to_fixed_bytes().into(); + let data = ArbWasm::activateProgramCall { program: contract }.abi_encode(); let tx = Eip1559TransactionRequest::new() .from(client.address()) .to(*ARB_WASM_H160) @@ -66,14 +66,14 @@ pub async fn activate_program(cfg: &ActivateConfig) -> Result<()> { match tx.await? { Some(receipt) => { greyln!( - "successfully activated program 0x{} with tx {}", + "successfully activated contract 0x{} with tx {}", hex::encode(cfg.address), hex::encode(receipt.transaction_hash).debug_lavender() ); } None => { bail!( - "failed to fetch receipt for program activation {}", + "failed to fetch receipt for contract activation {}", cfg.address ); } diff --git a/check/src/cache.rs b/check/src/cache.rs index 607db6c..7d907e1 100644 --- a/check/src/cache.rs +++ b/check/src/cache.rs @@ -33,7 +33,7 @@ sol! { } } -pub async fn cache_program(cfg: &CacheConfig) -> Result<()> { +pub async fn cache_contract(cfg: &CacheConfig) -> Result<()> { let provider = sys::new_provider(&cfg.common_cfg.endpoint)?; let chain_id = provider .get_chainid() @@ -59,8 +59,8 @@ pub async fn cache_program(cfg: &CacheConfig) -> Result<()> { let cache_manager = *cache_manager_addrs.last().unwrap(); let cache_manager = H160::from_slice(cache_manager.as_slice()); - let program: Address = cfg.address.to_fixed_bytes().into(); - let data = CacheManager::placeBidCall { program }.abi_encode(); + let contract: Address = cfg.address.to_fixed_bytes().into(); + let data = CacheManager::placeBidCall { program: contract }.abi_encode(); let mut tx = Eip1559TransactionRequest::new() .to(cache_manager) .data(data); @@ -80,13 +80,13 @@ pub async fn cache_program(cfg: &CacheConfig) -> Result<()> { }; use CacheManager::CacheManagerErrors as C; match error { - C::AsmTooLarge(_) => bail!("program too large"), - C::AlreadyCached(_) => bail!("program already cached"), + C::AsmTooLarge(_) => bail!("Stylus contract was too large to cache"), + C::AlreadyCached(_) => bail!("Stylus contract is already cached"), C::BidsArePaused(_) => { - bail!("bidding is currently paused for the Stylus cache manager") + bail!("Bidding is currently paused for the Stylus cache manager") } C::BidTooSmall(_) => { - bail!("bid amount {} (wei) too small", cfg.bid.unwrap_or_default()) + bail!("Bid amount {} (wei) too small", cfg.bid.unwrap_or_default()) } } } @@ -106,11 +106,11 @@ pub async fn cache_program(cfg: &CacheConfig) -> Result<()> { if verbose { let gas = format_gas(receipt.gas_used.unwrap_or_default()); greyln!( - "Successfully cached program at address: {address} {} {gas}", + "Successfully cached contract at address: {address} {} {gas}", "with".grey() ); } else { - greyln!("Successfully cached program at address: {address}"); + greyln!("Successfully cached contract at address: {address}"); } let tx_hash = receipt.transaction_hash.debug_lavender(); greyln!("Sent Stylus cache tx with hash: {tx_hash}"); diff --git a/check/src/check.rs b/check/src/check.rs index 137a14d..0716e62 100644 --- a/check/src/check.rs +++ b/check/src/check.rs @@ -44,9 +44,9 @@ sol! { } } -/// Checks that a program is valid and can be deployed onchain. +/// Checks that a contract is valid and can be deployed onchain. /// Returns whether the WASM is already up-to-date and activated onchain, and the data fee. -pub async fn check(cfg: &CheckConfig) -> Result { +pub async fn check(cfg: &CheckConfig) -> Result { if cfg.common_cfg.endpoint == "https://stylus-testnet.arbitrum.io/rpc" { let version = "cargo stylus version 0.2.1".to_string().red(); bail!("The old Stylus testnet is no longer supported.\nPlease downgrade to {version}",); @@ -78,31 +78,31 @@ pub async fn check(cfg: &CheckConfig) -> Result { greyln!("connecting to RPC: {}", &cfg.common_cfg.endpoint.lavender()); } - // check if the program already exists + // Check if the contract already exists. let provider = sys::new_provider(&cfg.common_cfg.endpoint)?; let codehash = alloy_primitives::keccak256(&code); - if program_exists(codehash, &provider).await? { - return Ok(ProgramCheck::Active { code }); + if contract_exists(codehash, &provider).await? { + return Ok(ContractCheck::Active { code }); } - let address = cfg.program_address.unwrap_or(H160::random()); + let address = cfg.contract_address.unwrap_or(H160::random()); let fee = check_activate(code.clone().into(), address, &provider).await?; let visual_fee = format_data_fee(fee).unwrap_or("???".red()); greyln!("wasm data fee: {visual_fee}"); - Ok(ProgramCheck::Ready { code, fee }) + Ok(ContractCheck::Ready { code, fee }) } -/// Whether a program is active, or needs activation. +/// Whether a contract is active, or needs activation. #[derive(PartialEq)] -pub enum ProgramCheck { - /// Program already exists onchain. +pub enum ContractCheck { + /// Contract already exists onchain. Active { code: Vec }, - /// Program can be activated with the given data fee. + /// Contract can be activated with the given data fee. Ready { code: Vec, fee: U256 }, } -impl ProgramCheck { +impl ContractCheck { pub fn code(&self) -> &[u8] { match self { Self::Active { code, .. } => code, @@ -200,8 +200,8 @@ pub async fn eth_call( } } -/// Checks whether a program has already been activated with the most recent version of Stylus. -async fn program_exists(codehash: B256, provider: &Provider) -> Result { +/// Checks whether a contract has already been activated with the most recent version of Stylus. +async fn contract_exists(codehash: B256, provider: &Provider) -> Result { let data = ArbWasm::codehashVersionCall { codehash }.abi_encode(); let tx = Eip1559TransactionRequest::new() .to(*ARB_WASM_H160) @@ -220,7 +220,7 @@ async fn program_exists(codehash: B256, provider: &Provider) -> Result bail!("not a Stylus program"), + A::ProgramNotWasm(_) => bail!("not a Stylus contract"), A::ProgramNotActivated(_) | A::ProgramNeedsUpgrade(_) | A::ProgramExpired(_) => { return Ok(false); } @@ -240,10 +240,10 @@ async fn program_exists(codehash: B256, provider: &Provider) -> Result) -> Result { - let program = Address::from(address.to_fixed_bytes()); - let data = ArbWasm::activateProgramCall { program }.abi_encode(); + let contract = Address::from(address.to_fixed_bytes()); + let data = ArbWasm::activateProgramCall { program: contract }.abi_encode(); let tx = Eip1559TransactionRequest::new() .to(*ARB_WASM_H160) .data(data) diff --git a/check/src/constants.rs b/check/src/constants.rs index d2bb12a..b923821 100644 --- a/check/src/constants.rs +++ b/check/src/constants.rs @@ -8,7 +8,7 @@ use lazy_static::lazy_static; /// EOF prefix used in Stylus compressed WASMs on-chain pub const EOF_PREFIX_NO_DICT: &str = "EFF00000"; -/// Maximum brotli compression level used for Stylus programs. +/// Maximum brotli compression level used for Stylus contracts. pub const BROTLI_COMPRESSION_LEVEL: u32 = 11; lazy_static! { diff --git a/check/src/deploy.rs b/check/src/deploy.rs index 600de07..f146e0b 100644 --- a/check/src/deploy.rs +++ b/check/src/deploy.rs @@ -3,7 +3,7 @@ #![allow(clippy::println_empty_string)] use crate::{ - check::{self, ProgramCheck}, + check::{self, ContractCheck}, constants::ARB_WASM_H160, macros::*, DeployConfig, @@ -36,7 +36,7 @@ sol! { pub type SignerClient = SignerMiddleware, Wallet>; -/// Deploys a stylus program, activating if needed. +/// Deploys a stylus contract, activating if needed. pub async fn deploy(cfg: DeployConfig) -> Result<()> { macro_rules! run { ($expr:expr) => { @@ -47,7 +47,7 @@ pub async fn deploy(cfg: DeployConfig) -> Result<()> { }; } - let program = run!(check::check(&cfg.check_config), "cargo stylus check failed"); + let contract = run!(check::check(&cfg.check_config), "cargo stylus check failed"); let verbose = cfg.check_config.common_cfg.verbose; let client = sys::new_provider(&cfg.check_config.common_cfg.endpoint)?; @@ -62,9 +62,9 @@ pub async fn deploy(cfg: DeployConfig) -> Result<()> { greyln!("sender address: {}", sender.debug_lavender()); } - let data_fee = program.suggest_fee(); + let data_fee = contract.suggest_fee(); - if let ProgramCheck::Ready { .. } = &program { + if let ContractCheck::Ready { .. } = &contract { // check balance early let balance = run!(client.get_balance(sender, None), "failed to get balance"); let balance = alloy_ethers_typecast::ethers_u256_to_alloy(balance); @@ -82,11 +82,16 @@ pub async fn deploy(cfg: DeployConfig) -> Result<()> { } } - let contract = cfg.deploy_contract(program.code(), sender, &client).await?; + let contract_addr = cfg + .deploy_contract(contract.code(), sender, &client) + .await?; - match program { - ProgramCheck::Ready { .. } => cfg.activate(sender, contract, data_fee, &client).await?, - ProgramCheck::Active { .. } => greyln!("wasm already activated!"), + match contract { + ContractCheck::Ready { .. } => { + cfg.activate(sender, contract_addr, data_fee, &client) + .await? + } + ContractCheck::Active { .. } => greyln!("wasm already activated!"), } Ok(()) } @@ -98,7 +103,7 @@ impl DeployConfig { sender: H160, client: &SignerClient, ) -> Result { - let init_code = program_deployment_calldata(code); + let init_code = contract_deployment_calldata(code); let tx = Eip1559TransactionRequest::new() .from(sender) @@ -141,8 +146,8 @@ impl DeployConfig { let tx_hash = receipt.transaction_hash.debug_lavender(); greyln!("deployment tx hash: {tx_hash}"); println!( - r#"we recommend running cargo stylus cache --address={} to cache your activated program in ArbOS. -Cached programs benefit from cheaper calls. To read more about the Stylus program cache, see + r#"we recommend running cargo stylus cache --address={} to cache your activated contract in ArbOS. +Cached contracts benefit from cheaper calls. To read more about the Stylus contract cache, see https://docs.arbitrum.io/stylus/concepts/stylus-cache-manager"#, hex::encode(contract) ); @@ -158,9 +163,12 @@ https://docs.arbitrum.io/stylus/concepts/stylus-cache-manager"#, ) -> Result<()> { let verbose = self.check_config.common_cfg.verbose; let data_fee = alloy_ethers_typecast::alloy_u256_to_ethers(data_fee); - let program: Address = contract.to_fixed_bytes().into(); + let contract_addr: Address = contract.to_fixed_bytes().into(); - let data = ArbWasm::activateProgramCall { program }.abi_encode(); + let data = ArbWasm::activateProgramCall { + program: contract_addr, + } + .abi_encode(); let tx = Eip1559TransactionRequest::new() .from(sender) @@ -195,7 +203,7 @@ https://docs.arbitrum.io/stylus/concepts/stylus-cache-manager"#, greyln!("activated with {gas}"); } greyln!( - "program activated and ready onchain with tx hash: {}", + "contract activated and ready onchain with tx hash: {}", receipt.transaction_hash.debug_lavender() ); Ok(()) @@ -233,7 +241,7 @@ pub async fn run_tx( } /// Prepares an EVM bytecode prelude for contract creation. -pub fn program_deployment_calldata(code: &[u8]) -> Vec { +pub fn contract_deployment_calldata(code: &[u8]) -> Vec { let mut code_len = [0u8; 32]; U256::from(code.len()).to_big_endian(&mut code_len); let mut deploy: Vec = vec![]; @@ -253,7 +261,7 @@ pub fn program_deployment_calldata(code: &[u8]) -> Vec { deploy } -pub fn extract_program_evm_deployment_prelude(calldata: &[u8]) -> Vec { +pub fn extract_contract_evm_deployment_prelude(calldata: &[u8]) -> Vec { // The length of the prelude, version part is 42 + 1 as per the code let metadata_length = 42 + 1; // Extract and return the metadata part diff --git a/check/src/export_abi.rs b/check/src/export_abi.rs index d508395..2eb0eda 100644 --- a/check/src/export_abi.rs +++ b/check/src/export_abi.rs @@ -10,7 +10,7 @@ use std::{ process::{self, Command, Stdio}, }; -/// Exports Solidity ABIs by running the program natively. +/// Exports Solidity ABIs by running the contract natively. pub fn export_abi(file: Option, json: bool) -> Result<()> { if json && !sys::command_exists("solc") { let link = "https://docs.soliditylang.org/en/latest/installing-solidity.html".red(); @@ -30,7 +30,7 @@ pub fn export_abi(file: Option, json: bool) -> Result<()> { let out = (out != "") .then_some(format!(": {out}")) .unwrap_or_default(); - egreyln!("failed to run program{out}"); + egreyln!("failed to run contract {out}"); process::exit(1); } diff --git a/check/src/main.rs b/check/src/main.rs index a57b1c3..9f8912b 100644 --- a/check/src/main.rs +++ b/check/src/main.rs @@ -38,7 +38,7 @@ enum Apis { New { /// Project name. name: PathBuf, - /// Create a minimal program. + /// Create a minimal contract. #[arg(long)] minimal: bool, }, @@ -62,7 +62,7 @@ enum Apis { /// Deploy a contract. #[command(alias = "d")] Deploy(DeployConfig), - /// Verify the deployment of a Stylus program. + /// Verify the deployment of a Stylus contract. #[command(alias = "v")] Verify(VerifyConfig), } @@ -94,10 +94,10 @@ pub struct CacheConfig { /// Wallet source to use. #[command(flatten)] auth: AuthOpts, - /// Deployed and activated program address to cache. + /// Deployed and activated contract address to cache. #[arg(long)] address: H160, - /// Bid, in wei, to place on the desired program to cache + /// Bid, in wei, to place on the desired contract to cache #[arg(short, long, hide(true))] bid: Option, } @@ -109,7 +109,7 @@ pub struct ActivateConfig { /// Wallet source to use. #[command(flatten)] auth: AuthOpts, - /// Deployed Stylus program address to activate. + /// Deployed Stylus contract address to activate. #[arg(long)] address: H160, /// Percent to bump the estimated activation data fee by. Default of 20% @@ -124,9 +124,9 @@ pub struct CheckConfig { /// The WASM to check (defaults to any found in the current directory). #[arg(long)] wasm_file: Option, - /// Where to deploy and activate the program (defaults to a random address). + /// Where to deploy and activate the contract (defaults to a random address). #[arg(long)] - program_address: Option, + contract_address: Option, /// If specified, will not run the command in a reproducible docker container. Useful for local /// builds, but at the risk of not having a reproducible contract for verification purposes. #[arg(long)] @@ -212,8 +212,8 @@ impl fmt::Display for CheckConfig { Some(path) => format!("--wasm-file={}", path.display()), None => "".to_string(), }, - match &self.program_address { - Some(addr) => format!("--program-address={:?}", addr), + match &self.contract_address { + Some(addr) => format!("--contract-address={:?}", addr), None => "".to_string(), }, match self.no_verify { @@ -301,12 +301,12 @@ async fn main_impl(args: Opts) -> Result<()> { } Apis::Activate(config) => { run!( - activate::activate_program(&config).await, + activate::activate_contract(&config).await, "stylus activate failed" ); } Apis::Cache(config) => { - run!(cache::cache_program(&config).await, "stylus cache failed"); + run!(cache::cache_contract(&config).await, "stylus cache failed"); } Apis::Check(config) => { if config.no_verify { diff --git a/check/src/project.rs b/check/src/project.rs index 0530ca6..ee327ec 100644 --- a/check/src/project.rs +++ b/check/src/project.rs @@ -310,7 +310,7 @@ pub fn compress_wasm(wasm: &PathBuf, project_hash: [u8; 32]) -> Result<(Vec, // Adds the hash of the project's source files to the wasm as a custom section // if it does not already exist. This allows for reproducible builds by cargo stylus -// for all Rust stylus programs. See `cargo stylus verify --help` for more information. +// for all Rust stylus contracts. See `cargo stylus verify --help` for more information. fn add_project_hash_to_wasm_file( wasm_file_bytes: &[u8], project_hash: [u8; 32], diff --git a/check/src/verify.rs b/check/src/verify.rs index 8eee240..9c55f8b 100644 --- a/check/src/verify.rs +++ b/check/src/verify.rs @@ -15,7 +15,7 @@ use serde::{Deserialize, Serialize}; use crate::{ check, constants::TOOLCHAIN_FILE_NAME, - deploy::{self, extract_compressed_wasm, extract_program_evm_deployment_prelude}, + deploy::{self, extract_compressed_wasm, extract_contract_evm_deployment_prelude}, project::{self, extract_toolchain_channel}, CheckConfig, VerifyConfig, }; @@ -53,7 +53,7 @@ pub async fn verify(cfg: VerifyConfig) -> eyre::Result<()> { let check_cfg = CheckConfig { common_cfg: cfg.common_cfg.clone(), wasm_file: None, - program_address: None, + contract_address: None, no_verify: cfg.no_verify, }; let _ = check::check(&check_cfg) @@ -68,14 +68,14 @@ pub async fn verify(cfg: VerifyConfig) -> eyre::Result<()> { let project_hash = project::hash_files(cfg.common_cfg.source_files_for_project_hash, build_cfg)?; let (_, init_code) = project::compress_wasm(&wasm_file, project_hash)?; - let deployment_data = deploy::program_deployment_calldata(&init_code); + let deployment_data = deploy::contract_deployment_calldata(&init_code); if deployment_data == *result.input { - println!("Verified - program matches local project's file hashes"); + println!("Verified - contract matches local project's file hashes"); } else { - let tx_prelude = extract_program_evm_deployment_prelude(&result.input); - let reconstructed_prelude = extract_program_evm_deployment_prelude(&deployment_data); + let tx_prelude = extract_contract_evm_deployment_prelude(&result.input); + let reconstructed_prelude = extract_contract_evm_deployment_prelude(&deployment_data); println!( - "{} - program deployment did not verify against local project's file hashes", + "{} - contract deployment did not verify against local project's file hashes", "FAILED".red() ); if tx_prelude != reconstructed_prelude { diff --git a/main/src/main.rs b/main/src/main.rs index a6ee7d6..5240e1b 100644 --- a/main/src/main.rs +++ b/main/src/main.rs @@ -38,7 +38,7 @@ enum Subcommands { /// Check a contract. #[command(alias = "c")] Check, - /// Activate an already deployed program + /// Activate an already deployed contract #[command(alias = "a")] Activate, /// Deploy a contract. @@ -50,7 +50,7 @@ enum Subcommands { /// Trace a transaction. #[command()] Trace, - /// Verify the deployment of a Stylus program against a local project. + /// Verify the deployment of a Stylus contract against a local project. #[command(alias = "v")] Verify, /// Generate C code. diff --git a/replay/src/hostio.rs b/replay/src/hostio.rs index 1674ee4..ce03b56 100644 --- a/replay/src/hostio.rs +++ b/replay/src/hostio.rs @@ -37,7 +37,7 @@ macro_rules! copy { }; } -/// Reads the program calldata. The semantics are equivalent to that of the EVM's +/// Reads the contract calldata. The semantics are equivalent to that of the EVM's /// [`CALLDATA_COPY`] opcode when requesting the entirety of the current call's calldata. /// /// [`CALLDATA_COPY`]: https://www.evm.codes/#37 @@ -48,8 +48,8 @@ pub unsafe extern "C" fn read_args(dest: *mut u8) { copy!(args, dest, args.len()); } -/// Writes the final return data. If not called before the program exists, the return data will -/// be 0 bytes long. Note that this hostio does not cause the program to exit, which happens +/// Writes the final return data. If not called before the contract exists, the return data will +/// be 0 bytes long. Note that this hostio does not cause the contract to exit, which happens /// naturally when `user_entrypoint` returns. #[named] #[no_mangle] @@ -313,7 +313,7 @@ pub unsafe extern "C" fn static_call_contract( status } -/// Gets the address of the current program. The semantics are equivalent to that of the EVM's +/// Gets the address of the current contract. The semantics are equivalent to that of the EVM's /// [`ADDRESS`] opcode. /// /// [`ADDRESS`]: https://www.evm.codes/#30 @@ -326,9 +326,9 @@ pub unsafe extern "C" fn contract_address(dest: *mut u8) { /// Deploys a new contract using the init code provided, which the EVM executes to construct /// the code of the newly deployed contract. The init code must be written in EVM bytecode, but -/// the code it deploys can be that of a Stylus program. The code returned will be treated as +/// the code it deploys can be that of a Stylus contract. The code returned will be treated as /// WASM if it begins with the EOF-inspired header `0xEFF000`. Otherwise the code will be -/// interpreted as that of a traditional EVM-style contract. See [`Deploying Stylus Programs`] +/// interpreted as that of a traditional EVM-style contract. See [`Deploying Stylus Contracts`] /// for more information on writing init code. /// /// On success, this hostio returns the address of the newly created account whose address is @@ -337,7 +337,7 @@ pub unsafe extern "C" fn contract_address(dest: *mut u8) { /// `read_return_data` hostio. The semantics are equivalent to that of the EVM's [`CREATE`] /// opcode, which notably includes the exact address returned. /// -/// [`Deploying Stylus Programs`]: https://developer.arbitrum.io/TODO +/// [`Deploying Stylus Contracts`]: https://developer.arbitrum.io/TODO /// [`CREATE`]: https://www.evm.codes/#f0 #[named] #[no_mangle] @@ -362,9 +362,9 @@ pub unsafe extern "C" fn create1( /// Deploys a new contract using the init code provided, which the EVM executes to construct /// the code of the newly deployed contract. The init code must be written in EVM bytecode, but -/// the code it deploys can be that of a Stylus program. The code returned will be treated as +/// the code it deploys can be that of a Stylus contract. The code returned will be treated as /// WASM if it begins with the EOF-inspired header `0xEFF000`. Otherwise the code will be -/// interpreted as that of a traditional EVM-style contract. See [`Deploying Stylus Programs`] +/// interpreted as that of a traditional EVM-style contract. See [`Deploying Stylus Contracts`] /// for more information on writing init code. /// /// On success, this hostio returns the address of the newly created account whose address is a @@ -373,7 +373,7 @@ pub unsafe extern "C" fn create1( /// via the `read_return_data` hostio. The semantics are equivalent to that of the EVM's /// `[CREATE2`] opcode, which notably includes the exact address returned. /// -/// [`Deploying Stylus Programs`]: https://developer.arbitrum.io/TODO +/// [`Deploying Stylus Contracts`]: https://developer.arbitrum.io/TODO /// [`CREATE2`]: https://www.evm.codes/#f5 #[named] #[no_mangle] @@ -442,7 +442,7 @@ pub unsafe extern "C" fn evm_ink_left() -> u64 { } /// The `entrypoint!` macro handles importing this hostio, which is required if the -/// program's memory grows. Otherwise compilation through the `ArbWasm` precompile will revert. +/// contract's memory grows. Otherwise compilation through the `ArbWasm` precompile will revert. /// Internally the Stylus VM forces calls to this hostio whenever new WASM pages are allocated. /// Calls made voluntarily will unproductively consume gas. #[named] @@ -460,7 +460,7 @@ pub unsafe extern "C" fn msg_reentrant() -> bool { reentrant } -/// Gets the address of the account that called the program. For normal L2-to-L2 transactions +/// Gets the address of the account that called the contract. For normal L2-to-L2 transactions /// the semantics are equivalent to that of the EVM's [`CALLER`] opcode, including in cases /// arising from [`DELEGATE_CALL`]. /// @@ -477,7 +477,7 @@ pub unsafe extern "C" fn msg_sender(dest: *mut u8) { copy!(sender, dest); } -/// Get the ETH value in wei sent to the program. The semantics are equivalent to that of the +/// Get the ETH value in wei sent to the contract. The semantics are equivalent to that of the /// EVM's [`CALLVALUE`] opcode. /// /// [`CALLVALUE`]: https://www.evm.codes/#34 @@ -521,7 +521,7 @@ pub unsafe extern "C" fn read_return_data( } /// Returns the length of the last EVM call or deployment return result, or `0` if neither have -/// happened during the program's execution. The semantics are equivalent to that of the EVM's +/// happened during the contract's execution. The semantics are equivalent to that of the EVM's /// [`RETURN_DATA_SIZE`] opcode. /// /// [`RETURN_DATA_SIZE`]: https://www.evm.codes/#3d diff --git a/replay/src/trace.rs b/replay/src/trace.rs index fecd5c6..37fc656 100644 --- a/replay/src/trace.rs +++ b/replay/src/trace.rs @@ -44,13 +44,13 @@ impl Trace { if let Value::Array(arr) = json.clone() { if arr.is_empty() { - bail!("No trace frames found, perhaps you are attempting to trace the program deployment transaction"); + bail!("No trace frames found, perhaps you are attempting to trace the contract deployment transaction"); } } let maybe_activation_trace: Result, _> = from_value(json.clone()); if maybe_activation_trace.is_ok() { - bail!("Your tx was a program activation transaction. It has no trace frames"); + bail!("Your tx was a contract activation transaction. It has no trace frames"); } let to = receipt.to.map(|x| Address::from(x.0)); From a3f203e5abe4c2417e1a3bed7018af63f4509bd8 Mon Sep 17 00:00:00 2001 From: Gabriel de Quadros Ligneul <8294320+gligneul@users.noreply.github.com> Date: Tue, 13 Aug 2024 17:39:57 -0300 Subject: [PATCH 29/35] Update Stylus Replay with changes on the HostIO API (#73) We introduced some changes to the HostIO API on the nitro repository. This commit updates the Stylus Replay tool to reflect these changes. Co-authored-by: Raul Jordan --- replay/src/hostio.rs | 227 ++++++++++++++++++++++++++++++++++++------- replay/src/trace.rs | 133 ++++++++++++++++++++----- 2 files changed, 299 insertions(+), 61 deletions(-) diff --git a/replay/src/hostio.rs b/replay/src/hostio.rs index ce03b56..d47b218 100644 --- a/replay/src/hostio.rs +++ b/replay/src/hostio.rs @@ -53,11 +53,26 @@ pub unsafe extern "C" fn read_args(dest: *mut u8) { /// naturally when `user_entrypoint` returns. #[named] #[no_mangle] -pub unsafe extern "C" fn write_result(data: *const u8, len: usize) { +pub unsafe extern "C" fn write_result(data: *const u8, len: u32) { frame!(WriteResult { result }); assert_eq!(read_bytes(data, len), &*result); } +/// Exits program execution early with the given status code. +/// If `0`, the program returns successfully with any data supplied by `write_result`. +/// Otherwise, the program reverts and treats any `write_result` data as revert data. +/// +/// The semantics are equivalent to that of the EVM's [`Return`] and [`Revert`] opcodes. +/// Note: this function just traces, it's up to the caller to actually perform the exit. +/// +/// [`Return`]: https://www.evm.codes/#f3 +/// [`Revert`]: https://www.evm.codes/#fd +#[named] +#[no_mangle] +pub unsafe extern "C" fn exit_early(status: u32) { + frame!(ExitEarly { status }); +} + /// Reads a 32-byte value from permanent storage. Stylus's storage format is identical to /// that of the EVM. This means that, under the hood, this hostio is accessing the 32-byte /// value stored in the EVM state trie at offset `key`, which will be `0` when not previously @@ -72,32 +87,61 @@ pub unsafe extern "C" fn storage_load_bytes32(key_ptr: *const u8, dest: *mut u8) copy!(value, dest); } -/// Stores a 32-byte value to permanent storage. Stylus's storage format is identical to that -/// of the EVM. This means that, under the hood, this hostio is storing a 32-byte value into -/// the EVM state trie at offset `key`. Furthermore, refunds are tabulated exactly as in the -/// EVM. The semantics, then, are equivalent to that of the EVM's [`SSTORE`] opcode. +/// Writes a 32-byte value to the permanent storage cache. Stylus's storage format is identical to that +/// of the EVM. This means that, under the hood, this hostio represents storing a 32-byte value into +/// the EVM state trie at offset `key`. Refunds are tabulated exactly as in the EVM. The semantics, then, +/// are equivalent to that of the EVM's [`SSTORE`] opcode. +/// +/// Note: because this value is cached, one must call `storage_flush_cache` to persist the value. +/// +/// Auditor's note: we require the [`SSTORE`] sentry per EVM rules. The `gas_cost` returned by the EVM API +/// may exceed this amount, but that's ok because the predominant cost is due to state bloat concerns. /// /// [`SSTORE`]: https://www.evm.codes/#55 #[named] #[no_mangle] -pub unsafe extern "C" fn storage_store_bytes32(key_ptr: *const u8, value_ptr: *const u8) { - frame!(StorageStoreBytes32 { key, value }); +pub unsafe extern "C" fn storage_cache_bytes32(key_ptr: *const u8, value_ptr: *const u8) { + frame!(StorageCacheBytes32 { key, value }); assert_eq!(read_fixed(key_ptr), key); assert_eq!(read_fixed(value_ptr), value); } +/// Persists any dirty values in the storage cache to the EVM state trie, dropping the cache entirely if requested. +/// Analogous to repeated invocations of [`SSTORE`]. +/// +/// [`SSTORE`]: https://www.evm.codes/#55 #[named] #[no_mangle] -pub unsafe extern "C" fn storage_cache_bytes32(key_ptr: *const u8, value_ptr: *const u8) { - frame!(StorageCacheBytes32 { key, value }); +pub unsafe extern "C" fn storage_flush_cache(clear: u32) { + frame!(StorageFlushCache { clear }); +} + +/// Reads a 32-byte value from transient storage. Stylus's storage format is identical to +/// that of the EVM. This means that, under the hood, this hostio is accessing the 32-byte +/// value stored in the EVM's transient state trie at offset `key`, which will be `0` when not previously +/// set. The semantics, then, are equivalent to that of the EVM's [`TLOAD`] opcode. +/// +/// [`TLOAD`]: https://www.evm.codes/#5c +#[named] +#[no_mangle] +pub unsafe extern "C" fn transient_load_bytes32(key_ptr: *const u8, dest: *mut u8) { + frame!(TransientLoadBytes32 { key, value }); assert_eq!(read_fixed(key_ptr), key); - assert_eq!(read_fixed(value_ptr), value); + copy!(value, dest); } +/// Writes a 32-byte value to transient storage. Stylus's storage format is identical to that +/// of the EVM. This means that, under the hood, this hostio represents storing a 32-byte value into +/// the EVM's transient state trie at offset `key`. The semantics, then, are equivalent to that of the +/// EVM's [`TSTORE`] opcode. +/// +/// [`TSTORE`]: https://www.evm.codes/#5d #[named] #[no_mangle] -pub unsafe extern "C" fn storage_flush_cache(clear: u32) { - frame!(StorageFlushCache { clear }); +pub unsafe extern "C" fn transient_store_bytes32(key_ptr: *const u8, value_ptr: *const u8) { + frame!(TransientStoreBytes32 { key, value }); + assert_eq!(read_fixed(key_ptr), key); + assert_eq!(read_fixed(value_ptr), value); } /// Gets the ETH balance in wei of the account at the given address. @@ -112,6 +156,45 @@ pub unsafe extern "C" fn account_balance(address_ptr: *const u8, dest: *mut u8) copy!(balance.to_be_bytes::<32>(), dest); } +/// Gets a subset of the code from the account at the given address. The semantics are identical to that +/// of the EVM's [`EXT_CODE_COPY`] opcode, aside from one small detail: the write to the buffer `dest` will +/// stop after the last byte is written. This is unlike the EVM, which right pads with zeros in this scenario. +/// The return value is the number of bytes written, which allows the caller to detect if this has occured. +/// +/// [`EXT_CODE_COPY`]: https://www.evm.codes/#3C +#[named] +#[no_mangle] +pub unsafe extern "C" fn account_code( + address_ptr: *const u8, + offset_recv: u32, + size_recv: u32, + dest: *mut u8, +) -> u32 { + frame!(AccountCode { + address, + offset, + size, + code + }); + assert_eq!(offset_recv, offset); + assert_eq!(size_recv, size); + assert_eq!(read_fixed(address_ptr), address); + copy!(code, dest); + code.len() as u32 +} + +/// Gets the size of the code in bytes at the given address. The semantics are equivalent +/// to that of the EVM's [`EXT_CODESIZE`]. +/// +/// [`EXT_CODESIZE`]: https://www.evm.codes/#3B +#[named] +#[no_mangle] +pub unsafe extern "C" fn account_code_size(address_ptr: *const u8) -> u32 { + frame!(AccountCodeSize { address, size }); + assert_eq!(read_fixed(address_ptr), address); + size +} + /// Gets the code hash of the account at the given address. The semantics are equivalent /// to that of the EVM's [`EXT_CODEHASH`] opcode. Note that the code hash of an account without /// code will be the empty hash @@ -215,10 +298,10 @@ pub unsafe extern "C" fn chainid() -> u64 { pub unsafe extern "C" fn call_contract( address_ptr: *const u8, calldata: *const u8, - calldata_len: usize, + calldata_len: u32, value_ptr: *const u8, gas_supplied: u64, - return_data_len: *mut usize, + return_data_len: *mut u32, ) -> u8 { frame!(CallContract { address, @@ -233,7 +316,7 @@ pub unsafe extern "C" fn call_contract( assert_eq!(read_bytes(calldata, calldata_len), &*data); assert_eq!(read_fixed(value_ptr), value.to_be_bytes::<32>()); assert_eq!(gas_supplied, gas); - *return_data_len = outs_len as usize; + *return_data_len = outs_len; status } @@ -256,9 +339,9 @@ pub unsafe extern "C" fn call_contract( pub unsafe extern "C" fn delegate_call_contract( address_ptr: *const u8, calldata: *const u8, - calldata_len: usize, + calldata_len: u32, gas_supplied: u64, - return_data_len: *mut usize, + return_data_len: *mut u32, ) -> u8 { frame!(DelegateCallContract { address, @@ -271,7 +354,7 @@ pub unsafe extern "C" fn delegate_call_contract( assert_eq!(read_fixed(address_ptr), address); assert_eq!(read_bytes(calldata, calldata_len), &*data); assert_eq!(gas_supplied, gas); - *return_data_len = outs_len as usize; + *return_data_len = outs_len; status } @@ -294,9 +377,9 @@ pub unsafe extern "C" fn delegate_call_contract( pub unsafe extern "C" fn static_call_contract( address_ptr: *const u8, calldata: *const u8, - calldata_len: usize, + calldata_len: u32, gas_supplied: u64, - return_data_len: *mut usize, + return_data_len: *mut u32, ) -> u8 { frame!(StaticCallContract { address, @@ -309,7 +392,7 @@ pub unsafe extern "C" fn static_call_contract( assert_eq!(read_fixed(address_ptr), address); assert_eq!(read_bytes(calldata, calldata_len), &*data); assert_eq!(gas_supplied, gas); - *return_data_len = outs_len as usize; + *return_data_len = outs_len; status } @@ -343,10 +426,10 @@ pub unsafe extern "C" fn contract_address(dest: *mut u8) { #[no_mangle] pub unsafe extern "C" fn create1( code_ptr: *const u8, - code_len: usize, + code_len: u32, value: *const u8, contract: *mut u8, - revert_data_len_ptr: *mut usize, + revert_data_len_ptr: *mut u32, ) { frame!(Create1 { code, @@ -379,11 +462,11 @@ pub unsafe extern "C" fn create1( #[no_mangle] pub unsafe extern "C" fn create2( code_ptr: *const u8, - code_len: usize, + code_len: u32, value_ptr: *const u8, salt_ptr: *const u8, contract: *mut u8, - revert_data_len_ptr: *mut usize, + revert_data_len_ptr: *mut u32, ) { frame!(Create2 { code, @@ -411,7 +494,7 @@ pub unsafe extern "C" fn create2( /// [`LOG4`]: https://www.evm.codes/#a4 #[named] #[no_mangle] -pub unsafe extern "C" fn emit_log(data_ptr: *const u8, len: usize, topic_count: usize) { +pub unsafe extern "C" fn emit_log(data_ptr: *const u8, len: u32, topic_count: u32) { frame!(EmitLog { data, topics }); assert_eq!(read_bytes(data_ptr, len), &*data); assert_eq!(topics, topic_count); @@ -452,6 +535,77 @@ pub unsafe extern "C" fn pay_for_memory_grow(new_pages: u16) { assert_eq!(new_pages, pages); } +/// Computes `value ÷ exponent` using 256-bit math, writing the result to the first. +/// The semantics are equivalent to that of the EVM's [`DIV`] opcode, which means that a `divisor` of `0` +/// writes `0` to `value`. +/// +/// [`DIV`]: https://www.evm.codes/#04 +#[named] +#[no_mangle] +pub unsafe fn math_div(value: *mut u8, divisor: *const u8) { + frame!(MathDiv { a, b, result }); + assert_eq!(read_fixed(value), a.to_be_bytes::<32>()); + assert_eq!(read_fixed(divisor), b.to_be_bytes::<32>()); + copy!(result.to_be_bytes::<32>(), value); +} + +/// Computes `value % exponent` using 256-bit math, writing the result to the first. +/// The semantics are equivalent to that of the EVM's [`MOD`] opcode, which means that a `modulus` of `0` +/// writes `0` to `value`. +/// +/// [`MOD`]: https://www.evm.codes/#06 +#[named] +#[no_mangle] +pub unsafe fn math_mod(value: *mut u8, modulus: *const u8) { + frame!(MathMod { a, b, result }); + assert_eq!(read_fixed(value), a.to_be_bytes::<32>()); + assert_eq!(read_fixed(modulus), b.to_be_bytes::<32>()); + copy!(result.to_be_bytes::<32>(), value); +} + +/// Computes `value ^ exponent` using 256-bit math, writing the result to the first. +/// The semantics are equivalent to that of the EVM's [`EXP`] opcode. +/// +/// [`EXP`]: https://www.evm.codes/#0A +#[named] +#[no_mangle] +pub unsafe fn math_pow(value: *mut u8, exponent: *const u8) { + frame!(MathPow { a, b, result }); + assert_eq!(read_fixed(value), a.to_be_bytes::<32>()); + assert_eq!(read_fixed(exponent), b.to_be_bytes::<32>()); + copy!(result.to_be_bytes::<32>(), value); +} + +/// Computes `(value + addend) % modulus` using 256-bit math, writing the result to the first. +/// The semantics are equivalent to that of the EVM's [`ADDMOD`] opcode, which means that a `modulus` of `0` +/// writes `0` to `value`. +/// +/// [`ADDMOD`]: https://www.evm.codes/#08 +#[named] +#[no_mangle] +pub unsafe fn math_add_mod(value: *mut u8, addend: *const u8, modulus: *const u8) { + frame!(MathAddMod { a, b, c, result }); + assert_eq!(read_fixed(value), a.to_be_bytes::<32>()); + assert_eq!(read_fixed(addend), b.to_be_bytes::<32>()); + assert_eq!(read_fixed(modulus), c.to_be_bytes::<32>()); + copy!(result.to_be_bytes::<32>(), value); +} + +/// Computes `(value * multiplier) % modulus` using 256-bit math, writing the result to the first. +/// The semantics are equivalent to that of the EVM's [`MULMOD`] opcode, which means that a `modulus` of `0` +/// writes `0` to `value`. +/// +/// [`MULMOD`]: https://www.evm.codes/#09 +#[named] +#[no_mangle] +pub unsafe fn math_mul_mod(value: *mut u8, multiplier: *const u8, modulus: *const u8) { + frame!(MathAddMod { a, b, c, result }); + assert_eq!(read_fixed(value), a.to_be_bytes::<32>()); + assert_eq!(read_fixed(multiplier), b.to_be_bytes::<32>()); + assert_eq!(read_fixed(modulus), c.to_be_bytes::<32>()); + copy!(result.to_be_bytes::<32>(), value); +} + /// Whether the current call is reentrant. #[named] #[no_mangle] @@ -495,7 +649,7 @@ pub unsafe extern "C" fn msg_value(dest: *mut u8) { /// [`SHA3`]: https://www.evm.codes/#20 #[named] #[no_mangle] -pub unsafe extern "C" fn native_keccak256(bytes: *const u8, len: usize, output: *mut u8) { +pub unsafe extern "C" fn native_keccak256(bytes: *const u8, len: u32, output: *mut u8) { frame!(NativeKeccak256 { preimage, digest }); assert_eq!(read_bytes(bytes, len), &*preimage); copy!(digest, output); @@ -510,14 +664,14 @@ pub unsafe extern "C" fn native_keccak256(bytes: *const u8, len: usize, output: #[no_mangle] pub unsafe extern "C" fn read_return_data( dest: *mut u8, - offset_value: usize, - size_value: usize, -) -> usize { + offset_value: u32, + size_value: u32, +) -> u32 { frame!(ReadReturnData { offset, size, data }); - assert_eq!(offset_value, offset as usize); - assert_eq!(size_value, size as usize); + assert_eq!(offset_value, offset); + assert_eq!(size_value, size); copy!(data, dest, data.len()); - data.len() + data.len() as u32 } /// Returns the length of the last EVM call or deployment return result, or `0` if neither have @@ -527,7 +681,7 @@ pub unsafe extern "C" fn read_return_data( /// [`RETURN_DATA_SIZE`]: https://www.evm.codes/#3d #[named] #[no_mangle] -pub unsafe extern "C" fn return_data_size() -> usize { +pub unsafe extern "C" fn return_data_size() -> u32 { frame!(ReturnDataSize { size }); size } @@ -604,7 +758,7 @@ pub unsafe extern "C" fn log_i64(value: i64) { /// Prints a UTF-8 encoded string to the console. Only available in debug mode. #[named] #[no_mangle] -pub unsafe extern "C" fn log_txt(text_ptr: *const u8, len: usize) { +pub unsafe extern "C" fn log_txt(text_ptr: *const u8, len: u32) { frame!(ConsoleLogText { text }); assert_eq!(read_bytes(text_ptr, len), &*text); } @@ -615,7 +769,8 @@ unsafe fn read_fixed(ptr: *const u8) -> [u8; N] { value.assume_init() } -unsafe fn read_bytes(ptr: *const u8, len: usize) -> Vec { +unsafe fn read_bytes(ptr: *const u8, len: u32) -> Vec { + let len = len as usize; let mut data = Vec::with_capacity(len); memcpy(ptr, data.as_mut_ptr(), len); data.set_len(len); diff --git a/replay/src/trace.rs b/replay/src/trace.rs index 37fc656..f7b9bb2 100644 --- a/replay/src/trace.rs +++ b/replay/src/trace.rs @@ -3,7 +3,7 @@ #![allow(clippy::redundant_closure_call)] -use alloy_primitives::{Address, FixedBytes, TxHash, B256, U256}; +use alloy_primitives::{Address, TxHash, B256, U256}; use cargo_stylus_util::color::{Color, DebugColor}; use ethers::{ providers::{JsonRpcClient, Middleware, Provider}, @@ -205,11 +205,6 @@ impl TraceFrame { read_num!($src, u64) }; } - macro_rules! read_usize { - ($src:ident) => { - read_num!($src, usize) - }; - } macro_rules! frame { () => {{ @@ -241,14 +236,13 @@ impl TraceFrame { "write_result" => WriteResult { result: read_data!(args), }, + "exit_early" => ExitEarly { + status: read_u32!(args), + }, "storage_load_bytes32" => StorageLoadBytes32 { key: read_b256!(args), value: read_b256!(outs), }, - "storage_store_bytes32" => StorageStoreBytes32 { - key: read_b256!(args), - value: read_b256!(args), - }, "storage_cache_bytes32" => StorageCacheBytes32 { key: read_b256!(args), value: read_b256!(args), @@ -256,10 +250,28 @@ impl TraceFrame { "storage_flush_cache" => StorageFlushCache { clear: read_u8!(args), }, + "transient_load_bytes32" => TransientLoadBytes32 { + key: read_b256!(args), + value: read_b256!(outs), + }, + "transient_store_bytes32" => TransientStoreBytes32 { + key: read_b256!(args), + value: read_b256!(args), + }, "account_balance" => AccountBalance { address: read_address!(args), balance: read_u256!(outs), }, + "account_code" => AccountCode { + address: read_address!(args), + offset: read_u32!(args), + size: read_u32!(args), + code: read_data!(outs), + }, + "account_code_size" => AccountCodeSize { + address: read_address!(args), + size: read_u32!(outs), + }, "account_codehash" => AccountCodehash { address: read_address!(args), codehash: read_b256!(outs), @@ -291,6 +303,33 @@ impl TraceFrame { "evm_ink_left" => EvmInkLeft { ink_left: read_u64!(outs), }, + "math_div" => MathDiv { + a: read_u256!(args), + b: read_u256!(args), + result: read_u256!(outs), + }, + "math_mod" => MathMod { + a: read_u256!(args), + b: read_u256!(args), + result: read_u256!(outs), + }, + "math_pow" => MathPow { + a: read_u256!(args), + b: read_u256!(args), + result: read_u256!(outs), + }, + "math_add_mod" => MathAddMod { + a: read_u256!(args), + b: read_u256!(args), + c: read_u256!(args), + result: read_u256!(outs), + }, + "math_mul_mod" => MathMulMod { + a: read_u256!(args), + b: read_u256!(args), + c: read_u256!(args), + result: read_u256!(outs), + }, "msg_reentrant" => MsgReentrant { reentrant: read_u32!(outs) != 0, }, @@ -313,7 +352,7 @@ impl TraceFrame { "tx_origin" => TxOrigin { origin: read_address!(outs), }, - "memory_grow" => PayForMemoryGrow { + "pay_for_memory_grow" => PayForMemoryGrow { pages: read_u16!(args), }, "call_contract" => CallContract { @@ -345,17 +384,17 @@ impl TraceFrame { endowment: read_u256!(args), code: read_data!(args), address: read_address!(outs), - revert_data_len: read_usize!(outs), + revert_data_len: read_u32!(outs), }, "create2" => Create2 { endowment: read_u256!(args), salt: read_b256!(args), code: read_data!(args), address: read_address!(outs), - revert_data_len: read_usize!(outs), + revert_data_len: read_u32!(outs), }, "emit_log" => EmitLog { - topics: read_usize!(args), + topics: read_u32!(args), data: read_data!(args), }, "read_return_data" => ReadReturnData { @@ -364,7 +403,7 @@ impl TraceFrame { data: read_data!(outs), }, "return_data_size" => ReturnDataSize { - size: read_usize!(outs), + size: read_u32!(outs), }, "console_log_text" => ConsoleLogText { text: read_data!(args), @@ -410,25 +449,42 @@ pub enum HostioKind { WriteResult { result: Box<[u8]>, }, + ExitEarly { + status: u32, + }, StorageLoadBytes32 { key: B256, value: B256, }, - StorageStoreBytes32 { + StorageCacheBytes32 { key: B256, value: B256, }, - StorageCacheBytes32 { - key: FixedBytes<32>, - value: FixedBytes<32>, - }, StorageFlushCache { clear: u8, }, + TransientLoadBytes32 { + key: B256, + value: B256, + }, + TransientStoreBytes32 { + key: B256, + value: B256, + }, AccountBalance { address: Address, balance: U256, }, + AccountCode { + address: Address, + offset: u32, + size: u32, + code: Box<[u8]>, + }, + AccountCodeSize { + address: Address, + size: u32, + }, AccountCodehash { address: Address, codehash: B256, @@ -463,6 +519,33 @@ pub enum HostioKind { PayForMemoryGrow { pages: u16, }, + MathDiv { + a: U256, + b: U256, + result: U256, + }, + MathMod { + a: U256, + b: U256, + result: U256, + }, + MathPow { + a: U256, + b: U256, + result: U256, + }, + MathAddMod { + a: U256, + b: U256, + c: U256, + result: U256, + }, + MathMulMod { + a: U256, + b: U256, + c: U256, + result: U256, + }, MsgReentrant { reentrant: bool, }, @@ -520,18 +603,18 @@ pub enum HostioKind { code: Box<[u8]>, endowment: U256, address: Address, - revert_data_len: usize, + revert_data_len: u32, }, Create2 { code: Box<[u8]>, endowment: U256, salt: B256, address: Address, - revert_data_len: usize, + revert_data_len: u32, }, EmitLog { data: Box<[u8]>, - topics: usize, + topics: u32, }, ReadReturnData { offset: u32, @@ -539,7 +622,7 @@ pub enum HostioKind { data: Box<[u8]>, }, ReturnDataSize { - size: usize, + size: u32, }, } @@ -583,7 +666,7 @@ impl FrameReader { let kind = hostio.kind; let name = kind.name(); match name { - "memory_grow" | "user_entrypoint" | "user_returned" => continue, + "pay_for_memory_grow" | "user_entrypoint" | "user_returned" => continue, _ => { detected(self, expected); println!("However, onchain there's a call to {name}. Are you sure this the right contract?\n"); From 5ccf086451c3db610803cd91fbaa580078d65dd5 Mon Sep 17 00:00:00 2001 From: Mark_Jeong <81726531+markjung96@users.noreply.github.com> Date: Wed, 14 Aug 2024 17:35:52 +0900 Subject: [PATCH 30/35] feat: activate export tx_data --- check/src/activate.rs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/check/src/activate.rs b/check/src/activate.rs index 0cb1122..af6c953 100644 --- a/check/src/activate.rs +++ b/check/src/activate.rs @@ -54,16 +54,6 @@ sol! { type SignerClient = SignerMiddleware, Wallet>; -/// Deploys a stylus program, activating if needed. -pub async fn activate(cfg: ActivateConfig) -> Result<()> { - greyln!("@@@ activate"); - let contract = cfg.address; - let program: Address = contract.to_fixed_bytes().into(); - let data = ArbWasm::activateProgramCall { program }.abi_encode(); - write_tx_data(TxKind::Activation, &data)?; - Ok(()) -} - fn write_tx_data(tx_kind: TxKind, data: &[u8]) -> eyre::Result<()> { let file_name = format!("{tx_kind}_tx_data"); let mut path = PathBuf::new(); @@ -133,6 +123,9 @@ pub async fn activate_contract(cfg: &ActivateConfig) -> Result<()> { hex::encode(cfg.address), hex::encode(receipt.transaction_hash).debug_lavender() ); + let program: Address = cfg.address.to_fixed_bytes().into(); + let data = ArbWasm::activateProgramCall { program }.abi_encode(); + wrtie_tx_data(TxKind::Activation, &data)?; } None => { bail!( From 1f255180c1e17d9015759a3ebdd5100a86ff9d2b Mon Sep 17 00:00:00 2001 From: Gabriel de Quadros Ligneul <8294320+gligneul@users.noreply.github.com> Date: Thu, 15 Aug 2024 12:35:39 -0300 Subject: [PATCH 31/35] Add replay command to install script (#75) --- install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install.sh b/install.sh index 682f003..99aee25 100755 --- a/install.sh +++ b/install.sh @@ -3,3 +3,4 @@ cargo clippy --package cargo-stylus --package cargo-stylus-cgen --package cargo- cargo install --path main cargo install --path cgen cargo install --path check +cargo install --path replay From 28b7df41bcbc35d34ca35ed912ec7ded5cdde2e5 Mon Sep 17 00:00:00 2001 From: Gabriel de Quadros Ligneul <8294320+gligneul@users.noreply.github.com> Date: Thu, 15 Aug 2024 17:19:18 -0300 Subject: [PATCH 32/35] Trim white spaces when reading private key (#77) This solves a common problem when there is an extra new-line in the private key file. For instance: Error: stylus deploy failed Caused by: 0: failed to load wallet 1: invalid private key 2: Odd number of digits --- util/src/text.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/util/src/text.rs b/util/src/text.rs index c4dd11c..c4a7e3f 100644 --- a/util/src/text.rs +++ b/util/src/text.rs @@ -5,6 +5,7 @@ use eyre::Result; pub fn decode0x>(text: T) -> Result> { let text = text.as_ref(); + let text = text.trim(); let text = text.strip_prefix("0x").unwrap_or(text); Ok(hex::decode(text)?) } From 16ace97ff52ace306e4ddc6484248dc7eb7aa5ae Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Thu, 15 Aug 2024 18:11:19 -0500 Subject: [PATCH 33/35] Miscellaneous Issue Resolution (#70) * misc fixes * check cache on unactivated * commentary * edits * add init command * use cargo stylus base * base rust * misc fixes * fix up docker * better error * cargo stylus check no docker * edit * use proper image * comment --- README.md | 19 +------------- check/Dockerfile | 7 ----- check/src/cache.rs | 4 +++ check/src/check.rs | 6 +++++ check/src/constants.rs | 5 ---- check/src/deploy.rs | 2 +- check/src/docker.rs | 25 +++++------------- check/src/main.rs | 58 +++++++++++++++++++++--------------------- check/src/new.rs | 28 ++++++++++++++++++++ check/src/project.rs | 7 ----- check/src/verify.rs | 1 - main/src/main.rs | 8 +++++- replay/src/main.rs | 7 ++--- 13 files changed, 84 insertions(+), 93 deletions(-) delete mode 100644 check/Dockerfile diff --git a/README.md b/README.md index bdd0228..fcca0c6 100644 --- a/README.md +++ b/README.md @@ -156,24 +156,7 @@ See `--help` for all available flags and default values. ## Verifying Stylus Contracts -**cargo stylus verify** - -Verifies that a deployed smart contract is identical to that produced by the -current project. Since Stylus smart contracts include a hash of all project -files, this additionally verifies that code comments and other files are -identical. To ensure build reproducibility, if a contract is to be verified, -it should be both deployed and verified using `cargo stylus reproducible`. - -See `--help` for all available flags and default values. - -## Reproducibly Deploying and Verifying - -**cargo stylus reproducible** - -Runs a `cargo stylus` command in a Docker container to ensure build -reproducibility. - -See `--help` for all available flags and default values. +See [here](https://hackmd.io/bpeMnrzbSvO4mohhvkrKqw) ## Deploying Non-Rust WASM Projects diff --git a/check/Dockerfile b/check/Dockerfile deleted file mode 100644 index cea0606..0000000 --- a/check/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM rust:1.71 as builder -COPY . . -RUN cargo build --release - -FROM debian:buster-slim -COPY --from=builder ./target/release/cargo-stylus ./target/release/cargo-stylus -CMD ["/target/release/cargo-stylus"] \ No newline at end of file diff --git a/check/src/cache.rs b/check/src/cache.rs index 7d907e1..f850e50 100644 --- a/check/src/cache.rs +++ b/check/src/cache.rs @@ -30,6 +30,7 @@ sol! { error AlreadyCached(bytes32 codehash); error BidTooSmall(uint192 bid, uint192 min); error BidsArePaused(); + error ProgramNotActivated(); } } @@ -88,6 +89,9 @@ pub async fn cache_contract(cfg: &CacheConfig) -> Result<()> { C::BidTooSmall(_) => { bail!("Bid amount {} (wei) too small", cfg.bid.unwrap_or_default()) } + C::ProgramNotActivated(_) => { + bail!("Your Stylus contract {} is not yet activated. To activate it, use the `cargo stylus activate` subcommand", hex::encode(contract)) + } } } let verbose = cfg.common_cfg.verbose; diff --git a/check/src/check.rs b/check/src/check.rs index 0716e62..e315d03 100644 --- a/check/src/check.rs +++ b/check/src/check.rs @@ -210,6 +210,12 @@ async fn contract_exists(codehash: B256, provider: &Provider) -> Result { + if outs.is_empty() { + bail!( + r#"No data returned from the ArbWasm precompile when checking if your Stylus contract exists. +Perhaps the Arbitrum node for the endpoint you are connecting to has not yet upgraded to Stylus"# + ); + } let ArbWasm::codehashVersionReturn { version } = ArbWasm::codehashVersionCall::abi_decode_returns(&outs, true)?; version diff --git a/check/src/constants.rs b/check/src/constants.rs index b923821..935d9b9 100644 --- a/check/src/constants.rs +++ b/check/src/constants.rs @@ -43,8 +43,3 @@ pub const PROJECT_HASH_SECTION_NAME: &str = "project_hash"; /// Name of the toolchain file used to specify the Rust toolchain version for a project. pub const TOOLCHAIN_FILE_NAME: &str = "rust-toolchain.toml"; - -/// Base Rust image version to be used for reproducible builds. This simply installs cargo and the Rust -/// compiler, but the user will specify the exact version of the Rust toolchain to use for building within -/// the docker container. -pub const RUST_BASE_IMAGE_VERSION: &str = "1.79.0"; diff --git a/check/src/deploy.rs b/check/src/deploy.rs index f146e0b..9c5d79e 100644 --- a/check/src/deploy.rs +++ b/check/src/deploy.rs @@ -146,7 +146,7 @@ impl DeployConfig { let tx_hash = receipt.transaction_hash.debug_lavender(); greyln!("deployment tx hash: {tx_hash}"); println!( - r#"we recommend running cargo stylus cache --address={} to cache your activated contract in ArbOS. + r#"INFO: Your program is not yet part of the Stylus contract cache. We recommend running `cargo stylus cache --address={}` to cache your activated contract in ArbOS. Cached contracts benefit from cheaper calls. To read more about the Stylus contract cache, see https://docs.arbitrum.io/stylus/concepts/stylus-cache-manager"#, hex::encode(contract) diff --git a/check/src/docker.rs b/check/src/docker.rs index 89a433d..fa96700 100644 --- a/check/src/docker.rs +++ b/check/src/docker.rs @@ -8,7 +8,7 @@ use std::process::{Command, Stdio}; use cargo_stylus_util::color::Color; use eyre::{bail, eyre, Result}; -use crate::constants::{RUST_BASE_IMAGE_VERSION, TOOLCHAIN_FILE_NAME}; +use crate::constants::TOOLCHAIN_FILE_NAME; use crate::macros::greyln; use crate::project::extract_toolchain_channel; @@ -45,15 +45,7 @@ fn create_image(version: &str) -> Result<()> { if image_exists(&name)? { return Ok(()); } - let cargo_stylus_version = env!("CARGO_PKG_VERSION"); - let cargo_stylus_version: String = cargo_stylus_version - .chars() - .filter(|c| c.is_alphanumeric() || *c == '-' || *c == '.') - .collect(); - println!( - "Building Docker image for cargo-stylus version {} and Rust toolchain {}", - cargo_stylus_version, version, - ); + println!("Building Docker image for Rust toolchain {}", version,); let mut child = Command::new("docker") .arg("build") .arg("-t") @@ -62,24 +54,19 @@ fn create_image(version: &str) -> Result<()> { .arg("-f-") .stdin(Stdio::piped()) .spawn() - .map_err(|e| eyre!("failed to execure Docker command: {e}"))?; + .map_err(|e| eyre!("failed to execute Docker command: {e}"))?; write!( child.stdin.as_mut().unwrap(), "\ - FROM --platform=linux/amd64 rust:{} as builder\n\ + FROM --platform=linux/amd64 offchainlabs/cargo-stylus-base as base RUN rustup toolchain install {}-x86_64-unknown-linux-gnu RUN rustup default {}-x86_64-unknown-linux-gnu RUN rustup target add wasm32-unknown-unknown - RUN rustup target add wasm32-wasi - RUN rustup target add x86_64-unknown-linux-gnu - RUN cargo install cargo-stylus-check --version {} --force - RUN cargo install cargo-stylus --version {} --force + RUN rustup component add rust-src --toolchain {}-x86_64-unknown-linux-gnu ", - RUST_BASE_IMAGE_VERSION, version, version, - cargo_stylus_version, - cargo_stylus_version, + version, )?; child.wait().map_err(|e| eyre!("wait failed: {e}"))?; Ok(()) diff --git a/check/src/main.rs b/check/src/main.rs index 9f8912b..848bf93 100644 --- a/check/src/main.rs +++ b/check/src/main.rs @@ -34,7 +34,7 @@ struct Opts { #[derive(Parser, Debug, Clone)] enum Apis { - /// Create a new Rust project. + /// Create a new Stylus project. New { /// Project name. name: PathBuf, @@ -42,6 +42,12 @@ enum Apis { #[arg(long)] minimal: bool, }, + /// Initializes a Stylus project in the current directory. + Init { + /// Create a minimal contract. + #[arg(long)] + minimal: bool, + }, /// Export a Solidity ABI. ExportAbi { /// The output file (defaults to stdout). @@ -127,10 +133,6 @@ pub struct CheckConfig { /// Where to deploy and activate the contract (defaults to a random address). #[arg(long)] contract_address: Option, - /// If specified, will not run the command in a reproducible docker container. Useful for local - /// builds, but at the risk of not having a reproducible contract for verification purposes. - #[arg(long)] - no_verify: bool, } #[derive(Args, Clone, Debug)] @@ -143,6 +145,10 @@ struct DeployConfig { /// Only perform gas estimation. #[arg(long)] estimate_gas: bool, + /// If specified, will not run the command in a reproducible docker container. Useful for local + /// builds, but at the risk of not having a reproducible contract for verification purposes. + #[arg(long)] + no_verify: bool, } #[derive(Args, Clone, Debug)] @@ -206,7 +212,7 @@ impl fmt::Display for CheckConfig { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, - "{} {} {} {}", + "{} {} {}", self.common_cfg, match &self.wasm_file { Some(path) => format!("--wasm-file={}", path.display()), @@ -216,10 +222,6 @@ impl fmt::Display for CheckConfig { Some(addr) => format!("--contract-address={:?}", addr), None => "".to_string(), }, - match self.no_verify { - true => "--no-verify".to_string(), - false => "".to_string(), - }, ) } } @@ -228,13 +230,17 @@ impl fmt::Display for DeployConfig { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, - "{} {} {}", + "{} {} {} {}", self.check_config, self.auth, match self.estimate_gas { true => "--estimate-gas".to_string(), false => "".to_string(), }, + match self.no_verify { + true => "--no-verify".to_string(), + false => "".to_string(), + }, ) } } @@ -296,6 +302,9 @@ async fn main_impl(args: Opts) -> Result<()> { Apis::New { name, minimal } => { run!(new::new(&name, minimal), "failed to open new project"); } + Apis::Init { minimal } => { + run!(new::init(minimal), "failed to initialize project"); + } Apis::ExportAbi { json, output } => { run!(export_abi::export_abi(output, json), "failed to export abi"); } @@ -309,28 +318,16 @@ async fn main_impl(args: Opts) -> Result<()> { run!(cache::cache_contract(&config).await, "stylus cache failed"); } Apis::Check(config) => { - if config.no_verify { - run!(check::check(&config).await, "stylus checks failed"); - } else { - let mut commands: Vec = - vec![String::from("check"), String::from("--no-verify")]; - let config_args = config - .to_string() - .split(' ') - .map(|s| s.to_string()) - .filter(|s| !s.is_empty()) - .collect::>(); - commands.extend(config_args); - run!( - docker::run_reproducible(&commands), - "failed reproducible run" - ); - } + run!(check::check(&config).await, "stylus checks failed"); } Apis::Deploy(config) => { - if config.check_config.no_verify { + if config.no_verify { run!(deploy::deploy(config).await, "stylus deploy failed"); } else { + println!( + "Running in a Docker container for reproducibility, this may take a while", + ); + println!("NOTE: You can opt out by doing --no-verify"); let mut commands: Vec = vec![String::from("deploy"), String::from("--no-verify")]; let config_args = config @@ -350,6 +347,9 @@ async fn main_impl(args: Opts) -> Result<()> { if config.no_verify { run!(verify::verify(config).await, "failed to verify"); } else { + println!( + "Running in a Docker container for reproducibility, this may take a while", + ); let mut commands: Vec = vec![String::from("verify"), String::from("--no-verify")]; let config_args = config diff --git a/check/src/new.rs b/check/src/new.rs index 668df01..7fe0e1c 100644 --- a/check/src/new.rs +++ b/check/src/new.rs @@ -29,3 +29,31 @@ pub fn new(name: &Path, minimal: bool) -> Result<()> { println!("{GREY}new project at: {}", path.to_string_lossy().mint()); Ok(()) } + +pub fn init(minimal: bool) -> Result<()> { + let current_dir = current_dir().wrap_err("no current dir")?; + let repo = if minimal { + GITHUB_TEMPLATE_REPO_MINIMAL + } else { + GITHUB_TEMPLATE_REPO + }; + + let output = sys::new_command("git") + .arg("clone") + .arg("--depth") + .arg("1") + .arg(repo) + .arg(".") + .output() + .wrap_err("git clone failed")?; + + if !output.status.success() { + bail!("git clone command failed"); + } + + println!( + "{GREY}initialized project in: {}", + current_dir.to_string_lossy().mint() + ); + Ok(()) +} diff --git a/check/src/project.rs b/check/src/project.rs index ee327ec..8ea07ab 100644 --- a/check/src/project.rs +++ b/check/src/project.rs @@ -57,10 +57,6 @@ pub fn build_dylib(cfg: BuildConfig) -> Result { let mut cmd = sys::new_command("cargo"); - if !cfg.stable { - cmd.arg("+nightly"); - } - cmd.arg("build"); cmd.arg("--lib"); @@ -208,9 +204,6 @@ pub fn extract_toolchain_channel(toolchain_file_path: &PathBuf) -> Result, cfg: BuildConfig) -> Result<[u8; 32]> { let mut keccak = Keccak::v256(); let mut cmd = Command::new("cargo"); - if !cfg.stable { - cmd.arg("+nightly"); - } cmd.arg("--version"); let output = cmd .output() diff --git a/check/src/verify.rs b/check/src/verify.rs index 9c55f8b..2cc0084 100644 --- a/check/src/verify.rs +++ b/check/src/verify.rs @@ -54,7 +54,6 @@ pub async fn verify(cfg: VerifyConfig) -> eyre::Result<()> { common_cfg: cfg.common_cfg.clone(), wasm_file: None, contract_address: None, - no_verify: cfg.no_verify, }; let _ = check::check(&check_cfg) .await diff --git a/main/src/main.rs b/main/src/main.rs index 5240e1b..ab9a655 100644 --- a/main/src/main.rs +++ b/main/src/main.rs @@ -28,8 +28,11 @@ struct Opts { #[derive(Parser, Debug, Clone)] enum Subcommands { #[command(alias = "n")] - /// Create a new Rust project. + /// Create a new Stylus project. New, + #[command(alias = "i")] + /// Initializes a Stylus project in the current directory. + Init, #[command(alias = "x")] /// Export a Solidity ABI. ExportAbi, @@ -69,12 +72,15 @@ const COMMANDS: &[Binary] = &[ name: "cargo-stylus-check", apis: &[ "new", + "init", + "activate", "export-abi", "cache", "check", "deploy", "verify", "a", + "i", "n", "x", "c", diff --git a/replay/src/main.rs b/replay/src/main.rs index e74b465..79fd1da 100644 --- a/replay/src/main.rs +++ b/replay/src/main.rs @@ -147,7 +147,7 @@ async fn replay(args: ReplayArgs) -> Result<()> { let provider = sys::new_provider(&args.endpoint)?; let trace = Trace::new(provider, args.tx).await?; - build_so(&args.project, args.stable_rust)?; + build_so(&args.project)?; let so = find_so(&args.project)?; // TODO: don't assume the contract is top-level @@ -169,12 +169,9 @@ async fn replay(args: ReplayArgs) -> Result<()> { Ok(()) } -pub fn build_so(path: &Path, stable: bool) -> Result<()> { +pub fn build_so(path: &Path) -> Result<()> { let mut cargo = sys::new_command("cargo"); - if !stable { - cargo.arg("+nightly"); - } cargo .current_dir(path) .arg("build") From f6fe6142a6fd61b32114d7ecd7d0c859ac59c336 Mon Sep 17 00:00:00 2001 From: Mark_Jeong <81726531+markjung96@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:09:26 +0900 Subject: [PATCH 34/35] chore: add comments --- check/src/check.rs | 109 +++++++++++++++++++++-------------------- main/src/main.rs | 117 +++++++++++++++++++++++---------------------- 2 files changed, 117 insertions(+), 109 deletions(-) diff --git a/check/src/check.rs b/check/src/check.rs index 54f99f6..f755c1f 100644 --- a/check/src/check.rs +++ b/check/src/check.rs @@ -1,5 +1,5 @@ // Copyright 2023-2024, Offchain Labs, Inc. -// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md +// 라이선스 정보는 https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md에서 확인할 수 있습니다. use crate::deploy::TxKind; use crate::{ @@ -28,6 +28,7 @@ use std::path::PathBuf; sol! { interface ArbWasm { + // ArbWasm 인터페이스 정의: 프로그램 활성화, Stylus 버전 확인, 코드 해시 버전 확인 및 오류 처리 함수들. function activateProgram(address program) external payable @@ -47,8 +48,8 @@ sol! { } } -/// Checks that a contract is valid and can be deployed onchain. -/// Returns whether the WASM is already up-to-date and activated onchain, and the data fee. +/// 계약이 유효하며 체인에 배포될 수 있는지 확인합니다. +/// 이더리움 WASM이 최신 상태로 이미 체인에서 활성화되었는지 여부와 데이터 수수료를 반환합니다. pub async fn check(cfg: &CheckConfig) -> Result { if cfg.common_cfg.endpoint == "https://stylus-testnet.arbitrum.io/rpc" { let version = "cargo stylus version 0.2.1".to_string().red(); @@ -56,19 +57,21 @@ pub async fn check(cfg: &CheckConfig) -> Result { } let verbose = cfg.common_cfg.verbose; - let (wasm, project_hash) = cfg.build_wasm().wrap_err("failed to build wasm")?; + let (wasm, project_hash) = cfg.build_wasm().wrap_err("failed to build wasm")?; // WASM 파일을 빌드합니다. if verbose { greyln!("reading wasm file at {}", wasm.to_string_lossy().lavender()); } + + // 다음으로, 사용자의 WASM(웹어셈블리) 파일에 프로젝트의 해시를 커스텀 섹션으로 포함시킵니다. + // 이 해시는 Cargo stylus의 재현 가능한 검증(reproducible verification)에 의해 검증될 수 있도록 추가됩니다. + // 이 해시는 WASM 런타임에서 무시되는 섹션으로 추가되기 때문에, 파일에는 메타데이터 용도로만 존재하게 됩니다. let (wasm_file_bytes, code) = - project::compress_wasm(&wasm, project_hash).wrap_err("failed to compress WASM")?; + project::compress_wasm(&wasm, project_hash).wrap_err("failed to compress WASM")?; // WASM 파일을 압축합니다. let code_copied = code.clone(); - let mut code_len = [0u8; 32]; - ethers::prelude::U256::from(code_copied.len()).to_big_endian(&mut code_len); let mut tx_code: Vec = vec![]; tx_code.push(0x7f); // PUSH32 @@ -85,9 +88,9 @@ pub async fn check(cfg: &CheckConfig) -> Result { tx_code.push(0x00); // version tx_code.extend(project_hash); tx_code.extend(code_copied); - write_tx_data(TxKind::Deployment, &tx_code)?; + write_tx_data(TxKind::Deployment, &tx_code)?; // 트랜잭션 데이터를 작성하여 파일로 저장합니다. - greyln!("contract size: {}", format_file_size(code.len(), 16, 24)); + greyln!("contract size: {}", format_file_size(code.len(), 16, 24)); // 계약 크기를 출력합니다. if verbose { greyln!( @@ -97,41 +100,41 @@ pub async fn check(cfg: &CheckConfig) -> Result { greyln!("connecting to RPC: {}", &cfg.common_cfg.endpoint.lavender()); } - // Check if the contract already exists. + // 계약이 이미 존재하는지 확인합니다. let provider = sys::new_provider(&cfg.common_cfg.endpoint)?; let codehash = alloy_primitives::keccak256(&code); if contract_exists(codehash, &provider).await? { - return Ok(ContractCheck::Active { code }); + return Ok(ContractCheck::Active { code }); // 계약이 이미 활성화된 경우. } - let address = cfg.contract_address.unwrap_or(H160::random()); - let fee = check_activate(code.clone().into(), address, &provider).await?; + let address = cfg.contract_address.unwrap_or(H160::random()); // 계약 주소를 설정하거나 새로 생성합니다. + let fee = check_activate(code.clone().into(), address, &provider).await?; // 계약 활성화를 위한 데이터 수수료를 계산합니다. let visual_fee = format_data_fee(fee).unwrap_or("???".red()); - greyln!("wasm data fee: {visual_fee}"); - Ok(ContractCheck::Ready { code, fee }) + greyln!("wasm data fee: {visual_fee}"); // 데이터 수수료를 출력합니다. + Ok(ContractCheck::Ready { code, fee }) // 계약이 활성화 준비가 된 경우. } -/// Whether a contract is active, or needs activation. +/// 계약이 활성화되었는지, 아니면 활성화가 필요한지 확인하는 열거형. #[derive(PartialEq)] pub enum ContractCheck { - /// Contract already exists onchain. + /// 계약이 이미 체인에 존재합니다. Active { code: Vec }, - /// Contract can be activated with the given data fee. + /// 계약을 데이터 수수료와 함께 활성화할 수 있습니다. Ready { code: Vec, fee: U256 }, } impl ContractCheck { pub fn code(&self) -> &[u8] { match self { - Self::Active { code, .. } => code, - Self::Ready { code, .. } => code, + Self::Active { code, .. } => code, // 활성화된 경우 코드 반환 + Self::Ready { code, .. } => code, // 준비된 경우 코드 반환 } } pub fn suggest_fee(&self) -> U256 { match self { - Self::Active { .. } => U256::default(), - Self::Ready { fee, .. } => fee * U256::from(120) / U256::from(100), + Self::Active { .. } => U256::default(), // 활성화된 경우 기본 수수료 반환 + Self::Ready { fee, .. } => fee * U256::from(120) / U256::from(100), // 준비된 경우 수수료를 조정하여 반환 } } } @@ -139,20 +142,20 @@ impl ContractCheck { impl CheckConfig { fn build_wasm(&self) -> Result<(PathBuf, [u8; 32])> { if let Some(wasm) = self.wasm_file.clone() { - return Ok((wasm, [0u8; 32])); + return Ok((wasm, [0u8; 32])); // 기존 WASM 파일이 있으면 사용 } let toolchain_file_path = PathBuf::from(".").as_path().join(TOOLCHAIN_FILE_NAME); - let toolchain_channel = extract_toolchain_channel(&toolchain_file_path)?; + let toolchain_channel = extract_toolchain_channel(&toolchain_file_path)?; // 도구 체인 채널을 추출합니다. let rust_stable = !toolchain_channel.contains("nightly"); let cfg = BuildConfig::new(rust_stable); - let wasm = project::build_dylib(cfg.clone())?; + let wasm = project::build_dylib(cfg.clone())?; // 동적 라이브러리(Dylib)를 빌드합니다. let project_hash = - project::hash_files(self.common_cfg.source_files_for_project_hash.clone(), cfg)?; + project::hash_files(self.common_cfg.source_files_for_project_hash.clone(), cfg)?; // 프로젝트 파일 해시를 계산합니다. Ok((wasm, project_hash)) } } -/// Pretty-prints a file size based on its limits. +/// 파일 크기를 포맷하여 예쁘게 출력합니다. pub fn format_file_size(len: usize, mid: u64, max: u64) -> String { let len = ByteSize::b(len as u64); let mid = ByteSize::kib(mid); @@ -166,7 +169,7 @@ pub fn format_file_size(len: usize, mid: u64, max: u64) -> String { } } -/// Pretty-prints a data fee. +/// 데이터 수수료를 포맷하여 출력합니다. fn format_data_fee(fee: U256) -> Result { let fee: u64 = (fee / U256::from(1e9)).try_into()?; let fee: f64 = fee as f64 / 1e9; @@ -187,41 +190,41 @@ pub struct EthCallError { impl From for ErrReport { fn from(value: EthCallError) -> Self { - eyre!(value.msg) + eyre!(value.msg) // EthCallError를 ErrReport로 변환 } } -/// A funded eth_call. +/// 자금이 충당된 eth_call을 실행합니다. pub async fn eth_call( tx: Eip1559TransactionRequest, mut state: State, provider: &Provider, ) -> Result, EthCallError>> { let tx = TypedTransaction::Eip1559(tx); - state.account(Default::default()).balance = Some(ethers::types::U256::MAX); // infinite balance + state.account(Default::default()).balance = Some(ethers::types::U256::MAX); // 무한한 잔고를 설정하여 가스 제한을 회피합니다. match provider.call_raw(&tx).state(&state).await { - Ok(bytes) => Ok(Ok(bytes.to_vec())), + Ok(bytes) => Ok(Ok(bytes.to_vec())), // 호출이 성공하면 결과를 바이트 배열로 반환 Err(ProviderError::JsonRpcClientError(error)) => { let error = error .as_error_response() - .ok_or_else(|| eyre!("json RPC failure: {error}"))?; + .ok_or_else(|| eyre!("json RPC failure: {error}"))?; // JSON RPC 실패 시 처리 let msg = error.message.clone(); let data = match &error.data { - Some(Value::String(data)) => text::decode0x(data)?.to_vec(), + Some(Value::String(data)) => text::decode0x(data)?.to_vec(), // 에러 데이터를 디코딩 Some(value) => bail!("failed to decode RPC failure: {value}"), - None => vec![], + None => vec![], // 데이터가 없는 경우 빈 벡터 반환 }; - Ok(Err(EthCallError { data, msg })) + Ok(Err(EthCallError { data, msg })) // EthCallError로 반환 } - Err(error) => Err(error.into()), + Err(error) => Err(error.into()), // 기타 에러 처리 } } -/// Checks whether a contract has already been activated with the most recent version of Stylus. +/// 계약이 최신 Stylus 버전으로 이미 활성화되어 있는지 확인합니다. async fn contract_exists(codehash: B256, provider: &Provider) -> Result { - let data = ArbWasm::codehashVersionCall { codehash }.abi_encode(); + let data = ArbWasm::codehashVersionCall { codehash }.abi_encode(); // 코드 해시 버전을 확인하는 호출 데이터 생성 let tx = Eip1559TransactionRequest::new() .to(*ARB_WASM_H160) .data(data); @@ -245,16 +248,16 @@ Perhaps the Arbitrum node for the endpoint you are connecting to has not yet upg }; use ArbWasmErrors as A; match error { - A::ProgramNotWasm(_) => bail!("not a Stylus contract"), + A::ProgramNotWasm(_) => bail!("not a Stylus contract"), // Stylus 계약이 아닌 경우 A::ProgramNotActivated(_) | A::ProgramNeedsUpgrade(_) | A::ProgramExpired(_) => { - return Ok(false); + return Ok(false); // 프로그램이 활성화되지 않았거나 업그레이드가 필요한 경우 } - _ => bail!("unexpected ArbWasm error: {msg}"), + _ => bail!("unexpected ArbWasm error: {msg}"), // 예기치 않은 오류 처리 } } }; - let data = ArbWasm::stylusVersionCall {}.abi_encode(); + let data = ArbWasm::stylusVersionCall {}.abi_encode(); // Stylus 버전을 확인하는 호출 데이터 생성 let tx = Eip1559TransactionRequest::new() .to(*ARB_WASM_H160) .data(data); @@ -262,31 +265,31 @@ Perhaps the Arbitrum node for the endpoint you are connecting to has not yet upg let ArbWasm::stylusVersionReturn { version } = ArbWasm::stylusVersionCall::abi_decode_returns(&outs, true)?; - Ok(program_version == version) + Ok(program_version == version) // 프로그램 버전이 최신 버전인지 확인 } -/// Checks contract activation, returning the data fee. +/// 계약 활성화를 확인하고, 데이터 수수료를 반환합니다. pub async fn check_activate(code: Bytes, address: H160, provider: &Provider) -> Result { let contract = Address::from(address.to_fixed_bytes()); - let data = ArbWasm::activateProgramCall { program: contract }.abi_encode(); + let data = ArbWasm::activateProgramCall { program: contract }.abi_encode(); // 프로그램 활성화 호출 데이터 생성 let tx = Eip1559TransactionRequest::new() .to(*ARB_WASM_H160) .data(data) - .value(ONE_ETH); - let state = spoof::code(address, code); + .value(ONE_ETH); // 활성화 트랜잭션을 위해 1 ETH를 설정 + let state = spoof::code(address, code); // 계약 코드와 주소를 기반으로 상태를 스푸핑(spoofing) let outs = eth_call(tx, state, provider).await??; let ArbWasm::activateProgramReturn { dataFee, .. } = ArbWasm::activateProgramCall::abi_decode_returns(&outs, true)?; - Ok(dataFee) + Ok(dataFee) // 활성화에 필요한 데이터 수수료 반환 } fn write_tx_data(tx_kind: TxKind, data: &[u8]) -> eyre::Result<()> { - let file_name = format!("{tx_kind}_tx_data"); + let file_name = format!("{tx_kind}_tx_data"); // 트랜잭션 종류에 따라 파일 이름 설정 let mut path = PathBuf::new(); path.push("./output"); if !path.exists() { - fs::create_dir_all(&path).map_err(|e| eyre!("could not create output directory: {e}"))?; + fs::create_dir_all(&path).map_err(|e| eyre!("could not create output directory: {e}"))?; // 출력 디렉토리 생성 } path = path.join(file_name); @@ -297,7 +300,7 @@ fn write_tx_data(tx_kind: TxKind, data: &[u8]) -> eyre::Result<()> { path_str.grey(), ); let mut f = std::fs::File::create(&path) - .map_err(|e| eyre!("could not create file to write tx data to path {path_str}: {e}",))?; + .map_err(|e| eyre!("could not create file to write tx data to path {path_str}: {e}",))?; // 파일 생성 f.write_all(data) - .map_err(|e| eyre!("could not write tx data as bytes to file to path {path_str}: {e}")) + .map_err(|e| eyre!("could not write tx data as bytes to file to path {path_str}: {e}")) // 데이터를 파일에 씁니다. } diff --git a/main/src/main.rs b/main/src/main.rs index 648fa5e..355e326 100644 --- a/main/src/main.rs +++ b/main/src/main.rs @@ -1,72 +1,74 @@ // Copyright 2023-2024, Offchain Labs, Inc. -// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md +// 라이선스 정보는 https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md에서 확인할 수 있습니다. -use cargo_stylus_util::{color::Color, sys}; -use clap::{CommandFactory, Parser}; -use eyre::{bail, Result}; +use cargo_stylus_util::{color::Color, sys}; // 색상 및 시스템 명령어 관련 유틸리티 모듈을 가져옴 +use clap::{CommandFactory, Parser}; // CLI 명령어 파싱을 위한 clap 라이브러리 가져옴 +use eyre::{bail, Result}; // 오류 처리 및 결과 반환을 위한 eyre 라이브러리 가져옴 -// Conditional import for Unix-specific `CommandExt` +// Unix 계열 운영체제에서만 사용되는 `CommandExt`를 조건부로 가져옴 #[cfg(unix)] use std::{env, os::unix::process::CommandExt}; -// Conditional import for Windows +// Windows에서만 사용되는 모듈을 조건부로 가져옴 #[cfg(windows)] use std::env; -#[derive(Parser, Debug)] -#[command(name = "stylus")] -#[command(bin_name = "cargo stylus")] -#[command(author = "Offchain Labs, Inc.")] -#[command(about = "Cargo subcommand for developing Stylus projects", long_about = None)] -#[command(propagate_version = true)] -#[command(version)] +#[derive(Parser, Debug)] // 명령어 파서를 정의하고 디버그 모드 활성화 +#[command(name = "stylus")] // 명령어 이름을 설정 +#[command(bin_name = "cargo stylus")] // 이 바이너리가 실행될 때 사용할 명령어 이름 +#[command(author = "Offchain Labs, Inc.")] // 작성자 정보 +#[command(about = "Stylus 프로젝트를 개발하기 위한 Cargo 서브 명령어", long_about = None)] // 프로그램 설명 +#[command(propagate_version = true)] // 버전 정보를 전파하도록 설정 +#[command(version)] // 버전 정보를 포함하도록 설정 struct Opts { #[command(subcommand)] - command: Subcommands, + command: Subcommands, // 서브커맨드를 정의 } -#[derive(Parser, Debug, Clone)] +#[derive(Parser, Debug, Clone)] // 서브커맨드의 파서를 정의하고 디버그 모드 및 복제 가능 설정 enum Subcommands { #[command(alias = "n")] - /// Create a new Stylus project. - New, + /// 새로운 Stylus 프로젝트를 생성합니다. + New, // 새로운 프로젝트를 생성하는 서브커맨드 #[command(alias = "i")] - /// Initializes a Stylus project in the current directory. - Init, + /// 현재 디렉토리에 Stylus 프로젝트를 초기화합니다. + Init, // 현재 디렉토리에 프로젝트를 초기화하는 서브커맨드 #[command(alias = "x")] - /// Export a Solidity ABI. - ExportAbi, - /// Cache a contract. - Cache, - /// Check a contract. + /// Solidity ABI를 내보냅니다. + ExportAbi, // Solidity ABI를 내보내는 서브커맨드 + /// 계약을 캐시합니다. + Cache, // 계약을 캐시하는 서브커맨드 + /// 계약을 검사합니다. #[command(alias = "c")] - Check, - /// Activate an already deployed contract + Check, // 계약을 검사하는 서브커맨드 + /// 이미 배포된 계약을 활성화합니다. #[command(alias = "a")] - Activate, - /// Deploy a contract. + Activate, // 이미 배포된 계약을 활성화하는 서브커맨드 + /// 계약을 배포합니다. #[command(alias = "d")] - Deploy, - /// Replay a transaction in gdb. + Deploy, // 계약을 배포하는 서브커맨드 + /// gdb에서 트랜잭션을 재실행합니다. #[command(alias = "r")] - Replay, - /// Trace a transaction. + Replay, // 트랜잭션을 gdb에서 재실행하는 서브커맨드 + /// 트랜잭션을 추적합니다. #[command()] - Trace, - /// Verify the deployment of a Stylus contract against a local project. + Trace, // 트랜잭션을 추적하는 서브커맨드 + /// Stylus 계약의 배포를 로컬 프로젝트와 검증합니다. #[command(alias = "v")] - Verify, - /// Generate C code. + Verify, // Stylus 계약의 배포를 검증하는 서브커맨드 + /// C 코드를 생성합니다. #[command()] - CGen, + CGen, // C 코드를 생성하는 서브커맨드 } +// 명령어 정보 구조체 struct Binary<'a> { - name: &'a str, - apis: &'a [&'a str], - rust_flags: Option<&'a str>, + name: &'a str, // 바이너리 이름 + apis: &'a [&'a str], // API 명령어 목록 + rust_flags: Option<&'a str>, // Rust 플래그 옵션 } +// 명령어 목록을 상수로 정의 const COMMANDS: &[Binary] = &[ Binary { name: "cargo-stylus-check", @@ -107,57 +109,60 @@ const COMMANDS: &[Binary] = &[ }, ]; -// prints help message and exits +// 도움말 메시지를 출력하고 프로그램을 종료 fn exit_with_help_msg() -> ! { Opts::command().print_help().unwrap(); std::process::exit(0); } -// prints version information and exits +// 버전 정보를 출력하고 프로그램을 종료 fn exit_with_version() -> ! { println!("{}", Opts::command().render_version()); std::process::exit(0); } +// 메인 함수 fn main() -> Result<()> { - // skip the starting arguments passed from the OS and/or cargo. + // 운영체제와 Cargo에서 전달된 시작 인수를 건너뜁니다. let mut args = env::args().skip_while(|x| x == "cargo" || x == "stylus" || x.contains("cargo-stylus")); + // 첫 번째 명령어 인수를 가져옵니다. 없다면 도움말 메시지를 출력 let Some(arg) = args.next() else { exit_with_help_msg(); }; - // perform any builtins + // 내장된 명령어를 처리합니다. match arg.as_str() { "--help" | "-h" => exit_with_help_msg(), "--version" | "-V" => exit_with_version(), _ => {} }; + // 명령어가 COMMANDS 목록에 있는지 확인합니다. 없다면 커스텀 명령어를 확인 let Some(bin) = COMMANDS.iter().find(|x| x.apis.contains(&arg.as_str())) else { - // see if custom extension exists + // 커스텀 확장이 존재하는지 확인 let custom = format!("cargo-stylus-{arg}"); if sys::command_exists(&custom) { let mut command = sys::new_command(&custom); command.arg(arg).args(args); - // Execute command conditionally based on the platform + // 플랫폼에 따라 명령어 실행 #[cfg(unix)] - let err = command.exec(); // Unix-specific execution + let err = command.exec(); // Unix 전용 실행 방식 #[cfg(windows)] - let err = command.status(); // Windows-specific execution - bail!("failed to invoke {:?}: {:?}", custom.red(), err); + let err = command.status(); // Windows 전용 실행 방식 + bail!("failed to invoke {:?}: {:?}", custom.red(), err); // 오류 발생 시 메시지 출력 } eprintln!("Unknown subcommand {}.", arg.red()); eprintln!(); - exit_with_help_msg(); + exit_with_help_msg(); // 알 수 없는 서브커맨드일 경우 도움말 메시지를 출력하고 종료 }; let name = bin.name; - // not all subcommands are shipped with `cargo-stylus`. + // 해당 서브커맨드가 설치되지 않은 경우 설치 방법을 안내 if !sys::command_exists(name) { let flags = bin.rust_flags.map(|x| format!("{x} ")).unwrap_or_default(); let install = format!(" {flags}cargo install --force {name}"); @@ -169,14 +174,14 @@ fn main() -> Result<()> { return Ok(()); } - // should never return + // 명령어를 생성하고 인수를 추가 let mut command = sys::new_command(name); command.arg(arg).args(args); - // Execute command conditionally based on the platform + // 플랫폼에 따라 명령어 실행 #[cfg(unix)] - let err = command.exec(); // Unix-specific execution + let err = command.exec(); // Unix 전용 실행 방식 #[cfg(windows)] - let err = command.status(); // Windows-specific execution - bail!("failed to invoke {:?}: {:?}", name.red(), err); + let err = command.status(); // Windows 전용 실행 방식 + bail!("failed to invoke {:?}: {:?}", name.red(), err); // 오류 발생 시 메시지 출력 } From a2c603972bc9e46067075106dbb52230e45a4a16 Mon Sep 17 00:00:00 2001 From: Mark_Jeong <81726531+markjung96@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:09:42 +0900 Subject: [PATCH 35/35] feat: set stylus a command --- check/src/activate.rs | 82 ++++++++++++++++++++++++++----------------- check/src/main.rs | 14 +++++--- 2 files changed, 58 insertions(+), 38 deletions(-) diff --git a/check/src/activate.rs b/check/src/activate.rs index af6c953..21d8cf9 100644 --- a/check/src/activate.rs +++ b/check/src/activate.rs @@ -1,15 +1,15 @@ // Copyright 2023-2024, Offchain Labs, Inc. -// For licensing, see https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md +// 라이선스 정보는 https://github.com/OffchainLabs/cargo-stylus/blob/main/licenses/COPYRIGHT.md에서 확인할 수 있습니다. -#![allow(clippy::println_empty_string)] +#![allow(clippy::println_empty_string)] // 빈 문자열을 println에 사용해도 Clippy 경고를 무시합니다. -use std::fs; -use std::io::Write; -use std::path::PathBuf; +use std::fs; // 파일 시스템 작업을 위한 표준 라이브러리 사용 +use std::io::Write; // 파일에 데이터를 쓰기 위한 표준 라이브러리 사용 +use std::path::PathBuf; // 파일 경로를 처리하기 위한 표준 라이브러리 사용 -use alloy_primitives::Address; -use alloy_sol_macro::sol; -use alloy_sol_types::SolCall; +use alloy_primitives::Address; // Ethereum 주소를 처리하기 위한 라이브러리 +use alloy_sol_macro::sol; // Solidity 인터페이스를 정의하기 위한 매크로 +use alloy_sol_types::SolCall; // Solidity 함수 호출을 처리하기 위한 타입 use ethers::{ core::k256::ecdsa::SigningKey, middleware::SignerMiddleware, @@ -19,32 +19,35 @@ use ethers::{ types::{Eip1559TransactionRequest, H160, U256}, utils::format_units, }; -use eyre::{bail, eyre, Context, Result, WrapErr}; +use eyre::{bail, eyre, Context, Result, WrapErr}; // 에러 핸들링을 위한 라이브러리 -use cargo_stylus_util::color::{Color, DebugColor}; -use cargo_stylus_util::sys; +use cargo_stylus_util::color::{Color, DebugColor}; // 컬러 출력을 위한 유틸리티 +use cargo_stylus_util::sys; // 시스템 관련 유틸리티 -use crate::check::check_activate; -use crate::constants::ARB_WASM_H160; -use crate::macros::greyln; -use crate::ActivateConfig; +use crate::check::check_activate; // 계약 활성화 체크 함수를 가져옵니다. +use crate::constants::ARB_WASM_H160; // Arbitrum WASM 주소 상수를 가져옵니다. +use crate::macros::greyln; // 컬러와 함께 로그를 출력하는 매크로를 가져옵니다. +use crate::ActivateConfig; // 활성화 구성 구조체를 가져옵니다. +use crate::ActivateWithoutPrivateKeyConfig; // 활성화 구성 구조체를 가져옵니다. pub enum TxKind { - Deployment, - Activation, + Deployment, // 배포 트랜잭션 + Activation, // 활성화 트랜잭션 } impl std::fmt::Display for TxKind { + // TxKind를 문자열로 출력하는 방법을 정의합니다. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match *self { - TxKind::Deployment => write!(f, "deployment"), - TxKind::Activation => write!(f, "activation"), + TxKind::Deployment => write!(f, "deployment"), // 배포 트랜잭션 + TxKind::Activation => write!(f, "activation"), // 활성화 트랜잭션 } } } sol! { interface ArbWasm { + // Arbitrum WASM 프로그램을 활성화하는 Solidity 함수 정의 function activateProgram(address program) external payable @@ -52,14 +55,16 @@ sol! { } } -type SignerClient = SignerMiddleware, Wallet>; +type SignerClient = SignerMiddleware, Wallet>; // 서명된 트랜잭션을 보내기 위한 클라이언트 타입 fn write_tx_data(tx_kind: TxKind, data: &[u8]) -> eyre::Result<()> { + // 트랜잭션 데이터를 파일로 작성하는 함수 let file_name = format!("{tx_kind}_tx_data"); let mut path = PathBuf::new(); path.push("./output"); if !path.exists() { fs::create_dir_all(&path).map_err(|e| eyre!("could not create output directory: {e}"))?; + // 출력 디렉토리를 생성합니다. } path = path.join(file_name); @@ -76,25 +81,26 @@ fn write_tx_data(tx_kind: TxKind, data: &[u8]) -> eyre::Result<()> { hex ); let mut f = std::fs::File::create(&path) - .map_err(|e| eyre!("could not create file to write tx data to path {path_str}: {e}",))?; + .map_err(|e| eyre!("could not create file to write tx data to path {path_str}: {e}",))?; // 파일을 생성합니다. f.write_all(data) .map_err(|e| eyre!("could not write tx data as bytes to file to path {path_str}: {e}")) + // 데이터를 파일에 씁니다. } -/// Activates an already deployed Stylus contract by address. +/// 이미 배포된 Stylus 계약을 주소를 통해 활성화합니다. pub async fn activate_contract(cfg: &ActivateConfig) -> Result<()> { - let provider = sys::new_provider(&cfg.common_cfg.endpoint)?; + let provider = sys::new_provider(&cfg.common_cfg.endpoint)?; // 프로바이더를 생성합니다. let chain_id = provider .get_chainid() .await - .wrap_err("failed to get chain id")?; + .wrap_err("failed to get chain id")?; // 체인 ID를 가져옵니다. - let wallet = cfg.auth.wallet().wrap_err("failed to load wallet")?; + let wallet = cfg.auth.wallet().wrap_err("failed to load wallet")?; // 지갑을 로드합니다. let wallet = wallet.with_chain_id(chain_id.as_u64()); - let client = SignerMiddleware::new(provider.clone(), wallet); + let client = SignerMiddleware::new(provider.clone(), wallet); // 서명된 트랜잭션 클라이언트를 생성합니다. - let code = client.get_code(cfg.address, None).await?; - let data_fee = check_activate(code, cfg.address, &provider).await?; + let code = client.get_code(cfg.address, None).await?; // 계약의 코드를 가져옵니다. + let data_fee = check_activate(code, cfg.address, &provider).await?; // 활성화에 필요한 데이터 수수료를 계산합니다. let mut data_fee = alloy_ethers_typecast::alloy_u256_to_ethers(data_fee); greyln!( @@ -105,17 +111,17 @@ pub async fn activate_contract(cfg: &ActivateConfig) -> Result<()> { "bumping estimated activation data fee by {}%", cfg.data_fee_bump_percent.debug_lavender() ); - data_fee = bump_data_fee(data_fee, cfg.data_fee_bump_percent); + data_fee = bump_data_fee(data_fee, cfg.data_fee_bump_percent); // 데이터 수수료를 조정합니다. let contract: Address = cfg.address.to_fixed_bytes().into(); - let data = ArbWasm::activateProgramCall { program: contract }.abi_encode(); + let data = ArbWasm::activateProgramCall { program: contract }.abi_encode(); // 프로그램 활성화 트랜잭션을 생성합니다. let tx = Eip1559TransactionRequest::new() .from(client.address()) .to(*ARB_WASM_H160) .value(data_fee) .data(data); let tx = TypedTransaction::Eip1559(tx); - let tx = client.send_transaction(tx, None).await?; + let tx = client.send_transaction(tx, None).await?; // 트랜잭션을 전송합니다. match tx.await? { Some(receipt) => { greyln!( @@ -125,19 +131,29 @@ pub async fn activate_contract(cfg: &ActivateConfig) -> Result<()> { ); let program: Address = cfg.address.to_fixed_bytes().into(); let data = ArbWasm::activateProgramCall { program }.abi_encode(); - wrtie_tx_data(TxKind::Activation, &data)?; + write_tx_data(TxKind::Activation, &data)?; // 트랜잭션 데이터를 파일로 작성합니다. } None => { bail!( "failed to fetch receipt for contract activation {}", cfg.address - ); + ); // 트랜잭션 영수증을 가져오지 못한 경우 오류를 발생시킵니다. } } Ok(()) } +/// Deploys a stylus program, activating if needed. +pub async fn activate(cfg: &ActivateWithoutPrivateKeyConfig) -> Result<()> { + greyln!("@@@ activate"); + let contract: Address = cfg.address.to_fixed_bytes().into(); + let data = ArbWasm::activateProgramCall { program: contract }.abi_encode(); // 프로그램 활성화 트랜잭션을 생성합니다. + write_tx_data(TxKind::Activation, &data)?; + Ok(()) +} + fn bump_data_fee(fee: U256, pct: u64) -> U256 { + // 데이터 수수료를 지정된 퍼센트만큼 증가시킵니다. let num = 100 + pct; fee * U256::from(num) / U256::from(100) } diff --git a/check/src/main.rs b/check/src/main.rs index 904b7da..1b2e686 100644 --- a/check/src/main.rs +++ b/check/src/main.rs @@ -60,7 +60,7 @@ enum Apis { }, /// Activate an already deployed contract. #[command(alias = "a")] - Activate(ActivateConfig), + Activate(ActivateWithoutPrivateKeyConfig), /// Cache a contract using the Stylus CacheManager for Arbitrum chains. Cache(CacheConfig), /// Check a contract. @@ -137,6 +137,13 @@ pub struct ActivateConfig { data_fee_bump_percent: u64, } +#[derive(Args, Clone, Debug)] +pub struct ActivateWithoutPrivateKeyConfig { + /// Deployed Stylus contract address to activate. + #[arg(long)] + address: H160, +} + #[derive(Args, Clone, Debug)] pub struct CheckConfig { #[command(flatten)] @@ -339,10 +346,7 @@ async fn main_impl(args: Opts) -> Result<()> { run!(export_abi::export_abi(output, json), "failed to export abi"); } Apis::Activate(config) => { - run!( - activate::activate_contract(&config).await, - "stylus activate failed" - ); + run!(activate::activate(&config).await, "stylus activate failed"); } Apis::Cache(config) => { run!(cache::cache_contract(&config).await, "stylus cache failed");