diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a95b5edd..3983f5e4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,16 +19,13 @@ jobs: - name: Setup third party dependencies run: | make fetch-thirdparty - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - name: Install solc + - name: Install Geth and solc run: | sudo add-apt-repository ppa:ethereum/ethereum sudo add-apt-repository ppa:ethereum/ethereum-dev sudo apt-get update sudo apt-get install solc + sudo apt-get install ethereum - name: Build run: | make build diff --git a/Cargo.lock b/Cargo.lock index 3b25d181..7788259f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,6 +35,7 @@ dependencies = [ "ron", "serde", "serde_json", + "tempdir", "tokio", "tonic", "tonic-build", @@ -570,7 +571,7 @@ dependencies = [ "hex", "hmac", "pbkdf2", - "rand", + "rand 0.8.5", "sha2 0.10.6", "thiserror", ] @@ -682,7 +683,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ "generic-array 0.14.6", - "rand_core", + "rand_core 0.6.4", "subtle", "zeroize", ] @@ -855,7 +856,7 @@ dependencies = [ "generic-array 0.14.6", "group", "pkcs8", - "rand_core", + "rand_core 0.6.4", "sec1", "subtle", "zeroize", @@ -891,7 +892,7 @@ dependencies = [ "hex", "k256", "log", - "rand", + "rand 0.8.5", "rlp", "serde", "sha3", @@ -945,7 +946,7 @@ dependencies = [ "hex", "hmac", "pbkdf2", - "rand", + "rand 0.8.5", "scrypt", "serde", "serde_json", @@ -1119,7 +1120,7 @@ dependencies = [ "once_cell", "open-fastrlp", "proc-macro2", - "rand", + "rand 0.8.5", "rlp", "rlp-derive", "serde", @@ -1220,7 +1221,7 @@ dependencies = [ "eth-keystore", "ethers-core", "hex", - "rand", + "rand 0.8.5", "sha2 0.10.6", "thiserror", ] @@ -1303,7 +1304,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" dependencies = [ - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -1314,7 +1315,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ "byteorder", - "rand", + "rand 0.8.5", "rustc-hex", "static_assertions", ] @@ -1340,6 +1341,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + [[package]] name = "funty" version = "2.0.0" @@ -1518,7 +1525,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ "ff", - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -1859,7 +1866,7 @@ dependencies = [ "hyper", "jsonrpsee-types", "parking_lot 0.12.1", - "rand", + "rand 0.8.5", "rustc-hash", "serde", "serde_json", @@ -2276,7 +2283,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" dependencies = [ "base64ct", - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -2341,7 +2348,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" dependencies = [ "phf_shared 0.11.1", - "rand", + "rand 0.8.5", ] [[package]] @@ -2588,6 +2595,19 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi", +] + [[package]] name = "rand" version = "0.8.5" @@ -2596,7 +2616,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -2606,9 +2626,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", ] +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + [[package]] name = "rand_core" version = "0.6.4" @@ -2640,6 +2675,15 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -3092,7 +3136,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ "digest 0.10.6", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -3138,7 +3182,7 @@ dependencies = [ "http", "httparse", "log", - "rand", + "rand 0.8.5", "sha-1", ] @@ -3247,6 +3291,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tempdir" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" +dependencies = [ + "rand 0.4.6", + "remove_dir_all", +] + [[package]] name = "tempfile" version = "3.3.0" @@ -3477,7 +3531,7 @@ dependencies = [ "indexmap", "pin-project", "pin-project-lite", - "rand", + "rand 0.8.5", "slab", "tokio", "tokio-util", diff --git a/Cargo.toml b/Cargo.toml index ddf02281..8e774632 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,9 @@ tonic = { version = "0.8", default-features = false, features = [ tracing = "0.1" tracing-subscriber = "0.3" +[dev-dependencies] +tempdir = "0.3.7" + [build-dependencies] anyhow = "1" ethers = { git = "https://github.com/gakonst/ethers-rs.git", rev = "c60990d7b6e6b3034f1e50b27b495aeda30e35e8", features = ["ethers-solc"] } diff --git a/README.md b/README.md index 90a677f1..90505b04 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ For more information: https://hackmd.io/@Vid201/aa-bundler-rust ## Prerequisites -1. Ethereum execution client JSON-RPC API with enabled [`debug_traceCall`](https://geth.ethereum.org/docs/interacting-with-geth/rpc/ns-debug#debug_tracecall). For production, you can use [Geth](https://github.com/ethereum/go-ethereum) or [Erigon](https://github.com/ledgerwatch/erigon). For testing purposes, you can use [Anvil](https://github.com/foundry-rs/foundry/tree/master/anvil#anvil), which provides enough functionalities of execution clients like Geth. To install Anvil, use [foundryup](https://getfoundry.sh/) +1. Ethereum execution client JSON-RPC API with enabled [`debug_traceCall`](https://geth.ethereum.org/docs/interacting-with-geth/rpc/ns-debug#debug_tracecall). For production, you can use [Geth](https://github.com/ethereum/go-ethereum) or [Erigon](https://github.com/ledgerwatch/erigon). For testing, we are using Geth dev mode; so you need to install [Geth](https://geth.ethereum.org/docs/getting-started/installing-geth) for running tests. 2. [solc](https://docs.soliditylang.org/en/v0.8.17/installing-solidity.html) >=0.8.12 ## How to run? diff --git a/src/contracts/entrypoint.rs b/src/contracts/entrypoint.rs index 20dd3077..483712ec 100644 --- a/src/contracts/entrypoint.rs +++ b/src/contracts/entrypoint.rs @@ -40,21 +40,19 @@ impl EntryPoint { ) -> Result { JsonRpcError::from_str(err_msg) .map_err(|_| { - EntryPointErr::DecodeErr(format!( - "{:?} is not a valid JsonRpcError message", - err_msg - )) + EntryPointErr::DecodeErr(format!("{err_msg:?} is not a valid JsonRpcError message")) }) .and_then(|json_error| { json_error.data.ok_or_else(|| { - EntryPointErr::DecodeErr("{:?} doesn't have valid data field".to_string()) + EntryPointErr::DecodeErr( + "{json_error:?} doesn't have valid data field".to_string(), + ) }) }) .and_then(|data: String| { AbiDecode::decode_hex(data).map_err(|_| { EntryPointErr::DecodeErr(format!( - "{:?} data field could not be deserialize to EntryPointAPIErrors", - err_msg + "{err_msg:?} data field could not be deserialize to EntryPointAPIErrors" )) }) }) @@ -84,8 +82,7 @@ impl EntryPoint { )) } _ => Err(EntryPointErr::UnknownErr(format!( - "Simulate validation with invalid error: {:?}", - op + "Simulate validation with invalid error: {op:?}" ))), }) } @@ -107,8 +104,7 @@ impl EntryPoint { Err(EntryPointErr::FailedOp(failed_op)) } _ => Err(EntryPointErr::UnknownErr(format!( - "Handle ops with invalid error: {:?}", - op + "Handle ops with invalid error: {op:?}" ))), }) }) @@ -132,8 +128,7 @@ impl EntryPoint { Err(EntryPointErr::FailedOp(failed_op)) } _ => Err(EntryPointErr::UnknownErr(format!( - "Simulate validation with invalid error: {:?}", - op + "Simulate validation with invalid error: {op:?}" ))), }) } diff --git a/src/utils.rs b/src/utils.rs index 46dfc16b..60bee535 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -2,8 +2,8 @@ use ethers::types::{Address, U256}; use std::str::FromStr; pub fn parse_address(s: &str) -> Result { - Address::from_str(s).map_err(|_| format!("Adress {} is not a valid address", s)) + Address::from_str(s).map_err(|_| format!("Adress {s} is not a valid address")) } pub fn parse_u256(s: &str) -> Result { - U256::from_str_radix(s, 10).map_err(|_| format!("{} is not a valid U256", s)) + U256::from_str_radix(s, 10).map_err(|_| format!("{s} is not a valid U256")) } diff --git a/tests/common/mod.rs b/tests/common/mod.rs index d16ad027..53f9d97a 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -14,8 +14,7 @@ use self::gen::{ }; pub mod gen; -pub const ANVIL_TEST_KEY_PHRASE: &str = - "test test test test test test test test test test test junk"; +pub const KEY_PHRASE: &str = "test test test test test test test test test test test junk"; pub struct DeployedContract { contract: C, diff --git a/tests/validate_tests.rs b/tests/validate_tests.rs index d0c281d6..ff65b534 100644 --- a/tests/validate_tests.rs +++ b/tests/validate_tests.rs @@ -5,22 +5,24 @@ use common::gen::{ EntryPointContract, TestOpcodesAccount, TestOpcodesAccountFactory, TestRulesAccount, TestRulesAccountFactory, TestStorageAccountFactory, }; -use common::DeployedContract; +use common::{DeployedContract, KEY_PHRASE}; use ethers::abi::Token; -use ethers::prelude::BaseContract; +use ethers::prelude::{BaseContract, MiddlewareBuilder, NonceManagerMiddleware}; use ethers::providers::Http; +use ethers::signers::coins_bip39::English; +use ethers::signers::MnemonicBuilder; use ethers::types::transaction::eip2718::TypedTransaction; -use ethers::types::Address; -use ethers::utils::{parse_units, AnvilInstance}; +use ethers::types::{Address, TransactionRequest}; +use ethers::utils::{parse_units, Geth, GethInstance}; use ethers::{ - core::utils::Anvil, prelude::SignerMiddleware, providers::{Middleware, Provider}, signers::{LocalWallet, Signer}, types::{Bytes, U256}, }; -use std::ops::Deref; +use std::ops::{Deref, Mul}; use std::{convert::TryFrom, sync::Arc, time::Duration}; +use tempdir::TempDir; use crate::common::{ deploy_entry_point, deploy_test_opcode_account, deploy_test_opcode_account_factory, @@ -30,7 +32,7 @@ use crate::common::{ struct TestContext { pub client: Arc, - pub _anvil: AnvilInstance, + pub _geth: GethInstance, pub entry_point: DeployedContract>, pub paymaster: DeployedContract>, pub opcodes_factory: DeployedContract>, @@ -39,18 +41,31 @@ struct TestContext { pub storage_account: DeployedContract>, } -type ClientType = SignerMiddleware, LocalWallet>; +type ClientType = NonceManagerMiddleware, LocalWallet>>; async fn setup() -> anyhow::Result> { - let anvil = Anvil::new().spawn(); + let chain_id: u64 = 1337; + let tmp_dir = TempDir::new("test_geth")?; + let wallet = MnemonicBuilder::::default() + .phrase(KEY_PHRASE) + .build()?; + + let geth = Geth::new().data_dir(tmp_dir.path().to_path_buf()).spawn(); let provider = - Provider::::try_from(anvil.endpoint())?.interval(Duration::from_millis(10u64)); - let wallet: LocalWallet = anvil.keys()[0].clone().into(); + Provider::::try_from(geth.endpoint())?.interval(Duration::from_millis(10u64)); + + let client = Arc::new( + SignerMiddleware::new(provider.clone(), wallet.clone().with_chain_id(chain_id)) + .nonce_manager(wallet.address()), + ); + + let coinbase = client.clone().get_accounts().await?[0]; + let tx = TransactionRequest::new() + .to(wallet.address()) + .value(U256::from(10).pow(U256::from(18)).mul(100)) + .from(coinbase); + provider.send_transaction(tx, None).await?.await?; - let client = Arc::new(SignerMiddleware::new( - provider, - wallet.clone().with_chain_id(anvil.chain_id()), - )); let entry_point = deploy_entry_point(client.clone()).await?; let paymaster = deploy_test_opcode_account(client.clone()).await?; entry_point @@ -83,7 +98,7 @@ async fn setup() -> anyhow::Result> { .await?; Ok(TestContext:: { client: client.clone(), - _anvil: anvil, + _geth: geth, entry_point, paymaster, opcodes_factory,