From 2ff4e140c37d96804525ae1dd0ffec9a3a1814b4 Mon Sep 17 00:00:00 2001 From: orkunkilic Date: Fri, 15 Sep 2023 11:52:23 +0300 Subject: [PATCH 01/11] implement getBlockByNumber query --- .../sov-evm/src/query.rs | 108 ++++++++++++++---- 1 file changed, 84 insertions(+), 24 deletions(-) diff --git a/module-system/module-implementations/sov-evm/src/query.rs b/module-system/module-implementations/sov-evm/src/query.rs index cef2f2fa1..da80f7a57 100644 --- a/module-system/module-implementations/sov-evm/src/query.rs +++ b/module-system/module-implementations/sov-evm/src/query.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use ethereum_types::U64; use jsonrpsee::core::RpcResult; use reth_primitives::contract::create_address; @@ -9,7 +11,7 @@ use tracing::info; use crate::call::get_cfg_env; use crate::evm::db::EvmDb; -use crate::evm::primitive_types::{Receipt, SealedBlock, TransactionSignedAndRecovered}; +use crate::evm::primitive_types::{Receipt, SealedBlock, TransactionSignedAndRecovered, Block}; use crate::evm::{executor, prepare_call_env}; use crate::Evm; @@ -29,38 +31,96 @@ impl Evm { #[rpc_method(name = "getBlockByNumber")] pub fn get_block_by_number( &self, - _block_number: Option, - _details: Option, - _working_set: &mut WorkingSet, + block_number: Option, + details: Option, + working_set: &mut WorkingSet, ) -> RpcResult> { info!("evm module: eth_getBlockByNumber"); - let header = reth_rpc_types::Header { - hash: Default::default(), - parent_hash: Default::default(), - uncles_hash: Default::default(), - miner: Default::default(), - state_root: Default::default(), - transactions_root: Default::default(), - receipts_root: Default::default(), - logs_bloom: Default::default(), - difficulty: Default::default(), - number: Default::default(), - gas_limit: Default::default(), - gas_used: Default::default(), - timestamp: Default::default(), - extra_data: Default::default(), - mix_hash: Default::default(), - nonce: Default::default(), - base_fee_per_gas: Some(reth_primitives::U256::from(100)), - withdrawals_root: Default::default(), + // "safe" and "finalized" are not implemented + let block = match block_number { + Some(ref block_number) if block_number == "earliest" => { + self + .blocks + .get(0, &mut working_set.accessory_state()) + .expect("Genesis block must be set") + }, + Some(ref block_number) if block_number == "latest" => { + self + .head + .get(working_set) + .expect("Head block must be set") + .seal() + }, + Some(ref block_number) if block_number == "pending" => { + self + .pending_head + .get(&mut working_set.accessory_state()) + .expect("Pending head block must be set") + .seal() + }, + Some(ref block_number) => { + let block_number = usize::from_str_radix(block_number, 16).unwrap(); + self + .blocks + .get(block_number, &mut working_set.accessory_state()) + .expect("Block must be set") + }, + None => { + self + .head + .get(working_set) + .expect("Head block must be set") + .seal() + }, + }; + + let (header, transactions) = { + let header = reth_rpc_types::Header::from_primitive_with_hash( + block.header.clone(), + ); + + let transaction_hashes = self.transactions + .iter(&mut working_set.accessory_state()) + .map(|tx| tx.signed_transaction.hash) + .collect::>(); + + let tx_numbers = transaction_hashes + .iter() + .map(|hash| ( + hash, + self.transaction_hashes.get(hash, &mut working_set.accessory_state()).unwrap() + )) + .collect::>(); + + let transactions = match details { + Some(true) => reth_rpc_types::BlockTransactions::Full( + self.transactions + .iter(&mut working_set.accessory_state()) + .map(|tx| { + let tx_number = tx_numbers.get(&tx.signed_transaction.hash).unwrap(); + + reth_rpc_types::Transaction::from_recovered_with_block_context( + tx.into(), + block.header.hash, + block.header.number, + block.header.base_fee_per_gas, + U256::from(tx_number - block.transactions.start), + ) + }) + .collect::>() + ), + _ => reth_rpc_types::BlockTransactions::Hashes(transaction_hashes), + }; + + (header, transactions) }; let block = reth_rpc_types::Block { header, total_difficulty: Default::default(), uncles: Default::default(), - transactions: reth_rpc_types::BlockTransactions::Hashes(Default::default()), + transactions, size: Default::default(), withdrawals: Default::default(), }; From 016a5d9b0285661ab74e225f6d8610b0f4ee0dff Mon Sep 17 00:00:00 2001 From: orkunkilic Date: Fri, 15 Sep 2023 11:55:29 +0300 Subject: [PATCH 02/11] remove todo on get-block-by-number --- module-system/module-implementations/sov-evm/src/query.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/module-system/module-implementations/sov-evm/src/query.rs b/module-system/module-implementations/sov-evm/src/query.rs index da80f7a57..55652c4b4 100644 --- a/module-system/module-implementations/sov-evm/src/query.rs +++ b/module-system/module-implementations/sov-evm/src/query.rs @@ -27,7 +27,6 @@ impl Evm { Ok(Some(reth_primitives::U64::from(1u64))) } - // TODO https://github.com/Sovereign-Labs/sovereign-sdk/issues/502 #[rpc_method(name = "getBlockByNumber")] pub fn get_block_by_number( &self, From 6234f3b220337691d6ed490c8fb1d37e101f538a Mon Sep 17 00:00:00 2001 From: orkunkilic Date: Fri, 15 Sep 2023 12:02:29 +0300 Subject: [PATCH 03/11] lint: get-block-by-number --- .../sov-evm/src/query.rs | 74 +++++++++---------- 1 file changed, 34 insertions(+), 40 deletions(-) diff --git a/module-system/module-implementations/sov-evm/src/query.rs b/module-system/module-implementations/sov-evm/src/query.rs index 55652c4b4..8bc245990 100644 --- a/module-system/module-implementations/sov-evm/src/query.rs +++ b/module-system/module-implementations/sov-evm/src/query.rs @@ -11,7 +11,7 @@ use tracing::info; use crate::call::get_cfg_env; use crate::evm::db::EvmDb; -use crate::evm::primitive_types::{Receipt, SealedBlock, TransactionSignedAndRecovered, Block}; +use crate::evm::primitive_types::{Receipt, SealedBlock, TransactionSignedAndRecovered}; use crate::evm::{executor, prepare_call_env}; use crate::Evm; @@ -38,58 +38,52 @@ impl Evm { // "safe" and "finalized" are not implemented let block = match block_number { - Some(ref block_number) if block_number == "earliest" => { - self - .blocks - .get(0, &mut working_set.accessory_state()) - .expect("Genesis block must be set") - }, - Some(ref block_number) if block_number == "latest" => { - self - .head - .get(working_set) - .expect("Head block must be set") - .seal() - }, - Some(ref block_number) if block_number == "pending" => { - self - .pending_head - .get(&mut working_set.accessory_state()) - .expect("Pending head block must be set") - .seal() - }, + Some(ref block_number) if block_number == "earliest" => self + .blocks + .get(0, &mut working_set.accessory_state()) + .expect("Genesis block must be set"), + Some(ref block_number) if block_number == "latest" => self + .head + .get(working_set) + .expect("Head block must be set") + .seal(), + Some(ref block_number) if block_number == "pending" => self + .pending_head + .get(&mut working_set.accessory_state()) + .expect("Pending head block must be set") + .seal(), Some(ref block_number) => { let block_number = usize::from_str_radix(block_number, 16).unwrap(); - self - .blocks + self.blocks .get(block_number, &mut working_set.accessory_state()) .expect("Block must be set") - }, - None => { - self - .head - .get(working_set) - .expect("Head block must be set") - .seal() - }, + } + None => self + .head + .get(working_set) + .expect("Head block must be set") + .seal(), }; let (header, transactions) = { - let header = reth_rpc_types::Header::from_primitive_with_hash( - block.header.clone(), - ); + let header = reth_rpc_types::Header::from_primitive_with_hash(block.header.clone()); - let transaction_hashes = self.transactions + let transaction_hashes = self + .transactions .iter(&mut working_set.accessory_state()) .map(|tx| tx.signed_transaction.hash) .collect::>(); let tx_numbers = transaction_hashes .iter() - .map(|hash| ( - hash, - self.transaction_hashes.get(hash, &mut working_set.accessory_state()).unwrap() - )) + .map(|hash| { + ( + hash, + self.transaction_hashes + .get(hash, &mut working_set.accessory_state()) + .unwrap(), + ) + }) .collect::>(); let transactions = match details { @@ -107,7 +101,7 @@ impl Evm { U256::from(tx_number - block.transactions.start), ) }) - .collect::>() + .collect::>(), ), _ => reth_rpc_types::BlockTransactions::Hashes(transaction_hashes), }; From 31aa26206508be2ebb7d58eea59112896507cb65 Mon Sep 17 00:00:00 2001 From: orkunkilic Date: Fri, 15 Sep 2023 12:49:38 +0300 Subject: [PATCH 04/11] fix: unnecessary block db loads --- .../sov-evm/src/query.rs | 62 +++++++++---------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/module-system/module-implementations/sov-evm/src/query.rs b/module-system/module-implementations/sov-evm/src/query.rs index 8bc245990..f8f15d939 100644 --- a/module-system/module-implementations/sov-evm/src/query.rs +++ b/module-system/module-implementations/sov-evm/src/query.rs @@ -43,67 +43,61 @@ impl Evm { .get(0, &mut working_set.accessory_state()) .expect("Genesis block must be set"), Some(ref block_number) if block_number == "latest" => self - .head - .get(working_set) - .expect("Head block must be set") - .seal(), + .blocks + .last(&mut working_set.accessory_state()) + .expect("Head block must be set"), Some(ref block_number) if block_number == "pending" => self .pending_head .get(&mut working_set.accessory_state()) .expect("Pending head block must be set") .seal(), Some(ref block_number) => { - let block_number = usize::from_str_radix(block_number, 16).unwrap(); + let block_number = usize::from_str_radix(block_number, 16).expect("Block number must be hex"); self.blocks .get(block_number, &mut working_set.accessory_state()) .expect("Block must be set") } None => self - .head - .get(working_set) - .expect("Head block must be set") - .seal(), + .blocks + .last(&mut working_set.accessory_state()) + .expect("Head block must be set"), }; let (header, transactions) = { let header = reth_rpc_types::Header::from_primitive_with_hash(block.header.clone()); - - let transaction_hashes = self - .transactions - .iter(&mut working_set.accessory_state()) - .map(|tx| tx.signed_transaction.hash) - .collect::>(); - - let tx_numbers = transaction_hashes - .iter() - .map(|hash| { - ( - hash, - self.transaction_hashes - .get(hash, &mut working_set.accessory_state()) - .unwrap(), - ) + + let transactions_with_id = block.transactions + .clone() + .map(|id| { + let tx = self.transactions + .get(id as usize, &mut working_set.accessory_state()) + .expect("Transaction must be set"); + (id, tx) }) - .collect::>(); + .collect::>(); + let transactions = match details { Some(true) => reth_rpc_types::BlockTransactions::Full( - self.transactions - .iter(&mut working_set.accessory_state()) - .map(|tx| { - let tx_number = tx_numbers.get(&tx.signed_transaction.hash).unwrap(); - + transactions_with_id + .iter() + .map(|(id, tx)| { reth_rpc_types::Transaction::from_recovered_with_block_context( - tx.into(), + tx.clone().into(), block.header.hash, block.header.number, block.header.base_fee_per_gas, - U256::from(tx_number - block.transactions.start), + U256::from(id - block.transactions.start), ) }) .collect::>(), ), - _ => reth_rpc_types::BlockTransactions::Hashes(transaction_hashes), + _ => reth_rpc_types::BlockTransactions::Hashes({ + transactions_with_id + .iter() + .map(|(_, tx)| tx.signed_transaction.hash) + .collect::>() + }), }; (header, transactions) From 3350352c280ae89b0e221d8e0699f4bed65069c9 Mon Sep 17 00:00:00 2001 From: orkunkilic Date: Fri, 15 Sep 2023 12:57:11 +0300 Subject: [PATCH 05/11] Extract helper for block by number --- .../sov-evm/src/query.rs | 126 ++++++++++-------- 1 file changed, 68 insertions(+), 58 deletions(-) diff --git a/module-system/module-implementations/sov-evm/src/query.rs b/module-system/module-implementations/sov-evm/src/query.rs index f8f15d939..851c4378f 100644 --- a/module-system/module-implementations/sov-evm/src/query.rs +++ b/module-system/module-implementations/sov-evm/src/query.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; + use ethereum_types::U64; use jsonrpsee::core::RpcResult; @@ -17,27 +17,13 @@ use crate::Evm; #[rpc_gen(client, server, namespace = "eth")] impl Evm { - // TODO https://github.com/Sovereign-Labs/sovereign-sdk/issues/502 - #[rpc_method(name = "chainId")] - pub fn chain_id( - &self, - _working_set: &mut WorkingSet, - ) -> RpcResult> { - info!("evm module: eth_chainId"); - Ok(Some(reth_primitives::U64::from(1u64))) - } - - #[rpc_method(name = "getBlockByNumber")] - pub fn get_block_by_number( + fn get_sealed_block_by_number( &self, block_number: Option, - details: Option, working_set: &mut WorkingSet, - ) -> RpcResult> { - info!("evm module: eth_getBlockByNumber"); - + ) -> SealedBlock { // "safe" and "finalized" are not implemented - let block = match block_number { + match block_number { Some(ref block_number) if block_number == "earliest" => self .blocks .get(0, &mut working_set.accessory_state()) @@ -52,7 +38,8 @@ impl Evm { .expect("Pending head block must be set") .seal(), Some(ref block_number) => { - let block_number = usize::from_str_radix(block_number, 16).expect("Block number must be hex"); + let block_number = + usize::from_str_radix(block_number, 16).expect("Block number must be hex"); self.blocks .get(block_number, &mut working_set.accessory_state()) .expect("Block must be set") @@ -61,48 +48,71 @@ impl Evm { .blocks .last(&mut working_set.accessory_state()) .expect("Head block must be set"), - }; + } + } - let (header, transactions) = { - let header = reth_rpc_types::Header::from_primitive_with_hash(block.header.clone()); - - let transactions_with_id = block.transactions - .clone() - .map(|id| { - let tx = self.transactions - .get(id as usize, &mut working_set.accessory_state()) - .expect("Transaction must be set"); - (id, tx) - }) - .collect::>(); - - - let transactions = match details { - Some(true) => reth_rpc_types::BlockTransactions::Full( - transactions_with_id - .iter() - .map(|(id, tx)| { - reth_rpc_types::Transaction::from_recovered_with_block_context( - tx.clone().into(), - block.header.hash, - block.header.number, - block.header.base_fee_per_gas, - U256::from(id - block.transactions.start), - ) - }) - .collect::>(), - ), - _ => reth_rpc_types::BlockTransactions::Hashes({ - transactions_with_id - .iter() - .map(|(_, tx)| tx.signed_transaction.hash) - .collect::>() - }), - }; - - (header, transactions) + // TODO https://github.com/Sovereign-Labs/sovereign-sdk/issues/502 + #[rpc_method(name = "chainId")] + pub fn chain_id( + &self, + _working_set: &mut WorkingSet, + ) -> RpcResult> { + info!("evm module: eth_chainId"); + Ok(Some(reth_primitives::U64::from(1u64))) + } + + #[rpc_method(name = "getBlockByNumber")] + pub fn get_block_by_number( + &self, + block_number: Option, + details: Option, + working_set: &mut WorkingSet, + ) -> RpcResult> { + info!("evm module: eth_getBlockByNumber"); + + let block = self.get_sealed_block_by_number(block_number, working_set); + + // Build rpc header response + let header = reth_rpc_types::Header::from_primitive_with_hash(block.header.clone()); + + // Collect transactions with ids from db + let transactions_with_ids = block + .transactions + .clone() + .map(|id| { + let tx = self + .transactions + .get(id as usize, &mut working_set.accessory_state()) + .expect("Transaction must be set"); + (id, tx) + }) + .collect::>(); + + // Build rpc transactions response + let transactions = match details { + Some(true) => reth_rpc_types::BlockTransactions::Full( + transactions_with_ids + .iter() + .map(|(id, tx)| { + reth_rpc_types::Transaction::from_recovered_with_block_context( + tx.clone().into(), + block.header.hash, + block.header.number, + block.header.base_fee_per_gas, + U256::from(id - block.transactions.start), + ) + }) + .collect::>(), + ), + _ => reth_rpc_types::BlockTransactions::Hashes({ + transactions_with_ids + .iter() + .map(|(_, tx)| tx.signed_transaction.hash) + .collect::>() + }), }; + // Build rpc block response let block = reth_rpc_types::Block { header, total_difficulty: Default::default(), From caa439461eb1d8968264bf7e81424645808fc09e Mon Sep 17 00:00:00 2001 From: orkunkilic Date: Fri, 15 Sep 2023 12:58:26 +0300 Subject: [PATCH 06/11] lint: get block by number --- module-system/module-implementations/sov-evm/src/query.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/module-system/module-implementations/sov-evm/src/query.rs b/module-system/module-implementations/sov-evm/src/query.rs index 851c4378f..d08ef2e63 100644 --- a/module-system/module-implementations/sov-evm/src/query.rs +++ b/module-system/module-implementations/sov-evm/src/query.rs @@ -1,5 +1,3 @@ - - use ethereum_types::U64; use jsonrpsee::core::RpcResult; use reth_primitives::contract::create_address; From 680563e4ebe574d82c5622755fc50906dad78da2 Mon Sep 17 00:00:00 2001 From: orkunkilic Date: Fri, 15 Sep 2023 11:52:23 +0300 Subject: [PATCH 07/11] implement getBlockByNumber query --- module-system/module-implementations/sov-evm/src/query.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/module-system/module-implementations/sov-evm/src/query.rs b/module-system/module-implementations/sov-evm/src/query.rs index 3c18aa707..9a7926e32 100644 --- a/module-system/module-implementations/sov-evm/src/query.rs +++ b/module-system/module-implementations/sov-evm/src/query.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use ethereum_types::U64; use jsonrpsee::core::RpcResult; use reth_primitives::contract::create_address; @@ -9,7 +11,7 @@ use tracing::info; use crate::call::get_cfg_env; use crate::evm::db::EvmDb; -use crate::evm::primitive_types::{Receipt, SealedBlock, TransactionSignedAndRecovered}; +use crate::evm::primitive_types::{Receipt, SealedBlock, TransactionSignedAndRecovered, Block}; use crate::evm::{executor, prepare_call_env}; use crate::Evm; From 7e9225c7ff5b94eecc108bbe7f60a80eacb8d26d Mon Sep 17 00:00:00 2001 From: orkunkilic Date: Fri, 15 Sep 2023 12:57:11 +0300 Subject: [PATCH 08/11] Extract helper for block by number --- .../module-implementations/sov-evm/src/query.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/module-system/module-implementations/sov-evm/src/query.rs b/module-system/module-implementations/sov-evm/src/query.rs index 9a7926e32..6a2736e06 100644 --- a/module-system/module-implementations/sov-evm/src/query.rs +++ b/module-system/module-implementations/sov-evm/src/query.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; + use ethereum_types::U64; use jsonrpsee::core::RpcResult; @@ -20,9 +20,9 @@ impl Evm { fn get_sealed_block_by_number( &self, block_number: Option, - working_set: &mut WorkingSet, + working_set: &mut WorkingSet, ) -> SealedBlock { - // "safe" and "finalized" are not implemented + // safe, finalized, and pending are not supported match block_number { Some(ref block_number) if block_number == "earliest" => self .blocks @@ -32,11 +32,6 @@ impl Evm { .blocks .last(&mut working_set.accessory_state()) .expect("Head block must be set"), - Some(ref block_number) if block_number == "pending" => self - .pending_head - .get(&mut working_set.accessory_state()) - .expect("Pending head block must be set") - .seal(), Some(ref block_number) => { let block_number = usize::from_str_radix(block_number, 16).expect("Block number must be hex"); From 1369c49fe5ab9761db09d28fddbf5621f61fd898 Mon Sep 17 00:00:00 2001 From: orkunkilic Date: Tue, 19 Sep 2023 11:20:03 +0300 Subject: [PATCH 09/11] fix storage context --- module-system/module-implementations/sov-evm/src/query.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module-system/module-implementations/sov-evm/src/query.rs b/module-system/module-implementations/sov-evm/src/query.rs index 6a2736e06..36a8f7e0c 100644 --- a/module-system/module-implementations/sov-evm/src/query.rs +++ b/module-system/module-implementations/sov-evm/src/query.rs @@ -68,7 +68,7 @@ impl Evm { &self, block_number: Option, details: Option, - working_set: &mut WorkingSet, + working_set: &mut WorkingSet, ) -> RpcResult> { info!("evm module: eth_getBlockByNumber"); From ed461c7659b78b2533f17eeaab2f9127350c1424 Mon Sep 17 00:00:00 2001 From: orkunkilic Date: Tue, 19 Sep 2023 11:21:02 +0300 Subject: [PATCH 10/11] lint: get block by number --- module-system/module-implementations/sov-evm/src/query.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/module-system/module-implementations/sov-evm/src/query.rs b/module-system/module-implementations/sov-evm/src/query.rs index 36a8f7e0c..8199f10eb 100644 --- a/module-system/module-implementations/sov-evm/src/query.rs +++ b/module-system/module-implementations/sov-evm/src/query.rs @@ -1,5 +1,3 @@ - - use ethereum_types::U64; use jsonrpsee::core::RpcResult; use reth_primitives::contract::create_address; @@ -11,7 +9,7 @@ use tracing::info; use crate::call::get_cfg_env; use crate::evm::db::EvmDb; -use crate::evm::primitive_types::{Receipt, SealedBlock, TransactionSignedAndRecovered, Block}; +use crate::evm::primitive_types::{Receipt, SealedBlock, TransactionSignedAndRecovered}; use crate::evm::{executor, prepare_call_env}; use crate::Evm; @@ -45,7 +43,7 @@ impl Evm { .expect("Head block must be set"), } } - + #[rpc_method(name = "chainId")] pub fn chain_id( &self, From 020b0c205a6d3a74bedb800089c2bb1104c88f05 Mon Sep 17 00:00:00 2001 From: orkunkilic Date: Tue, 19 Sep 2023 14:40:09 +0300 Subject: [PATCH 11/11] test: get block by number --- examples/demo-rollup/tests/evm/mod.rs | 50 ++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/examples/demo-rollup/tests/evm/mod.rs b/examples/demo-rollup/tests/evm/mod.rs index 952174e7a..cdbcd1111 100644 --- a/examples/demo-rollup/tests/evm/mod.rs +++ b/examples/demo-rollup/tests/evm/mod.rs @@ -5,7 +5,7 @@ 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::Eip1559TransactionRequest; +use ethers_core::types::{Block, Eip1559TransactionRequest, Transaction, TxHash}; use ethers_middleware::SignerMiddleware; use ethers_providers::{Http, Middleware, PendingTransaction, Provider}; use ethers_signers::{LocalWallet, Signer, Wallet}; @@ -146,6 +146,23 @@ impl TestClient { chain_id.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 execute(self) -> Result<(), Box> { let contract_address = { let deploy_contract_req = self.deploy_contract().await?; @@ -158,18 +175,32 @@ impl TestClient { .unwrap() }; + // 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, 1).await; self.send_publish_batch_request().await; - set_value_req.await.unwrap(); - } + set_value_req.await.unwrap().unwrap().transaction_hash + }; { let get_arg = self.query_contract(contract_address, 2).await?; assert_eq!(set_arg, get_arg.as_u32()); } + // 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); + // Create a blob with multiple transactions. let mut requests = Vec::default(); let mut nonce = 2; @@ -213,6 +244,17 @@ async fn send_tx_test_to_eth(rpc_address: SocketAddr) -> Result<(), Box