From da032670e51d1f46272c3661b11269109cf99602 Mon Sep 17 00:00:00 2001 From: bkolad Date: Thu, 5 Oct 2023 19:48:43 +0200 Subject: [PATCH 01/13] add pre_state_root in evm hook --- examples/demo-stf/src/hooks_impl.rs | 2 +- module-system/module-implementations/sov-evm/src/hooks.rs | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/examples/demo-stf/src/hooks_impl.rs b/examples/demo-stf/src/hooks_impl.rs index 38e786a69..cfa29fd8d 100644 --- a/examples/demo-stf/src/hooks_impl.rs +++ b/examples/demo-stf/src/hooks_impl.rs @@ -89,7 +89,7 @@ impl SlotHooks for Runtime { ) { #[cfg(feature = "experimental")] self.evm - .begin_slot_hook(slot_header.hash().into(), working_set); + .begin_slot_hook(slot_header.hash().into(), &pre_state_root, working_set); self.chain_state.begin_slot_hook( slot_header, diff --git a/module-system/module-implementations/sov-evm/src/hooks.rs b/module-system/module-implementations/sov-evm/src/hooks.rs index ad0c28427..b1cdfb1cf 100644 --- a/module-system/module-implementations/sov-evm/src/hooks.rs +++ b/module-system/module-implementations/sov-evm/src/hooks.rs @@ -11,7 +11,12 @@ where ::Root: Into<[u8; 32]>, { /// Logic executed at the beginning of the slot. Here we set the root hash of the previous head. - pub fn begin_slot_hook(&self, da_root_hash: [u8; 32], working_set: &mut WorkingSet) { + pub fn begin_slot_hook( + &self, + da_root_hash: [u8; 32], + _pre_state_root: &<::Storage as Storage>::Root, + working_set: &mut WorkingSet, + ) { let parent_block = self .head .get(working_set) From 77ed281c8bb8b710f28a23977f1fe5b9cd43129f Mon Sep 17 00:00:00 2001 From: bkolad Date: Thu, 5 Oct 2023 19:54:40 +0200 Subject: [PATCH 02/13] fix tests --- .../sov-evm/src/tests/call_tests.rs | 4 ++-- .../sov-evm/src/tests/hooks_tests.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/module-system/module-implementations/sov-evm/src/tests/call_tests.rs b/module-system/module-implementations/sov-evm/src/tests/call_tests.rs index 17a8c78a4..f18fd24a6 100644 --- a/module-system/module-implementations/sov-evm/src/tests/call_tests.rs +++ b/module-system/module-implementations/sov-evm/src/tests/call_tests.rs @@ -77,7 +77,7 @@ fn evm_test() { .as_slice(), ); - evm.begin_slot_hook([5u8; 32], working_set); + evm.begin_slot_hook([5u8; 32], &[10u8; 32].into(), working_set); let set_arg = 999; let sender_context = C::new( @@ -140,7 +140,7 @@ fn failed_transaction_test() { .as_slice(), ); - evm.begin_slot_hook([5u8; 32], working_set); + evm.begin_slot_hook([5u8; 32], &[10u8; 32].into(), working_set); let set_arg = 999; let sender_context = C::new( diff --git a/module-system/module-implementations/sov-evm/src/tests/hooks_tests.rs b/module-system/module-implementations/sov-evm/src/tests/hooks_tests.rs index 35174c414..736fbba53 100644 --- a/module-system/module-implementations/sov-evm/src/tests/hooks_tests.rs +++ b/module-system/module-implementations/sov-evm/src/tests/hooks_tests.rs @@ -19,7 +19,7 @@ lazy_static! { #[test] fn begin_slot_hook_creates_pending_block() { let (evm, mut working_set) = get_evm(&TEST_CONFIG); - evm.begin_slot_hook(DA_ROOT_HASH.0, &mut working_set); + evm.begin_slot_hook(DA_ROOT_HASH.0, &[10u8; 32].into(), &mut working_set); let pending_block = evm.block_env.get(&mut working_set).unwrap(); assert_eq!( pending_block, @@ -37,7 +37,7 @@ fn begin_slot_hook_creates_pending_block() { #[test] fn end_slot_hook_sets_head() { let (evm, mut working_set) = get_evm(&TEST_CONFIG); - evm.begin_slot_hook(DA_ROOT_HASH.0, &mut working_set); + evm.begin_slot_hook(DA_ROOT_HASH.0, &[10u8; 32].into(), &mut working_set); evm.pending_transactions.push( &create_pending_transaction(H256::from([1u8; 32]), 1), @@ -98,7 +98,7 @@ fn end_slot_hook_sets_head() { #[test] fn end_slot_hook_moves_transactions_and_receipts() { let (evm, mut working_set) = get_evm(&TEST_CONFIG); - evm.begin_slot_hook(DA_ROOT_HASH.0, &mut working_set); + evm.begin_slot_hook(DA_ROOT_HASH.0, [10u8; 32].into(), &mut working_set); let tx1 = create_pending_transaction(H256::from([1u8; 32]), 1); evm.pending_transactions.push(&tx1, &mut working_set); @@ -180,7 +180,7 @@ fn create_pending_transaction(hash: H256, index: u64) -> PendingTransaction { #[test] fn finalize_hook_creates_final_block() { let (evm, mut working_set) = get_evm(&TEST_CONFIG); - evm.begin_slot_hook(DA_ROOT_HASH.0, &mut working_set); + evm.begin_slot_hook(DA_ROOT_HASH.0, [10u8; 32].into(), &mut working_set); evm.pending_transactions.push( &create_pending_transaction(H256::from([1u8; 32]), 1), &mut working_set, From b7cf98b298e529cd5f6330413d62b510451356be Mon Sep 17 00:00:00 2001 From: bkolad Date: Thu, 5 Oct 2023 19:57:00 +0200 Subject: [PATCH 03/13] fix test --- .../module-implementations/sov-evm/src/tests/hooks_tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module-system/module-implementations/sov-evm/src/tests/hooks_tests.rs b/module-system/module-implementations/sov-evm/src/tests/hooks_tests.rs index 736fbba53..572fdae71 100644 --- a/module-system/module-implementations/sov-evm/src/tests/hooks_tests.rs +++ b/module-system/module-implementations/sov-evm/src/tests/hooks_tests.rs @@ -98,7 +98,7 @@ fn end_slot_hook_sets_head() { #[test] fn end_slot_hook_moves_transactions_and_receipts() { let (evm, mut working_set) = get_evm(&TEST_CONFIG); - evm.begin_slot_hook(DA_ROOT_HASH.0, [10u8; 32].into(), &mut working_set); + evm.begin_slot_hook(DA_ROOT_HASH.0, &[10u8; 32].into(), &mut working_set); let tx1 = create_pending_transaction(H256::from([1u8; 32]), 1); evm.pending_transactions.push(&tx1, &mut working_set); @@ -180,7 +180,7 @@ fn create_pending_transaction(hash: H256, index: u64) -> PendingTransaction { #[test] fn finalize_hook_creates_final_block() { let (evm, mut working_set) = get_evm(&TEST_CONFIG); - evm.begin_slot_hook(DA_ROOT_HASH.0, [10u8; 32].into(), &mut working_set); + evm.begin_slot_hook(DA_ROOT_HASH.0, &[10u8; 32].into(), &mut working_set); evm.pending_transactions.push( &create_pending_transaction(H256::from([1u8; 32]), 1), &mut working_set, From 9ad8cfa8e5455f23879a8596220cc137e35d41e4 Mon Sep 17 00:00:00 2001 From: bkolad Date: Fri, 6 Oct 2023 18:03:38 +0200 Subject: [PATCH 04/13] fix root hash --- examples/demo-rollup/tests/evm/mod.rs | 16 +++++++++++++++ .../sov-evm/src/hooks.rs | 12 +++++------ .../sov-evm/src/tests/hooks_tests.rs | 20 +++++++++++++------ 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/examples/demo-rollup/tests/evm/mod.rs b/examples/demo-rollup/tests/evm/mod.rs index 4c503f17c..7a0dad5e0 100644 --- a/examples/demo-rollup/tests/evm/mod.rs +++ b/examples/demo-rollup/tests/evm/mod.rs @@ -419,6 +419,22 @@ impl TestClient { self.send_publish_batch_request().await; + // second block + self.send_publish_batch_request().await; + + let first_block = self.eth_get_block_by_number(Some("0".to_owned())).await; + let second_block = self.eth_get_block_by_number(Some("1".to_owned())).await; + + println!("first_block: {:?}", first_block); + println!("second_block: {:?}", second_block); + + // assert parent hash + assert_eq!( + first_block.hash.unwrap(), + second_block.parent_hash, + "Parent hash should be the hash of the previous block" + ); + for req in requests { req.await.unwrap(); } diff --git a/module-system/module-implementations/sov-evm/src/hooks.rs b/module-system/module-implementations/sov-evm/src/hooks.rs index b1cdfb1cf..ec86183d2 100644 --- a/module-system/module-implementations/sov-evm/src/hooks.rs +++ b/module-system/module-implementations/sov-evm/src/hooks.rs @@ -1,4 +1,4 @@ -use reth_primitives::{Bloom, Bytes, U256}; +use reth_primitives::{Bloom, Bytes, U256, H256}; use sov_modules_api::{AccessoryWorkingSet, Spec, WorkingSet}; use sov_state::Storage; @@ -14,17 +14,17 @@ where pub fn begin_slot_hook( &self, da_root_hash: [u8; 32], - _pre_state_root: &<::Storage as Storage>::Root, + pre_state_root: &<::Storage as Storage>::Root, working_set: &mut WorkingSet, ) { - let parent_block = self + let mut parent_block = self .head .get(working_set) .expect("Head block should always be set"); - // TODO - // parent_block.header.state_root = root_hash.into(); - // self.head.set(&parent_block, working_set); + + parent_block.header.state_root = H256(pre_state_root.clone().into()); + self.head.set(&parent_block, working_set); let cfg = self.cfg.get(working_set).unwrap_or_default(); let new_pending_env = BlockEnv { diff --git a/module-system/module-implementations/sov-evm/src/tests/hooks_tests.rs b/module-system/module-implementations/sov-evm/src/tests/hooks_tests.rs index 572fdae71..d5054888e 100644 --- a/module-system/module-implementations/sov-evm/src/tests/hooks_tests.rs +++ b/module-system/module-implementations/sov-evm/src/tests/hooks_tests.rs @@ -180,7 +180,8 @@ fn create_pending_transaction(hash: H256, index: u64) -> PendingTransaction { #[test] fn finalize_hook_creates_final_block() { let (evm, mut working_set) = get_evm(&TEST_CONFIG); - evm.begin_slot_hook(DA_ROOT_HASH.0, &[10u8; 32].into(), &mut working_set); + let p = [10u8; 32].into(); + evm.begin_slot_hook(DA_ROOT_HASH.0, &p, &mut working_set); evm.pending_transactions.push( &create_pending_transaction(H256::from([1u8; 32]), 1), &mut working_set, @@ -191,12 +192,19 @@ fn finalize_hook_creates_final_block() { ); evm.end_slot_hook(&mut working_set); - let mut accessory_state = working_set.accessory_state(); let root_hash = [99u8; 32].into(); - evm.finalize_hook(&root_hash, &mut accessory_state); + { + let mut accessory_state = working_set.accessory_state(); + evm.finalize_hook(&root_hash, &mut accessory_state); + assert_eq!(evm.blocks.len(&mut accessory_state), 2); + } - assert_eq!(evm.blocks.len(&mut accessory_state), 2); + evm.begin_slot_hook(DA_ROOT_HASH.0, &root_hash, &mut working_set); + + let mut accessory_state = working_set.accessory_state(); + let parent_block = evm.blocks.get(0usize, &mut accessory_state).unwrap(); + let parent_hash = parent_block.header.hash; let block = evm.blocks.get(1usize, &mut accessory_state).unwrap(); assert_eq!( @@ -204,7 +212,7 @@ fn finalize_hook_creates_final_block() { SealedBlock { header: SealedHeader { header: Header { - parent_hash: SEALED_GENESIS_HASH, + parent_hash, ommers_hash: EMPTY_OMMER_ROOT, beneficiary: TEST_CONFIG.coinbase, state_root: H256::from(root_hash.0), @@ -232,7 +240,7 @@ fn finalize_hook_creates_final_block() { parent_beacon_block_root: None, }, hash: H256(hex!( - "0da4e80c5cbd00d9538cb0215d069bfee5be5b59ae4da00244f9b8db429e6889" + "38cd68642013a65c7fdeea92f9f0e1b5709156ac9140f00ffb182c7a605337b0" )), }, transactions: 0..2 From 566f7a702bba1658b14906150186900bd22630ee Mon Sep 17 00:00:00 2001 From: bkolad Date: Sat, 7 Oct 2023 13:22:54 +0200 Subject: [PATCH 05/13] fix crago fmt --- module-system/module-implementations/sov-evm/src/hooks.rs | 3 +-- .../sov-evm/src/tests/genesis_tests.rs | 4 ---- .../sov-evm/src/tests/hooks_tests.rs | 8 +++----- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/module-system/module-implementations/sov-evm/src/hooks.rs b/module-system/module-implementations/sov-evm/src/hooks.rs index ec86183d2..8beeb5f50 100644 --- a/module-system/module-implementations/sov-evm/src/hooks.rs +++ b/module-system/module-implementations/sov-evm/src/hooks.rs @@ -1,4 +1,4 @@ -use reth_primitives::{Bloom, Bytes, U256, H256}; +use reth_primitives::{Bloom, Bytes, H256, U256}; use sov_modules_api::{AccessoryWorkingSet, Spec, WorkingSet}; use sov_state::Storage; @@ -22,7 +22,6 @@ where .get(working_set) .expect("Head block should always be set"); - parent_block.header.state_root = H256(pre_state_root.clone().into()); self.head.set(&parent_block, working_set); diff --git a/module-system/module-implementations/sov-evm/src/tests/genesis_tests.rs b/module-system/module-implementations/sov-evm/src/tests/genesis_tests.rs index 669c5e86f..16e3c0275 100644 --- a/module-system/module-implementations/sov-evm/src/tests/genesis_tests.rs +++ b/module-system/module-implementations/sov-evm/src/tests/genesis_tests.rs @@ -41,10 +41,6 @@ pub(crate) const GENESIS_HASH: H256 = H256(hex!( "3441c3084e43183a53aabbbe3e94512bb3db4aca826af8f23b38f0613811571d" )); -pub(crate) const SEALED_GENESIS_HASH: H256 = H256(hex!( - "d57423e4375c45bc114cd137146aab671dbd3f6304f05b31bdd416301b4a99f0" -)); - pub(crate) const GENESIS_STATE_ROOT: H256 = H256(hex!( "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" )); diff --git a/module-system/module-implementations/sov-evm/src/tests/hooks_tests.rs b/module-system/module-implementations/sov-evm/src/tests/hooks_tests.rs index d5054888e..f7d0afaa9 100644 --- a/module-system/module-implementations/sov-evm/src/tests/hooks_tests.rs +++ b/module-system/module-implementations/sov-evm/src/tests/hooks_tests.rs @@ -10,7 +10,7 @@ use crate::evm::primitive_types::{ Block, BlockEnv, Receipt, SealedBlock, TransactionSignedAndRecovered, }; use crate::experimental::PendingTransaction; -use crate::tests::genesis_tests::{BENEFICIARY, SEALED_GENESIS_HASH}; +use crate::tests::genesis_tests::{BENEFICIARY, GENESIS_HASH}; lazy_static! { pub(crate) static ref DA_ROOT_HASH: H256 = H256::from([5u8; 32]); @@ -62,10 +62,8 @@ fn end_slot_hook_sets_head() { Block { header: Header { // TODO: temp parent hash until: https://github.com/Sovereign-Labs/sovereign-sdk/issues/876 - // parent_hash: GENESIS_HASH, - parent_hash: H256(hex!( - "d57423e4375c45bc114cd137146aab671dbd3f6304f05b31bdd416301b4a99f0" - )), + parent_hash: GENESIS_HASH, + ommers_hash: EMPTY_OMMER_ROOT, beneficiary: TEST_CONFIG.coinbase, state_root: KECCAK_EMPTY, From a6586476fc15eb10fc63467b06f72a486177fb3e Mon Sep 17 00:00:00 2001 From: bkolad Date: Sat, 7 Oct 2023 14:31:27 +0200 Subject: [PATCH 06/13] cleanup --- examples/demo-stf/src/hooks_impl.rs | 2 +- .../sov-evm/src/evm/tests.rs | 27 ++-- .../sov-evm/src/tests/call_tests.rs | 142 +++++++++--------- .../sov-evm/src/tests/genesis_tests.rs | 3 +- .../sov-evm/src/tests/hooks_tests.rs | 9 +- 5 files changed, 85 insertions(+), 98 deletions(-) diff --git a/examples/demo-stf/src/hooks_impl.rs b/examples/demo-stf/src/hooks_impl.rs index cfa29fd8d..e41290789 100644 --- a/examples/demo-stf/src/hooks_impl.rs +++ b/examples/demo-stf/src/hooks_impl.rs @@ -89,7 +89,7 @@ impl SlotHooks for Runtime { ) { #[cfg(feature = "experimental")] self.evm - .begin_slot_hook(slot_header.hash().into(), &pre_state_root, working_set); + .begin_slot_hook(slot_header.hash().into(), pre_state_root, working_set); self.chain_state.begin_slot_hook( slot_header, diff --git a/module-system/module-implementations/sov-evm/src/evm/tests.rs b/module-system/module-implementations/sov-evm/src/evm/tests.rs index a5778ec3f..b1c7fe75e 100644 --- a/module-system/module-implementations/sov-evm/src/evm/tests.rs +++ b/module-system/module-implementations/sov-evm/src/evm/tests.rs @@ -1,7 +1,6 @@ use std::convert::Infallible; use reth_primitives::TransactionKind; -use revm::db::CacheDB; use revm::precompile::B160; use revm::primitives::{CfgEnv, ExecutionResult, Output, SpecId, KECCAK_EMPTY, U256}; use revm::{Database, DatabaseCommit}; @@ -18,16 +17,6 @@ use crate::tests::dev_signer::TestSigner; use crate::Evm; type C = sov_modules_api::default_context::DefaultContext; -pub(crate) fn output(result: ExecutionResult) -> bytes::Bytes { - match result { - ExecutionResult::Success { output, .. } => match output { - Output::Call(out) => out, - Output::Create(out, _) => out, - }, - _ => panic!("Expected successful ExecutionResult"), - } -} - #[test] fn simple_contract_execution_sov_state() { let tmpdir = tempfile::tempdir().unwrap(); @@ -40,12 +29,6 @@ fn simple_contract_execution_sov_state() { simple_contract_execution(evm_db); } -#[test] -fn simple_contract_execution_in_memory_state() { - let db = CacheDB::default(); - simple_contract_execution(db); -} - fn simple_contract_execution + DatabaseCommit + InitEvmDb>( mut evm_db: DB, ) { @@ -148,3 +131,13 @@ fn contract_address(result: &ExecutionResult) -> Option { _ => None, } } + +fn output(result: ExecutionResult) -> bytes::Bytes { + match result { + ExecutionResult::Success { output, .. } => match output { + Output::Call(out) => out, + Output::Create(out, _) => out, + }, + _ => panic!("Expected successful ExecutionResult"), + } +} diff --git a/module-system/module-implementations/sov-evm/src/tests/call_tests.rs b/module-system/module-implementations/sov-evm/src/tests/call_tests.rs index f18fd24a6..77a5bc71f 100644 --- a/module-system/module-implementations/sov-evm/src/tests/call_tests.rs +++ b/module-system/module-implementations/sov-evm/src/tests/call_tests.rs @@ -1,10 +1,8 @@ use reth_primitives::{Address, Bytes, TransactionKind}; use revm::primitives::{SpecId, KECCAK_EMPTY, U256}; use sov_modules_api::default_context::DefaultContext; -use sov_modules_api::default_signature::private_key::DefaultPrivateKey; -use sov_modules_api::{Context, Module, Spec}; -#[cfg(test)] -use sov_modules_api::{PrivateKey, PublicKey}; +use sov_modules_api::utils::generate_address; +use sov_modules_api::{Context, Module}; use crate::call::CallMessage; use crate::evm::primitive_types::Receipt; @@ -14,46 +12,9 @@ use crate::tests::genesis_tests::get_evm; use crate::{AccountData, EvmConfig}; type C = DefaultContext; -fn create_messages( - contract_addr: Address, - set_arg: u32, - dev_signer: TestSigner, - create_contract: bool, -) -> Vec { - let mut transactions = Vec::default(); - let contract = SimpleStorageContract::default(); - let mut nonce = 0; - - // Contract creation. - if create_contract { - let signed_tx = dev_signer - .sign_default_transaction(TransactionKind::Create, contract.byte_code().to_vec(), 0) - .unwrap(); - - transactions.push(CallMessage { tx: signed_tx }); - nonce += 1; - } - - // Update contract state. - { - let signed_tx = dev_signer - .sign_default_transaction( - TransactionKind::Call(contract_addr), - hex::decode(hex::encode(&contract.set_call_data(set_arg))).unwrap(), - nonce, - ) - .unwrap(); - - transactions.push(CallMessage { tx: signed_tx }); - } - - transactions -} - #[test] -fn evm_test() { +fn call_test() { let dev_signer: TestSigner = TestSigner::new_random(); - let config = EvmConfig { data: vec![AccountData { address: dev_signer.address(), @@ -69,7 +30,6 @@ fn evm_test() { }; let (evm, mut working_set) = get_evm(&config); - let working_set = &mut working_set; let contract_addr: Address = Address::from_slice( hex::decode("819c5497b157177315e1204f52e588b393771719") @@ -77,23 +37,28 @@ fn evm_test() { .as_slice(), ); - evm.begin_slot_hook([5u8; 32], &[10u8; 32].into(), working_set); + evm.begin_slot_hook([5u8; 32], &[10u8; 32].into(), &mut working_set); let set_arg = 999; - let sender_context = C::new( - DefaultPrivateKey::generate() - .pub_key() - .to_address::<::Address>(), - ); - - for tx in create_messages(contract_addr, set_arg, dev_signer, true) { - evm.call(tx, &sender_context, working_set).unwrap(); + { + let sender_address = generate_address::("sender"); + let context = C::new(sender_address); + + let messages = vec![ + create_contract_message(&dev_signer, 0), + set_arg_message(contract_addr, &dev_signer, 1, set_arg), + ]; + for tx in messages { + evm.call(tx, &context, &mut working_set).unwrap(); + } } + evm.end_slot_hook(&mut working_set); - evm.end_slot_hook(working_set); - - let db_account = evm.accounts.get(&contract_addr, working_set).unwrap(); - let storage_value = db_account.storage.get(&U256::ZERO, working_set).unwrap(); + let db_account = evm.accounts.get(&contract_addr, &mut working_set).unwrap(); + let storage_value = db_account + .storage + .get(&U256::ZERO, &mut working_set) + .unwrap(); assert_eq!(U256::from(set_arg), storage_value); assert_eq!( @@ -130,29 +95,30 @@ fn evm_test() { #[test] fn failed_transaction_test() { let dev_signer: TestSigner = TestSigner::new_random(); - let (evm, mut working_set) = get_evm(&EvmConfig::default()); let working_set = &mut working_set; - let contract_addr: Address = Address::from_slice( - hex::decode("819c5497b157177315e1204f52e588b393771719") - .unwrap() - .as_slice(), - ); - evm.begin_slot_hook([5u8; 32], &[10u8; 32].into(), working_set); - let set_arg = 999; - let sender_context = C::new( - DefaultPrivateKey::generate() - .pub_key() - .to_address::<::Address>(), - ); - - for tx in create_messages(contract_addr, set_arg, dev_signer, false) { - evm.call(tx, &sender_context, working_set).unwrap(); + { + let contract_addr: Address = Address::from_slice( + hex::decode("819c5497b157177315e1204f52e588b393771719") + .unwrap() + .as_slice(), + ); + + let sender_address = generate_address::("sender"); + let set_arg = 999; + let context = C::new(sender_address); + + let messages = vec![ + create_contract_message(&dev_signer, 0), + set_arg_message(contract_addr, &dev_signer, 1, set_arg), + ]; + for tx in messages { + evm.call(tx, &context, working_set).unwrap(); + } } - evm.end_slot_hook(working_set); assert_eq!( @@ -177,3 +143,33 @@ fn failed_transaction_test() { }] ) } + +fn create_contract_message(dev_signer: &TestSigner, nonce: u64) -> CallMessage { + let contract = SimpleStorageContract::default(); + let signed_tx = dev_signer + .sign_default_transaction( + TransactionKind::Create, + contract.byte_code().to_vec(), + nonce, + ) + .unwrap(); + CallMessage { tx: signed_tx } +} + +fn set_arg_message( + contract_addr: Address, + dev_signer: &TestSigner, + nonce: u64, + set_arg: u32, +) -> CallMessage { + let contract = SimpleStorageContract::default(); + let signed_tx = dev_signer + .sign_default_transaction( + TransactionKind::Call(contract_addr), + hex::decode(hex::encode(&contract.set_call_data(set_arg))).unwrap(), + nonce, + ) + .unwrap(); + + CallMessage { tx: signed_tx } +} diff --git a/module-system/module-implementations/sov-evm/src/tests/genesis_tests.rs b/module-system/module-implementations/sov-evm/src/tests/genesis_tests.rs index 16e3c0275..275ff2f83 100644 --- a/module-system/module-implementations/sov-evm/src/tests/genesis_tests.rs +++ b/module-system/module-implementations/sov-evm/src/tests/genesis_tests.rs @@ -132,6 +132,7 @@ fn genesis_block() { .block_hashes .get(&GENESIS_HASH, &mut accessory_state) .unwrap(); + let block = evm .blocks .get(block_number as usize, &mut accessory_state) @@ -177,7 +178,6 @@ fn genesis_block() { #[test] fn genesis_head() { let (evm, mut working_set) = get_evm(&TEST_CONFIG); - let head = evm.head.get(&mut working_set).unwrap(); assert_eq!( @@ -216,6 +216,5 @@ pub(crate) fn get_evm(config: &EvmConfig) -> (Evm, WorkingSet let evm = Evm::::default(); evm.genesis(config, &mut working_set).unwrap(); evm.finalize_hook(&[10u8; 32].into(), &mut working_set.accessory_state()); - (evm, working_set) } diff --git a/module-system/module-implementations/sov-evm/src/tests/hooks_tests.rs b/module-system/module-implementations/sov-evm/src/tests/hooks_tests.rs index f7d0afaa9..d6b3e2388 100644 --- a/module-system/module-implementations/sov-evm/src/tests/hooks_tests.rs +++ b/module-system/module-implementations/sov-evm/src/tests/hooks_tests.rs @@ -191,11 +191,10 @@ fn finalize_hook_creates_final_block() { evm.end_slot_hook(&mut working_set); let root_hash = [99u8; 32].into(); - { - let mut accessory_state = working_set.accessory_state(); - evm.finalize_hook(&root_hash, &mut accessory_state); - assert_eq!(evm.blocks.len(&mut accessory_state), 2); - } + + let mut accessory_state = working_set.accessory_state(); + evm.finalize_hook(&root_hash, &mut accessory_state); + assert_eq!(evm.blocks.len(&mut accessory_state), 2); evm.begin_slot_hook(DA_ROOT_HASH.0, &root_hash, &mut working_set); From 60b8891db7f8231dd29a4a5f3a17a70906249901 Mon Sep 17 00:00:00 2001 From: bkolad Date: Sat, 7 Oct 2023 15:06:02 +0200 Subject: [PATCH 07/13] fix tests --- .../sov-evm/src/tests/call_tests.rs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/module-system/module-implementations/sov-evm/src/tests/call_tests.rs b/module-system/module-implementations/sov-evm/src/tests/call_tests.rs index 77a5bc71f..da4888ff0 100644 --- a/module-system/module-implementations/sov-evm/src/tests/call_tests.rs +++ b/module-system/module-implementations/sov-evm/src/tests/call_tests.rs @@ -101,20 +101,10 @@ fn failed_transaction_test() { evm.begin_slot_hook([5u8; 32], &[10u8; 32].into(), working_set); { - let contract_addr: Address = Address::from_slice( - hex::decode("819c5497b157177315e1204f52e588b393771719") - .unwrap() - .as_slice(), - ); - let sender_address = generate_address::("sender"); - let set_arg = 999; let context = C::new(sender_address); - let messages = vec![ - create_contract_message(&dev_signer, 0), - set_arg_message(contract_addr, &dev_signer, 1, set_arg), - ]; + let messages = vec![create_contract_message(&dev_signer, 0)]; for tx in messages { evm.call(tx, &context, working_set).unwrap(); } From 937e7d765899d1d244716074148ce12e5290b952 Mon Sep 17 00:00:00 2001 From: bkolad Date: Sat, 7 Oct 2023 15:15:45 +0200 Subject: [PATCH 08/13] cleanup --- .../module-implementations/sov-evm/src/evm/tests.rs | 2 +- .../module-implementations/sov-evm/src/tests/call_tests.rs | 5 ++--- .../module-implementations/sov-evm/src/tests/mod.rs | 2 +- .../sov-evm/src/tests/{dev_signer.rs => test_signer.rs} | 0 4 files changed, 4 insertions(+), 5 deletions(-) rename module-system/module-implementations/sov-evm/src/tests/{dev_signer.rs => test_signer.rs} (100%) diff --git a/module-system/module-implementations/sov-evm/src/evm/tests.rs b/module-system/module-implementations/sov-evm/src/evm/tests.rs index b1c7fe75e..b66a26644 100644 --- a/module-system/module-implementations/sov-evm/src/evm/tests.rs +++ b/module-system/module-implementations/sov-evm/src/evm/tests.rs @@ -13,7 +13,7 @@ use super::executor; use crate::evm::primitive_types::BlockEnv; use crate::evm::AccountInfo; use crate::smart_contracts::SimpleStorageContract; -use crate::tests::dev_signer::TestSigner; +use crate::tests::test_signer::TestSigner; use crate::Evm; type C = sov_modules_api::default_context::DefaultContext; diff --git a/module-system/module-implementations/sov-evm/src/tests/call_tests.rs b/module-system/module-implementations/sov-evm/src/tests/call_tests.rs index da4888ff0..0dc6cb766 100644 --- a/module-system/module-implementations/sov-evm/src/tests/call_tests.rs +++ b/module-system/module-implementations/sov-evm/src/tests/call_tests.rs @@ -7,8 +7,8 @@ use sov_modules_api::{Context, Module}; use crate::call::CallMessage; use crate::evm::primitive_types::Receipt; use crate::smart_contracts::SimpleStorageContract; -use crate::tests::dev_signer::TestSigner; use crate::tests::genesis_tests::get_evm; +use crate::tests::test_signer::TestSigner; use crate::{AccountData, EvmConfig}; type C = DefaultContext; @@ -99,12 +99,11 @@ fn failed_transaction_test() { let working_set = &mut working_set; evm.begin_slot_hook([5u8; 32], &[10u8; 32].into(), working_set); - { let sender_address = generate_address::("sender"); let context = C::new(sender_address); - let messages = vec![create_contract_message(&dev_signer, 0)]; + for tx in messages { evm.call(tx, &context, working_set).unwrap(); } diff --git a/module-system/module-implementations/sov-evm/src/tests/mod.rs b/module-system/module-implementations/sov-evm/src/tests/mod.rs index da5a19d50..155594fe3 100644 --- a/module-system/module-implementations/sov-evm/src/tests/mod.rs +++ b/module-system/module-implementations/sov-evm/src/tests/mod.rs @@ -1,7 +1,7 @@ mod call_tests; mod cfg_tests; mod config_tests; -pub(crate) mod dev_signer; mod genesis_tests; mod hooks_tests; +pub(crate) mod test_signer; mod tx_tests; diff --git a/module-system/module-implementations/sov-evm/src/tests/dev_signer.rs b/module-system/module-implementations/sov-evm/src/tests/test_signer.rs similarity index 100% rename from module-system/module-implementations/sov-evm/src/tests/dev_signer.rs rename to module-system/module-implementations/sov-evm/src/tests/test_signer.rs From 103a50b6609f62d7d2b0386482edd3ae8d1754e1 Mon Sep 17 00:00:00 2001 From: bkolad Date: Sat, 7 Oct 2023 15:46:47 +0200 Subject: [PATCH 09/13] Update test client --- examples/demo-rollup/tests/evm/mod.rs | 452 +---------------- examples/demo-rollup/tests/evm/test_client.rs | 461 ++++++++++++++++++ 2 files changed, 465 insertions(+), 448 deletions(-) create mode 100644 examples/demo-rollup/tests/evm/test_client.rs diff --git a/examples/demo-rollup/tests/evm/mod.rs b/examples/demo-rollup/tests/evm/mod.rs index b5b61761c..1f93df517 100644 --- a/examples/demo-rollup/tests/evm/mod.rs +++ b/examples/demo-rollup/tests/evm/mod.rs @@ -1,27 +1,15 @@ use std::net::SocketAddr; use std::str::FromStr; +use super::test_helpers::start_rollup; use demo_stf::genesis_config::GenesisPaths; -use ethereum_types::H160; use ethers_core::abi::Address; -use ethers_core::k256::ecdsa::SigningKey; -use ethers_core::types::transaction::eip2718::TypedTransaction; -use ethers_core::types::{ - Block, Eip1559TransactionRequest, Transaction, TransactionRequest, TxHash, -}; -use ethers_middleware::SignerMiddleware; -use ethers_providers::{Http, Middleware, PendingTransaction, Provider}; -use ethers_signers::{LocalWallet, Signer, Wallet}; -use jsonrpsee::core::client::ClientT; -use jsonrpsee::http_client::{HttpClient, HttpClientBuilder}; -use jsonrpsee::rpc_params; -use reth_primitives::Bytes; +use ethers_signers::{LocalWallet, Signer}; use sov_evm::SimpleStorageContract; use sov_risc0_adapter::host::Risc0Host; -use super::test_helpers::start_rollup; - -const MAX_FEE_PER_GAS: u64 = 100000001; +mod test_client; +use test_client::TestClient; const TEST_GENESIS_PATHS: GenesisPaths<&str> = GenesisPaths { bank_genesis_path: "../test-data/genesis/integration-tests/bank.json", @@ -34,438 +22,6 @@ const TEST_GENESIS_PATHS: GenesisPaths<&str> = GenesisPaths { evm_genesis_path: "../test-data/genesis/integration-tests/evm.json", }; -struct TestClient { - chain_id: u64, - from_addr: Address, - contract: SimpleStorageContract, - client: SignerMiddleware, Wallet>, - http_client: HttpClient, -} - -impl TestClient { - #[allow(dead_code)] - async fn new( - chain_id: u64, - key: Wallet, - from_addr: Address, - contract: SimpleStorageContract, - rpc_addr: std::net::SocketAddr, - ) -> Self { - let host = format!("http://localhost:{}", rpc_addr.port()); - - let provider = Provider::try_from(&host).unwrap(); - let client = SignerMiddleware::new_with_provider_chain(provider, key) - .await - .unwrap(); - - let http_client = HttpClientBuilder::default().build(host).unwrap(); - - Self { - chain_id, - from_addr, - contract, - client, - http_client, - } - } - - async fn send_publish_batch_request(&self) { - let _: String = self - .http_client - .request("eth_publishBatch", rpc_params![]) - .await - .unwrap(); - } - - async fn deploy_contract( - &self, - ) -> Result, Box> { - let req = Eip1559TransactionRequest::new() - .from(self.from_addr) - .chain_id(self.chain_id) - .nonce(0u64) - .max_priority_fee_per_gas(10u64) - .max_fee_per_gas(MAX_FEE_PER_GAS) - .gas(900000u64) - .data(self.contract.byte_code()); - - let typed_transaction = TypedTransaction::Eip1559(req); - - let receipt_req = self - .client - .send_transaction(typed_transaction, None) - .await?; - - Ok(receipt_req) - } - - async fn deploy_contract_call(&self) -> Result> { - let req = Eip1559TransactionRequest::new() - .from(self.from_addr) - .chain_id(self.chain_id) - .nonce(0u64) - .max_priority_fee_per_gas(10u64) - .max_fee_per_gas(MAX_FEE_PER_GAS) - .gas(900000u64) - .data(self.contract.byte_code()); - - let typed_transaction = TypedTransaction::Eip1559(req); - - let receipt_req = self.eth_call(typed_transaction, None).await?; - - Ok(receipt_req) - } - - async fn set_value_unsigned( - &self, - contract_address: H160, - set_arg: u32, - ) -> PendingTransaction<'_, Http> { - // Tx without gas_limit should estimate and include it in send_transaction endpoint - // Tx without nonce should fetch and include it in send_transaction endpoint - let req = Eip1559TransactionRequest::new() - .from(self.from_addr) - .to(contract_address) - .chain_id(self.chain_id) - .data(self.contract.set_call_data(set_arg)) - .max_priority_fee_per_gas(10u64) - .max_fee_per_gas(MAX_FEE_PER_GAS); - - let typed_transaction = TypedTransaction::Eip1559(req); - - self.eth_send_transaction(typed_transaction).await - } - - async fn set_value( - &self, - contract_address: H160, - set_arg: u32, - ) -> PendingTransaction<'_, Http> { - let nonce = self.eth_get_transaction_count(self.from_addr).await; - - let req = Eip1559TransactionRequest::new() - .from(self.from_addr) - .to(contract_address) - .chain_id(self.chain_id) - .nonce(nonce) - .data(self.contract.set_call_data(set_arg)) - .max_priority_fee_per_gas(10u64) - .max_fee_per_gas(MAX_FEE_PER_GAS) - .gas(900000u64); - - let typed_transaction = TypedTransaction::Eip1559(req); - - self.client - .send_transaction(typed_transaction, None) - .await - .unwrap() - } - - async fn set_value_call( - &self, - contract_address: H160, - set_arg: u32, - ) -> Result> { - let nonce = self.eth_get_transaction_count(self.from_addr).await; - - // Any type of transaction can be used for eth_call - let req = TransactionRequest::new() - .from(self.from_addr) - .to(contract_address) - .chain_id(self.chain_id) - .nonce(nonce) - .data(self.contract.set_call_data(set_arg)) - .gas_price(10u64); - - let typed_transaction = TypedTransaction::Legacy(req.clone()); - - // Estimate gas on rpc - let gas = self - .eth_estimate_gas(typed_transaction, Some("latest".to_owned())) - .await; - - // Call with the estimated gas - let req = req.gas(gas); - let typed_transaction = TypedTransaction::Legacy(req); - - let response = self - .eth_call(typed_transaction, Some("latest".to_owned())) - .await?; - - Ok(response) - } - - async fn failing_call( - &self, - contract_address: H160, - ) -> Result> { - let nonce = self.eth_get_transaction_count(self.from_addr).await; - - // Any type of transaction can be used for eth_call - let req = Eip1559TransactionRequest::new() - .from(self.from_addr) - .to(contract_address) - .chain_id(self.chain_id) - .nonce(nonce) - .data(self.contract.failing_function_call_data()) - .max_priority_fee_per_gas(10u64) - .max_fee_per_gas(MAX_FEE_PER_GAS) - .gas(900000u64); - - let typed_transaction = TypedTransaction::Eip1559(req); - - self.eth_call(typed_transaction, Some("latest".to_owned())) - .await - } - - async fn query_contract( - &self, - contract_address: H160, - ) -> Result> { - let nonce = self.eth_get_transaction_count(self.from_addr).await; - - let req = Eip1559TransactionRequest::new() - .from(self.from_addr) - .to(contract_address) - .chain_id(self.chain_id) - .nonce(nonce) - .data(self.contract.get_call_data()) - .gas(900000u64); - - let typed_transaction = TypedTransaction::Eip1559(req); - - let response = self.client.call(&typed_transaction, None).await?; - - let resp_array: [u8; 32] = response.to_vec().try_into().unwrap(); - Ok(ethereum_types::U256::from(resp_array)) - } - - async fn eth_accounts(&self) -> Vec
{ - self.http_client - .request("eth_accounts", rpc_params![]) - .await - .unwrap() - } - - async fn eth_send_transaction(&self, tx: TypedTransaction) -> PendingTransaction<'_, Http> { - self.client - .provider() - .send_transaction(tx, None) - .await - .unwrap() - } - - async fn eth_chain_id(&self) -> u64 { - let chain_id: ethereum_types::U64 = self - .http_client - .request("eth_chainId", rpc_params![]) - .await - .unwrap(); - - chain_id.as_u64() - } - - async fn eth_get_balance(&self, address: Address) -> ethereum_types::U256 { - self.http_client - .request("eth_getBalance", rpc_params![address, "latest"]) - .await - .unwrap() - } - - async fn eth_get_storage_at( - &self, - address: Address, - index: ethereum_types::U256, - ) -> ethereum_types::U256 { - self.http_client - .request("eth_getStorageAt", rpc_params![address, index, "latest"]) - .await - .unwrap() - } - - async fn eth_get_code(&self, address: Address) -> Bytes { - self.http_client - .request("eth_getCode", rpc_params![address, "latest"]) - .await - .unwrap() - } - - async fn eth_get_transaction_count(&self, address: Address) -> u64 { - let count: ethereum_types::U64 = self - .http_client - .request("eth_getTransactionCount", rpc_params![address, "latest"]) - .await - .unwrap(); - - count.as_u64() - } - - async fn eth_get_block_by_number(&self, block_number: Option) -> Block { - self.http_client - .request("eth_getBlockByNumber", rpc_params![block_number, false]) - .await - .unwrap() - } - - async fn eth_get_block_by_number_with_detail( - &self, - block_number: Option, - ) -> Block { - self.http_client - .request("eth_getBlockByNumber", rpc_params![block_number, true]) - .await - .unwrap() - } - - async fn eth_call( - &self, - tx: TypedTransaction, - block_number: Option, - ) -> Result> { - self.http_client - .request("eth_call", rpc_params![tx, block_number]) - .await - .map_err(|e| e.into()) - } - - async fn eth_estimate_gas(&self, tx: TypedTransaction, block_number: Option) -> u64 { - let gas: ethereum_types::U64 = self - .http_client - .request("eth_estimateGas", rpc_params![tx, block_number]) - .await - .unwrap(); - - gas.as_u64() - } - - async fn execute(self) -> Result<(), Box> { - // Nonce should be 0 in genesis - let nonce = self.eth_get_transaction_count(self.from_addr).await; - assert_eq!(0, nonce); - - // Balance should be > 0 in genesis - let balance = self.eth_get_balance(self.from_addr).await; - assert!(balance > ethereum_types::U256::zero()); - - let (contract_address, runtime_code) = { - let runtime_code = self.deploy_contract_call().await?; - - let deploy_contract_req = self.deploy_contract().await?; - self.send_publish_batch_request().await; - - let contract_address = deploy_contract_req - .await? - .unwrap() - .contract_address - .unwrap(); - - (contract_address, runtime_code) - }; - - // Assert contract deployed correctly - let code = self.eth_get_code(contract_address).await; - // code has natural following 0x00 bytes, so we need to trim it - assert_eq!(code.to_vec()[..runtime_code.len()], runtime_code.to_vec()); - - // Nonce should be 1 after the deploy - let nonce = self.eth_get_transaction_count(self.from_addr).await; - assert_eq!(1, nonce); - - // Check that the first block has published - // It should have a single transaction, deploying the contract - let first_block = self.eth_get_block_by_number(Some("1".to_owned())).await; - assert_eq!(first_block.number.unwrap().as_u64(), 1); - assert_eq!(first_block.transactions.len(), 1); - - let set_arg = 923; - let tx_hash = { - let set_value_req = self.set_value(contract_address, set_arg).await; - self.send_publish_batch_request().await; - set_value_req.await.unwrap().unwrap().transaction_hash - }; - - let get_arg = self.query_contract(contract_address).await?; - assert_eq!(set_arg, get_arg.as_u32()); - - // Assert storage slot is set - let storage_slot = 0x0; - let storage_value = self - .eth_get_storage_at(contract_address, storage_slot.into()) - .await; - assert_eq!(storage_value, ethereum_types::U256::from(set_arg)); - - // Check that the second block has published - // None should return the latest block - // It should have a single transaction, setting the value - let latest_block = self.eth_get_block_by_number_with_detail(None).await; - assert_eq!(latest_block.number.unwrap().as_u64(), 2); - assert_eq!(latest_block.transactions.len(), 1); - assert_eq!(latest_block.transactions[0].hash, tx_hash); - - // This should just pass without error - self.set_value_call(contract_address, set_arg) - .await - .unwrap(); - - // This call should fail because function does not exist - let failing_call = self.failing_call(contract_address).await; - assert!(failing_call.is_err()); - - // Create a blob with multiple transactions. - let mut requests = Vec::default(); - for value in 100..103 { - let set_value_req = self.set_value(contract_address, value).await; - requests.push(set_value_req); - } - - self.send_publish_batch_request().await; - - // second block - self.send_publish_batch_request().await; - - let first_block = self.eth_get_block_by_number(Some("0".to_owned())).await; - let second_block = self.eth_get_block_by_number(Some("1".to_owned())).await; - - println!("first_block: {:?}", first_block); - println!("second_block: {:?}", second_block); - - // assert parent hash - assert_eq!( - first_block.hash.unwrap(), - second_block.parent_hash, - "Parent hash should be the hash of the previous block" - ); - - for req in requests { - req.await.unwrap(); - } - - { - let get_arg = self.query_contract(contract_address).await?; - assert_eq!(102, get_arg.as_u32()); - } - - { - let value = 103; - - let tx_hash = { - let set_value_req = self.set_value_unsigned(contract_address, value).await; - self.send_publish_batch_request().await; - set_value_req.await.unwrap().unwrap().transaction_hash - }; - - let latest_block = self.eth_get_block_by_number(None).await; - assert_eq!(latest_block.transactions.len(), 1); - assert_eq!(latest_block.transactions[0], tx_hash); - - let get_arg = self.query_contract(contract_address).await?; - assert_eq!(value, get_arg.as_u32()); - } - - Ok(()) - } -} - async fn send_tx_test_to_eth(rpc_address: SocketAddr) -> Result<(), Box> { let chain_id: u64 = 1; let key = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" diff --git a/examples/demo-rollup/tests/evm/test_client.rs b/examples/demo-rollup/tests/evm/test_client.rs new file mode 100644 index 000000000..7fb4c3858 --- /dev/null +++ b/examples/demo-rollup/tests/evm/test_client.rs @@ -0,0 +1,461 @@ +use std::net::SocketAddr; + +use ethereum_types::H160; +use ethers_core::abi::Address; +use ethers_core::k256::ecdsa::SigningKey; +use ethers_core::types::transaction::eip2718::TypedTransaction; +use ethers_core::types::{ + Block, Eip1559TransactionRequest, Transaction, TransactionRequest, TxHash, +}; +use ethers_middleware::SignerMiddleware; +use ethers_providers::{Http, Middleware, PendingTransaction, Provider}; +use ethers_signers::{Signer, Wallet}; +use jsonrpsee::core::client::ClientT; +use jsonrpsee::http_client::{HttpClient, HttpClientBuilder}; +use jsonrpsee::rpc_params; +use reth_primitives::Bytes; +use sov_evm::SimpleStorageContract; + +const MAX_FEE_PER_GAS: u64 = 100000001; + +pub(crate) struct TestClient { + chain_id: u64, + from_addr: Address, + contract: SimpleStorageContract, + client: SignerMiddleware, Wallet>, + http_client: HttpClient, +} + +impl TestClient { + #[allow(dead_code)] + pub(crate) async fn new( + chain_id: u64, + key: Wallet, + from_addr: Address, + contract: SimpleStorageContract, + rpc_addr: std::net::SocketAddr, + ) -> Self { + let host = format!("http://localhost:{}", rpc_addr.port()); + + let provider = Provider::try_from(&host).unwrap(); + let client = SignerMiddleware::new_with_provider_chain(provider, key) + .await + .unwrap(); + + let http_client = HttpClientBuilder::default().build(host).unwrap(); + + Self { + chain_id, + from_addr, + contract, + client, + http_client, + } + } + + pub(crate) async fn send_publish_batch_request(&self) { + let _: String = self + .http_client + .request("eth_publishBatch", rpc_params![]) + .await + .unwrap(); + } + + pub(crate) async fn deploy_contract( + &self, + ) -> Result, Box> { + let req = Eip1559TransactionRequest::new() + .from(self.from_addr) + .chain_id(self.chain_id) + .nonce(0u64) + .max_priority_fee_per_gas(10u64) + .max_fee_per_gas(MAX_FEE_PER_GAS) + .gas(900000u64) + .data(self.contract.byte_code()); + + let typed_transaction = TypedTransaction::Eip1559(req); + + let receipt_req = self + .client + .send_transaction(typed_transaction, None) + .await?; + + Ok(receipt_req) + } + + pub(crate) async fn deploy_contract_call(&self) -> Result> { + let req = Eip1559TransactionRequest::new() + .from(self.from_addr) + .chain_id(self.chain_id) + .nonce(0u64) + .max_priority_fee_per_gas(10u64) + .max_fee_per_gas(MAX_FEE_PER_GAS) + .gas(900000u64) + .data(self.contract.byte_code()); + + let typed_transaction = TypedTransaction::Eip1559(req); + + let receipt_req = self.eth_call(typed_transaction, None).await?; + + Ok(receipt_req) + } + + pub(crate) async fn set_value_unsigned( + &self, + contract_address: H160, + set_arg: u32, + ) -> PendingTransaction<'_, Http> { + // Tx without gas_limit should estimate and include it in send_transaction endpoint + // Tx without nonce should fetch and include it in send_transaction endpoint + let req = Eip1559TransactionRequest::new() + .from(self.from_addr) + .to(contract_address) + .chain_id(self.chain_id) + .data(self.contract.set_call_data(set_arg)) + .max_priority_fee_per_gas(10u64) + .max_fee_per_gas(MAX_FEE_PER_GAS); + + let typed_transaction = TypedTransaction::Eip1559(req); + + self.eth_send_transaction(typed_transaction).await + } + + pub(crate) async fn set_value( + &self, + contract_address: H160, + set_arg: u32, + ) -> PendingTransaction<'_, Http> { + let nonce = self.eth_get_transaction_count(self.from_addr).await; + + let req = Eip1559TransactionRequest::new() + .from(self.from_addr) + .to(contract_address) + .chain_id(self.chain_id) + .nonce(nonce) + .data(self.contract.set_call_data(set_arg)) + .max_priority_fee_per_gas(10u64) + .max_fee_per_gas(MAX_FEE_PER_GAS) + .gas(900000u64); + + let typed_transaction = TypedTransaction::Eip1559(req); + + self.client + .send_transaction(typed_transaction, None) + .await + .unwrap() + } + + pub(crate) async fn set_value_call( + &self, + contract_address: H160, + set_arg: u32, + ) -> Result> { + let nonce = self.eth_get_transaction_count(self.from_addr).await; + + // Any type of transaction can be used for eth_call + let req = TransactionRequest::new() + .from(self.from_addr) + .to(contract_address) + .chain_id(self.chain_id) + .nonce(nonce) + .data(self.contract.set_call_data(set_arg)) + .gas_price(10u64); + + let typed_transaction = TypedTransaction::Legacy(req.clone()); + + // Estimate gas on rpc + let gas = self + .eth_estimate_gas(typed_transaction, Some("latest".to_owned())) + .await; + + // Call with the estimated gas + let req = req.gas(gas); + let typed_transaction = TypedTransaction::Legacy(req); + + let response = self + .eth_call(typed_transaction, Some("latest".to_owned())) + .await?; + + Ok(response) + } + + pub(crate) async fn failing_call( + &self, + contract_address: H160, + ) -> Result> { + let nonce = self.eth_get_transaction_count(self.from_addr).await; + + // Any type of transaction can be used for eth_call + let req = Eip1559TransactionRequest::new() + .from(self.from_addr) + .to(contract_address) + .chain_id(self.chain_id) + .nonce(nonce) + .data(self.contract.failing_function_call_data()) + .max_priority_fee_per_gas(10u64) + .max_fee_per_gas(MAX_FEE_PER_GAS) + .gas(900000u64); + + let typed_transaction = TypedTransaction::Eip1559(req); + + self.eth_call(typed_transaction, Some("latest".to_owned())) + .await + } + + pub(crate) async fn query_contract( + &self, + contract_address: H160, + ) -> Result> { + let nonce = self.eth_get_transaction_count(self.from_addr).await; + + let req = Eip1559TransactionRequest::new() + .from(self.from_addr) + .to(contract_address) + .chain_id(self.chain_id) + .nonce(nonce) + .data(self.contract.get_call_data()) + .gas(900000u64); + + let typed_transaction = TypedTransaction::Eip1559(req); + + let response = self.client.call(&typed_transaction, None).await?; + + let resp_array: [u8; 32] = response.to_vec().try_into().unwrap(); + Ok(ethereum_types::U256::from(resp_array)) + } + + pub(crate) async fn eth_accounts(&self) -> Vec
{ + self.http_client + .request("eth_accounts", rpc_params![]) + .await + .unwrap() + } + + pub(crate) async fn eth_send_transaction( + &self, + tx: TypedTransaction, + ) -> PendingTransaction<'_, Http> { + self.client + .provider() + .send_transaction(tx, None) + .await + .unwrap() + } + + pub(crate) async fn eth_chain_id(&self) -> u64 { + let chain_id: ethereum_types::U64 = self + .http_client + .request("eth_chainId", rpc_params![]) + .await + .unwrap(); + + chain_id.as_u64() + } + + pub(crate) async fn eth_get_balance(&self, address: Address) -> ethereum_types::U256 { + self.http_client + .request("eth_getBalance", rpc_params![address, "latest"]) + .await + .unwrap() + } + + pub(crate) async fn eth_get_storage_at( + &self, + address: Address, + index: ethereum_types::U256, + ) -> ethereum_types::U256 { + self.http_client + .request("eth_getStorageAt", rpc_params![address, index, "latest"]) + .await + .unwrap() + } + + pub(crate) async fn eth_get_code(&self, address: Address) -> Bytes { + self.http_client + .request("eth_getCode", rpc_params![address, "latest"]) + .await + .unwrap() + } + + pub(crate) async fn eth_get_transaction_count(&self, address: Address) -> u64 { + let count: ethereum_types::U64 = self + .http_client + .request("eth_getTransactionCount", rpc_params![address, "latest"]) + .await + .unwrap(); + + count.as_u64() + } + + pub(crate) async fn eth_get_block_by_number( + &self, + block_number: Option, + ) -> Block { + self.http_client + .request("eth_getBlockByNumber", rpc_params![block_number, false]) + .await + .unwrap() + } + + pub(crate) async fn eth_get_block_by_number_with_detail( + &self, + block_number: Option, + ) -> Block { + self.http_client + .request("eth_getBlockByNumber", rpc_params![block_number, true]) + .await + .unwrap() + } + + pub(crate) async fn eth_call( + &self, + tx: TypedTransaction, + block_number: Option, + ) -> Result> { + self.http_client + .request("eth_call", rpc_params![tx, block_number]) + .await + .map_err(|e| e.into()) + } + + pub(crate) async fn eth_estimate_gas( + &self, + tx: TypedTransaction, + block_number: Option, + ) -> u64 { + let gas: ethereum_types::U64 = self + .http_client + .request("eth_estimateGas", rpc_params![tx, block_number]) + .await + .unwrap(); + + gas.as_u64() + } + + pub(crate) async fn execute(&self) -> Result<(), Box> { + // Nonce should be 0 in genesis + let nonce = self.eth_get_transaction_count(self.from_addr).await; + assert_eq!(0, nonce); + + // Balance should be > 0 in genesis + let balance = self.eth_get_balance(self.from_addr).await; + assert!(balance > ethereum_types::U256::zero()); + + let (contract_address, runtime_code) = { + let runtime_code = self.deploy_contract_call().await?; + + let deploy_contract_req = self.deploy_contract().await?; + self.send_publish_batch_request().await; + + let contract_address = deploy_contract_req + .await? + .unwrap() + .contract_address + .unwrap(); + + (contract_address, runtime_code) + }; + + // Assert contract deployed correctly + let code = self.eth_get_code(contract_address).await; + // code has natural following 0x00 bytes, so we need to trim it + assert_eq!(code.to_vec()[..runtime_code.len()], runtime_code.to_vec()); + + // Nonce should be 1 after the deploy + let nonce = self.eth_get_transaction_count(self.from_addr).await; + assert_eq!(1, nonce); + + // Check that the first block has published + // It should have a single transaction, deploying the contract + let first_block = self.eth_get_block_by_number(Some("1".to_owned())).await; + assert_eq!(first_block.number.unwrap().as_u64(), 1); + assert_eq!(first_block.transactions.len(), 1); + + let set_arg = 923; + let tx_hash = { + let set_value_req = self.set_value(contract_address, set_arg).await; + self.send_publish_batch_request().await; + set_value_req.await.unwrap().unwrap().transaction_hash + }; + + let get_arg = self.query_contract(contract_address).await?; + assert_eq!(set_arg, get_arg.as_u32()); + + // Assert storage slot is set + let storage_slot = 0x0; + let storage_value = self + .eth_get_storage_at(contract_address, storage_slot.into()) + .await; + assert_eq!(storage_value, ethereum_types::U256::from(set_arg)); + + // Check that the second block has published + // None should return the latest block + // It should have a single transaction, setting the value + let latest_block = self.eth_get_block_by_number_with_detail(None).await; + assert_eq!(latest_block.number.unwrap().as_u64(), 2); + assert_eq!(latest_block.transactions.len(), 1); + assert_eq!(latest_block.transactions[0].hash, tx_hash); + + // This should just pass without error + self.set_value_call(contract_address, set_arg) + .await + .unwrap(); + + // This call should fail because function does not exist + let failing_call = self.failing_call(contract_address).await; + assert!(failing_call.is_err()); + + // Create a blob with multiple transactions. + let mut requests = Vec::default(); + for value in 100..103 { + let set_value_req = self.set_value(contract_address, value).await; + requests.push(set_value_req); + } + + self.send_publish_batch_request().await; + + // second block + self.send_publish_batch_request().await; + + let first_block = self.eth_get_block_by_number(Some("0".to_owned())).await; + let second_block = self.eth_get_block_by_number(Some("1".to_owned())).await; + + println!("first_block: {:?}", first_block); + println!("second_block: {:?}", second_block); + + // assert parent hash + assert_eq!( + first_block.hash.unwrap(), + second_block.parent_hash, + "Parent hash should be the hash of the previous block" + ); + + for req in requests { + req.await.unwrap(); + } + + { + let get_arg = self.query_contract(contract_address).await?; + assert_eq!(102, get_arg.as_u32()); + } + + { + let value = 103; + + let tx_hash = { + let set_value_req = self.set_value_unsigned(contract_address, value).await; + self.send_publish_batch_request().await; + set_value_req.await.unwrap().unwrap().transaction_hash + }; + + let latest_block = self.eth_get_block_by_number(None).await; + assert_eq!(latest_block.transactions.len(), 1); + assert_eq!(latest_block.transactions[0], tx_hash); + + let get_arg = self.query_contract(contract_address).await?; + assert_eq!(value, get_arg.as_u32()); + } + + Ok(()) + } +} From fb95ffa06044349df896cf12ae1065278dbb9670 Mon Sep 17 00:00:00 2001 From: bkolad Date: Sat, 7 Oct 2023 15:51:23 +0200 Subject: [PATCH 10/13] refactor integration tests --- examples/demo-rollup/tests/evm/mod.rs | 159 ++++++++++++++++-- examples/demo-rollup/tests/evm/test_client.rs | 133 +-------------- 2 files changed, 146 insertions(+), 146 deletions(-) diff --git a/examples/demo-rollup/tests/evm/mod.rs b/examples/demo-rollup/tests/evm/mod.rs index 1f93df517..abd7532c4 100644 --- a/examples/demo-rollup/tests/evm/mod.rs +++ b/examples/demo-rollup/tests/evm/mod.rs @@ -1,14 +1,15 @@ +mod test_client; + use std::net::SocketAddr; use std::str::FromStr; -use super::test_helpers::start_rollup; use demo_stf::genesis_config::GenesisPaths; use ethers_core::abi::Address; use ethers_signers::{LocalWallet, Signer}; use sov_evm::SimpleStorageContract; use sov_risc0_adapter::host::Risc0Host; -mod test_client; +use super::test_helpers::start_rollup; use test_client::TestClient; const TEST_GENESIS_PATHS: GenesisPaths<&str> = GenesisPaths { @@ -22,6 +23,23 @@ const TEST_GENESIS_PATHS: GenesisPaths<&str> = GenesisPaths { evm_genesis_path: "../test-data/genesis/integration-tests/evm.json", }; +#[cfg(feature = "experimental")] +#[tokio::test] +async fn evm_tx_tests() -> Result<(), anyhow::Error> { + let (port_tx, port_rx) = tokio::sync::oneshot::channel(); + + let rollup_task = tokio::spawn(async { + // Don't provide a prover since the EVM is not currently provable + start_rollup::, _>(port_tx, None, &TEST_GENESIS_PATHS).await; + }); + + // Wait for rollup task to start: + let port = port_rx.await.unwrap(); + send_tx_test_to_eth(port).await.unwrap(); + rollup_task.abort(); + Ok(()) +} + async fn send_tx_test_to_eth(rpc_address: SocketAddr) -> Result<(), Box> { let chain_id: u64 = 1; let key = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" @@ -52,22 +70,133 @@ async fn send_tx_test_to_eth(rpc_address: SocketAddr) -> Result<(), Box Result<(), anyhow::Error> { - let (port_tx, port_rx) = tokio::sync::oneshot::channel(); +async fn execute(client: &TestClient) -> Result<(), Box> { + // Nonce should be 0 in genesis + let nonce = client.eth_get_transaction_count(client.from_addr).await; + assert_eq!(0, nonce); - let rollup_task = tokio::spawn(async { - // Don't provide a prover since the EVM is not currently provable - start_rollup::, _>(port_tx, None, &TEST_GENESIS_PATHS).await; - }); + // Balance should be > 0 in genesis + let balance = client.eth_get_balance(client.from_addr).await; + assert!(balance > ethereum_types::U256::zero()); + + let (contract_address, runtime_code) = { + let runtime_code = client.deploy_contract_call().await?; + + let deploy_contract_req = client.deploy_contract().await?; + client.send_publish_batch_request().await; + + let contract_address = deploy_contract_req + .await? + .unwrap() + .contract_address + .unwrap(); + + (contract_address, runtime_code) + }; + + // Assert contract deployed correctly + let code = client.eth_get_code(contract_address).await; + // code has natural following 0x00 bytes, so we need to trim it + assert_eq!(code.to_vec()[..runtime_code.len()], runtime_code.to_vec()); + + // Nonce should be 1 after the deploy + let nonce = client.eth_get_transaction_count(client.from_addr).await; + assert_eq!(1, nonce); + + // Check that the first block has published + // It should have a single transaction, deploying the contract + let first_block = client.eth_get_block_by_number(Some("1".to_owned())).await; + assert_eq!(first_block.number.unwrap().as_u64(), 1); + assert_eq!(first_block.transactions.len(), 1); + + let set_arg = 923; + let tx_hash = { + let set_value_req = client.set_value(contract_address, set_arg).await; + client.send_publish_batch_request().await; + set_value_req.await.unwrap().unwrap().transaction_hash + }; + + let get_arg = client.query_contract(contract_address).await?; + assert_eq!(set_arg, get_arg.as_u32()); + + // Assert storage slot is set + let storage_slot = 0x0; + let storage_value = client + .eth_get_storage_at(contract_address, storage_slot.into()) + .await; + assert_eq!(storage_value, ethereum_types::U256::from(set_arg)); + + // Check that the second block has published + // None should return the latest block + // It should have a single transaction, setting the value + let latest_block = client.eth_get_block_by_number_with_detail(None).await; + assert_eq!(latest_block.number.unwrap().as_u64(), 2); + assert_eq!(latest_block.transactions.len(), 1); + assert_eq!(latest_block.transactions[0].hash, tx_hash); + + // This should just pass without error + client + .set_value_call(contract_address, set_arg) + .await + .unwrap(); + + // This call should fail because function does not exist + let failing_call = client.failing_call(contract_address).await; + assert!(failing_call.is_err()); + + // Create a blob with multiple transactions. + let mut requests = Vec::default(); + for value in 100..103 { + let set_value_req = client.set_value(contract_address, value).await; + requests.push(set_value_req); + } + + client.send_publish_batch_request().await; + + // second block + client.send_publish_batch_request().await; + + let first_block = client.eth_get_block_by_number(Some("0".to_owned())).await; + let second_block = client.eth_get_block_by_number(Some("1".to_owned())).await; + + println!("first_block: {:?}", first_block); + println!("second_block: {:?}", second_block); + + // assert parent hash + assert_eq!( + first_block.hash.unwrap(), + second_block.parent_hash, + "Parent hash should be the hash of the previous block" + ); + + for req in requests { + req.await.unwrap(); + } + + { + let get_arg = client.query_contract(contract_address).await?; + assert_eq!(102, get_arg.as_u32()); + } + + { + let value = 103; + + let tx_hash = { + let set_value_req = client.set_value_unsigned(contract_address, value).await; + client.send_publish_batch_request().await; + set_value_req.await.unwrap().unwrap().transaction_hash + }; + + let latest_block = client.eth_get_block_by_number(None).await; + assert_eq!(latest_block.transactions.len(), 1); + assert_eq!(latest_block.transactions[0], tx_hash); + + let get_arg = client.query_contract(contract_address).await?; + assert_eq!(value, get_arg.as_u32()); + } - // Wait for rollup task to start: - let port = port_rx.await.unwrap(); - send_tx_test_to_eth(port).await.unwrap(); - rollup_task.abort(); Ok(()) } diff --git a/examples/demo-rollup/tests/evm/test_client.rs b/examples/demo-rollup/tests/evm/test_client.rs index 7fb4c3858..deefc3d78 100644 --- a/examples/demo-rollup/tests/evm/test_client.rs +++ b/examples/demo-rollup/tests/evm/test_client.rs @@ -1,5 +1,3 @@ -use std::net::SocketAddr; - use ethereum_types::H160; use ethers_core::abi::Address; use ethers_core::k256::ecdsa::SigningKey; @@ -9,7 +7,7 @@ use ethers_core::types::{ }; use ethers_middleware::SignerMiddleware; use ethers_providers::{Http, Middleware, PendingTransaction, Provider}; -use ethers_signers::{Signer, Wallet}; +use ethers_signers::Wallet; use jsonrpsee::core::client::ClientT; use jsonrpsee::http_client::{HttpClient, HttpClientBuilder}; use jsonrpsee::rpc_params; @@ -20,7 +18,7 @@ const MAX_FEE_PER_GAS: u64 = 100000001; pub(crate) struct TestClient { chain_id: u64, - from_addr: Address, + pub(crate) from_addr: Address, contract: SimpleStorageContract, client: SignerMiddleware, Wallet>, http_client: HttpClient, @@ -331,131 +329,4 @@ impl TestClient { gas.as_u64() } - - pub(crate) async fn execute(&self) -> Result<(), Box> { - // Nonce should be 0 in genesis - let nonce = self.eth_get_transaction_count(self.from_addr).await; - assert_eq!(0, nonce); - - // Balance should be > 0 in genesis - let balance = self.eth_get_balance(self.from_addr).await; - assert!(balance > ethereum_types::U256::zero()); - - let (contract_address, runtime_code) = { - let runtime_code = self.deploy_contract_call().await?; - - let deploy_contract_req = self.deploy_contract().await?; - self.send_publish_batch_request().await; - - let contract_address = deploy_contract_req - .await? - .unwrap() - .contract_address - .unwrap(); - - (contract_address, runtime_code) - }; - - // Assert contract deployed correctly - let code = self.eth_get_code(contract_address).await; - // code has natural following 0x00 bytes, so we need to trim it - assert_eq!(code.to_vec()[..runtime_code.len()], runtime_code.to_vec()); - - // Nonce should be 1 after the deploy - let nonce = self.eth_get_transaction_count(self.from_addr).await; - assert_eq!(1, nonce); - - // Check that the first block has published - // It should have a single transaction, deploying the contract - let first_block = self.eth_get_block_by_number(Some("1".to_owned())).await; - assert_eq!(first_block.number.unwrap().as_u64(), 1); - assert_eq!(first_block.transactions.len(), 1); - - let set_arg = 923; - let tx_hash = { - let set_value_req = self.set_value(contract_address, set_arg).await; - self.send_publish_batch_request().await; - set_value_req.await.unwrap().unwrap().transaction_hash - }; - - let get_arg = self.query_contract(contract_address).await?; - assert_eq!(set_arg, get_arg.as_u32()); - - // Assert storage slot is set - let storage_slot = 0x0; - let storage_value = self - .eth_get_storage_at(contract_address, storage_slot.into()) - .await; - assert_eq!(storage_value, ethereum_types::U256::from(set_arg)); - - // Check that the second block has published - // None should return the latest block - // It should have a single transaction, setting the value - let latest_block = self.eth_get_block_by_number_with_detail(None).await; - assert_eq!(latest_block.number.unwrap().as_u64(), 2); - assert_eq!(latest_block.transactions.len(), 1); - assert_eq!(latest_block.transactions[0].hash, tx_hash); - - // This should just pass without error - self.set_value_call(contract_address, set_arg) - .await - .unwrap(); - - // This call should fail because function does not exist - let failing_call = self.failing_call(contract_address).await; - assert!(failing_call.is_err()); - - // Create a blob with multiple transactions. - let mut requests = Vec::default(); - for value in 100..103 { - let set_value_req = self.set_value(contract_address, value).await; - requests.push(set_value_req); - } - - self.send_publish_batch_request().await; - - // second block - self.send_publish_batch_request().await; - - let first_block = self.eth_get_block_by_number(Some("0".to_owned())).await; - let second_block = self.eth_get_block_by_number(Some("1".to_owned())).await; - - println!("first_block: {:?}", first_block); - println!("second_block: {:?}", second_block); - - // assert parent hash - assert_eq!( - first_block.hash.unwrap(), - second_block.parent_hash, - "Parent hash should be the hash of the previous block" - ); - - for req in requests { - req.await.unwrap(); - } - - { - let get_arg = self.query_contract(contract_address).await?; - assert_eq!(102, get_arg.as_u32()); - } - - { - let value = 103; - - let tx_hash = { - let set_value_req = self.set_value_unsigned(contract_address, value).await; - self.send_publish_batch_request().await; - set_value_req.await.unwrap().unwrap().transaction_hash - }; - - let latest_block = self.eth_get_block_by_number(None).await; - assert_eq!(latest_block.transactions.len(), 1); - assert_eq!(latest_block.transactions[0], tx_hash); - - let get_arg = self.query_contract(contract_address).await?; - assert_eq!(value, get_arg.as_u32()); - } - - Ok(()) - } } From 2112b0e469541b4ad9d19fd31c75f5700d02acb2 Mon Sep 17 00:00:00 2001 From: bkolad Date: Sat, 7 Oct 2023 16:00:32 +0200 Subject: [PATCH 11/13] extract GAS --- examples/demo-rollup/tests/evm/test_client.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/demo-rollup/tests/evm/test_client.rs b/examples/demo-rollup/tests/evm/test_client.rs index deefc3d78..8a7154b49 100644 --- a/examples/demo-rollup/tests/evm/test_client.rs +++ b/examples/demo-rollup/tests/evm/test_client.rs @@ -15,6 +15,7 @@ use reth_primitives::Bytes; use sov_evm::SimpleStorageContract; const MAX_FEE_PER_GAS: u64 = 100000001; +const GAS: u64 = 900000u64; pub(crate) struct TestClient { chain_id: u64, @@ -68,7 +69,7 @@ impl TestClient { .nonce(0u64) .max_priority_fee_per_gas(10u64) .max_fee_per_gas(MAX_FEE_PER_GAS) - .gas(900000u64) + .gas(GAS) .data(self.contract.byte_code()); let typed_transaction = TypedTransaction::Eip1559(req); @@ -88,7 +89,7 @@ impl TestClient { .nonce(0u64) .max_priority_fee_per_gas(10u64) .max_fee_per_gas(MAX_FEE_PER_GAS) - .gas(900000u64) + .gas(GAS) .data(self.contract.byte_code()); let typed_transaction = TypedTransaction::Eip1559(req); @@ -133,7 +134,7 @@ impl TestClient { .data(self.contract.set_call_data(set_arg)) .max_priority_fee_per_gas(10u64) .max_fee_per_gas(MAX_FEE_PER_GAS) - .gas(900000u64); + .gas(GAS); let typed_transaction = TypedTransaction::Eip1559(req); @@ -192,7 +193,7 @@ impl TestClient { .data(self.contract.failing_function_call_data()) .max_priority_fee_per_gas(10u64) .max_fee_per_gas(MAX_FEE_PER_GAS) - .gas(900000u64); + .gas(GAS); let typed_transaction = TypedTransaction::Eip1559(req); @@ -212,7 +213,7 @@ impl TestClient { .chain_id(self.chain_id) .nonce(nonce) .data(self.contract.get_call_data()) - .gas(900000u64); + .gas(GAS); let typed_transaction = TypedTransaction::Eip1559(req); From 36b5a4fa5f7c4e5d6eac411e019c385ed18e3d9c Mon Sep 17 00:00:00 2001 From: bkolad Date: Sat, 7 Oct 2023 16:03:03 +0200 Subject: [PATCH 12/13] fix lint --- examples/demo-rollup/tests/evm/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/demo-rollup/tests/evm/mod.rs b/examples/demo-rollup/tests/evm/mod.rs index abd7532c4..0caf0cfc7 100644 --- a/examples/demo-rollup/tests/evm/mod.rs +++ b/examples/demo-rollup/tests/evm/mod.rs @@ -8,9 +8,9 @@ use ethers_core::abi::Address; use ethers_signers::{LocalWallet, Signer}; use sov_evm::SimpleStorageContract; use sov_risc0_adapter::host::Risc0Host; +use test_client::TestClient; use super::test_helpers::start_rollup; -use test_client::TestClient; const TEST_GENESIS_PATHS: GenesisPaths<&str> = GenesisPaths { bank_genesis_path: "../test-data/genesis/integration-tests/bank.json", From 99639f356ed992cf3f9b1f62c0ef061a953b645c Mon Sep 17 00:00:00 2001 From: bkolad Date: Sat, 7 Oct 2023 16:11:14 +0200 Subject: [PATCH 13/13] Remove printlns --- examples/demo-rollup/tests/evm/mod.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/examples/demo-rollup/tests/evm/mod.rs b/examples/demo-rollup/tests/evm/mod.rs index 0caf0cfc7..88762a2a1 100644 --- a/examples/demo-rollup/tests/evm/mod.rs +++ b/examples/demo-rollup/tests/evm/mod.rs @@ -162,9 +162,6 @@ async fn execute(client: &TestClient) -> Result<(), Box> let first_block = client.eth_get_block_by_number(Some("0".to_owned())).await; let second_block = client.eth_get_block_by_number(Some("1".to_owned())).await; - println!("first_block: {:?}", first_block); - println!("second_block: {:?}", second_block); - // assert parent hash assert_eq!( first_block.hash.unwrap(),