From 95c651aa994acce775a2f95d10ddce47cfcc9009 Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 12 Jul 2024 12:21:50 -0300 Subject: [PATCH 01/36] Impl RLPDecode for BlockHeader --- crates/core/src/types/block.rs | 59 +++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/crates/core/src/types/block.rs b/crates/core/src/types/block.rs index f040c7e590..425191d064 100644 --- a/crates/core/src/types/block.rs +++ b/crates/core/src/types/block.rs @@ -3,7 +3,11 @@ use super::{ GAS_LIMIT_MINIMUM, }; use crate::{ - rlp::{encode::RLPEncode, structs::Encoder}, + rlp::{ + decode::RLPDecode, + encode::RLPEncode, + structs::{Decoder, Encoder}, + }, types::Receipt, Address, H256, U256, }; @@ -78,6 +82,59 @@ impl RLPEncode for BlockHeader { } } +impl RLPDecode for BlockHeader { + fn decode_unfinished(rlp: &[u8]) -> Result<(Self, &[u8]), crate::rlp::error::RLPDecodeError> { + let decoder = Decoder::new(rlp)?; + let (parent_hash, decoder) = decoder.decode_field("parent_hash")?; + let (ommers_hash, decoder) = decoder.decode_field("parent_hash")?; + let (coinbase, decoder) = decoder.decode_field("coinbase")?; + let (state_root, decoder) = decoder.decode_field("state_root")?; + let (transactions_root, decoder) = decoder.decode_field("transactions_root")?; + let (receipt_root, decoder) = decoder.decode_field("receipt_root")?; + let (logs_bloom, decoder) = decoder.decode_field("logs_bloom")?; + let (difficulty, decoder) = decoder.decode_field("difficulty")?; + let (number, decoder) = decoder.decode_field("number")?; + let (gas_limit, decoder) = decoder.decode_field("gas_limit")?; + let (gas_used, decoder) = decoder.decode_field("gas_used")?; + let (timestamp, decoder) = decoder.decode_field("timestamp")?; + let (extra_data, decoder) = decoder.decode_field("extra_data")?; + let (prev_randao, decoder) = decoder.decode_field("prev_randao")?; + let (nonce, decoder) = decoder.decode_field("nonce")?; + let nonce = u64::from_be_bytes(nonce); + let (base_fee_per_gas, decoder) = decoder.decode_field("base_fee_per_gas")?; + let (withdrawals_root, decoder) = decoder.decode_field("withdrawals_root")?; + let (blob_gas_used, decoder) = decoder.decode_field("blob_gas_used")?; + let (excess_blob_gas, decoder) = decoder.decode_field("excess_blob_gas")?; + let (parent_beacon_block_root, decoder) = + decoder.decode_field("parent_beacon_block_root")?; + Ok(( + BlockHeader { + parent_hash, + ommers_hash, + coinbase, + state_root, + transactions_root, + receipt_root, + logs_bloom, + difficulty, + number, + gas_limit, + gas_used, + timestamp, + extra_data, + prev_randao, + nonce, + base_fee_per_gas, + withdrawals_root, + blob_gas_used, + excess_blob_gas, + parent_beacon_block_root, + }, + decoder.finish()?, + )) + } +} + // The body of a block on the chain #[derive(Clone, Debug, PartialEq, Eq)] pub struct BlockBody { From 1e2a66c3ba4d73223f3b6584430d847faec7f680 Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 12 Jul 2024 12:35:53 -0300 Subject: [PATCH 02/36] Extend Store api to fetch blocks + start implementing Decode for Transaction --- crates/core/src/types/block.rs | 13 ++++++++++++- crates/core/src/types/transaction.rs | 7 +------ crates/storage/src/lib.rs | 24 +++++++++++++++++++++++- crates/storage/src/libmdbx.rs | 15 +++++++++++++++ 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/crates/core/src/types/block.rs b/crates/core/src/types/block.rs index 425191d064..0e38ff6bce 100644 --- a/crates/core/src/types/block.rs +++ b/crates/core/src/types/block.rs @@ -86,7 +86,7 @@ impl RLPDecode for BlockHeader { fn decode_unfinished(rlp: &[u8]) -> Result<(Self, &[u8]), crate::rlp::error::RLPDecodeError> { let decoder = Decoder::new(rlp)?; let (parent_hash, decoder) = decoder.decode_field("parent_hash")?; - let (ommers_hash, decoder) = decoder.decode_field("parent_hash")?; + let (ommers_hash, decoder) = decoder.decode_field("ommers_hash")?; let (coinbase, decoder) = decoder.decode_field("coinbase")?; let (state_root, decoder) = decoder.decode_field("state_root")?; let (transactions_root, decoder) = decoder.decode_field("transactions_root")?; @@ -228,6 +228,17 @@ impl RLPEncode for BlockBody { } } +impl RLPDecode for BlockBody { + fn decode_unfinished(rlp: &[u8]) -> Result<(Self, &[u8]), crate::rlp::error::RLPDecodeError> { + let decoder = Decoder::new(rlp)?; + let (transactions, decoder) = decoder.decode_field("transactions")?; + let (ommers, decoder) = decoder.decode_field("ommers")?; + let (withdrawals, decoder) = decoder.decode_field("withdrawals")?; + Ok((BlockBody { transactions, ommers, withdrawals }, decoder.finish()?)) + } + +} + impl BlockHeader { pub fn compute_block_hash(&self) -> H256 { let mut buf = vec![]; diff --git a/crates/core/src/types/transaction.rs b/crates/core/src/types/transaction.rs index 9549629774..2eacdc2930 100644 --- a/crates/core/src/types/transaction.rs +++ b/crates/core/src/types/transaction.rs @@ -116,12 +116,7 @@ impl Transaction { impl RLPEncode for Transaction { fn encode(&self, buf: &mut dyn bytes::BufMut) { - match self { - Transaction::LegacyTransaction(t) => t.encode(buf), - Transaction::EIP2930Transaction(t) => t.encode(buf), - Transaction::EIP1559Transaction(t) => t.encode(buf), - Transaction::EIP4844Transaction(t) => t.encode(buf), - }; + self.encode_with_type(buf) } } diff --git a/crates/storage/src/lib.rs b/crates/storage/src/lib.rs index 2c8f24c9ef..f34d808029 100644 --- a/crates/storage/src/lib.rs +++ b/crates/storage/src/lib.rs @@ -13,7 +13,7 @@ use self::libmdbx::Store as LibmdbxStore; use self::rocksdb::Store as RocksDbStore; #[cfg(feature = "sled")] use self::sled::Store as SledStore; -use ethereum_rust_core::types::AccountInfo; +use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHeader}; use ethereum_types::Address; use std::fmt::Debug; use std::sync::{Arc, Mutex}; @@ -44,6 +44,12 @@ pub trait StoreEngine: Debug + Send { /// Obtain account info fn get_account_info(&self, address: Address) -> Result, StoreError>; + // Obtain block header + fn get_block_header(&self, block_number: u64) -> Result, StoreError>; + + // Obtain block body + fn get_block_body(&self, block_number: u64) -> Result, StoreError>; + /// Set an arbitrary value (used for eventual persistent values: eg. current_block_height) fn set_value(&mut self, key: Key, value: Value) -> Result<(), StoreError>; @@ -110,6 +116,22 @@ impl Store { .unwrap() .get_account_info(address) } + + pub fn get_block_header(&self, block_number: u64) -> Result, StoreError> { + self.engine + .clone() + .lock() + .unwrap() + .get_block_header(block_number) + } + + pub fn get_block_body(&self, block_number: u64) -> Result, StoreError> { + self.engine + .clone() + .lock() + .unwrap() + .get_block_body(block_number) + } } #[cfg(test)] diff --git a/crates/storage/src/libmdbx.rs b/crates/storage/src/libmdbx.rs index 23a5fcb260..1edb9f1b8e 100644 --- a/crates/storage/src/libmdbx.rs +++ b/crates/storage/src/libmdbx.rs @@ -57,6 +57,21 @@ impl StoreEngine for Store { } } + fn get_block_body( + &self, + block_number: u64, + ) -> std::result::Result, StoreError> { + // Read block body from mdbx + let read_value = { + let txn = self.db.begin_read().unwrap(); + txn.get::(block_number.into()) + }; + match read_value { + Ok(value) => Ok(value.map(|a| a.to())), + Err(err) => Err(StoreError::LibmdbxError(err)), + } + } + fn set_value(&mut self, _key: Key, _value: Value) -> Result<(), StoreError> { todo!() } From ac5f04e6623dd7adc530512763fb1cfd27cc737d Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 12 Jul 2024 12:52:13 -0300 Subject: [PATCH 03/36] Encode and Decode transactions with type --- crates/core/src/types/block.rs | 12 +++-- crates/core/src/types/engine/payload.rs | 33 +------------ crates/core/src/types/transaction.rs | 65 ++++++++++++++++++++----- 3 files changed, 63 insertions(+), 47 deletions(-) diff --git a/crates/core/src/types/block.rs b/crates/core/src/types/block.rs index 0e38ff6bce..1feb9ff7b6 100644 --- a/crates/core/src/types/block.rs +++ b/crates/core/src/types/block.rs @@ -166,7 +166,7 @@ impl BlockBody { // Value: tx_type || RLP(tx) if tx_type != 0 // RLP(tx) else let mut v = Vec::new(); - tx.encode_with_type(&mut v); + tx.encode(&mut v); (k, v) }) @@ -234,9 +234,15 @@ impl RLPDecode for BlockBody { let (transactions, decoder) = decoder.decode_field("transactions")?; let (ommers, decoder) = decoder.decode_field("ommers")?; let (withdrawals, decoder) = decoder.decode_field("withdrawals")?; - Ok((BlockBody { transactions, ommers, withdrawals }, decoder.finish()?)) + Ok(( + BlockBody { + transactions, + ommers, + withdrawals, + }, + decoder.finish()?, + )) } - } impl BlockHeader { diff --git a/crates/core/src/types/engine/payload.rs b/crates/core/src/types/engine/payload.rs index 3123035dfc..3addd4dda0 100644 --- a/crates/core/src/types/engine/payload.rs +++ b/crates/core/src/types/engine/payload.rs @@ -7,8 +7,7 @@ use crate::rlp::decode::RLPDecode; use crate::{rlp::error::RLPDecodeError, serde_utils}; use crate::types::{ - compute_withdrawals_root, BlockBody, BlockHeader, EIP1559Transaction, EIP2930Transaction, - EIP4844Transaction, LegacyTransaction, Transaction, Withdrawal, DEFAULT_OMMERS_HASH, + compute_withdrawals_root, BlockBody, BlockHeader, Transaction, Withdrawal, DEFAULT_OMMERS_HASH, }; #[allow(unused)] @@ -64,35 +63,7 @@ impl EncodedTransaction { /// A) `TransactionType || Transaction` (Where Transaction type is an 8-bit number between 0 and 0x7f, and Transaction is an rlp encoded transaction of type TransactionType) /// B) `LegacyTransaction` (An rlp encoded LegacyTransaction) fn decode(&self) -> Result { - // Look at the first byte to check if it corresponds to a TransactionType - match self.0.first() { - // First byte is a valid TransactionType - Some(tx_type) if *tx_type < 0x7f => { - // Decode tx based on type - let tx_bytes = &self.0.as_ref()[1..]; - match *tx_type { - // Legacy - 0x0 => LegacyTransaction::decode(tx_bytes).map(Transaction::LegacyTransaction), // TODO: check if this is a real case scenario - // EIP2930 - 0x1 => { - EIP2930Transaction::decode(tx_bytes).map(Transaction::EIP2930Transaction) - } - // EIP1559 - 0x2 => { - EIP1559Transaction::decode(tx_bytes).map(Transaction::EIP1559Transaction) - } - // EIP4844 - 0x3 => { - EIP4844Transaction::decode(tx_bytes).map(Transaction::EIP4844Transaction) - } - ty => Err(RLPDecodeError::Custom(format!( - "Invalid transaction type: {ty}" - ))), - } - } - // LegacyTransaction - _ => LegacyTransaction::decode(self.0.as_ref()).map(Transaction::LegacyTransaction), - } + Transaction::decode(self.0.as_ref()) } } diff --git a/crates/core/src/types/transaction.rs b/crates/core/src/types/transaction.rs index 2eacdc2930..2c07556431 100644 --- a/crates/core/src/types/transaction.rs +++ b/crates/core/src/types/transaction.rs @@ -92,18 +92,6 @@ pub enum TxType { } impl Transaction { - pub fn encode_with_type(&self, buf: &mut dyn bytes::BufMut) { - // tx_type || RLP(tx) if tx_type != 0 - // RLP(tx) else - match self { - // Legacy transactions don't have a prefix - Transaction::LegacyTransaction(_) => {} - _ => buf.put_u8(self.tx_type() as u8), - } - - self.encode(buf); - } - pub fn tx_type(&self) -> TxType { match self { Transaction::LegacyTransaction(_) => TxType::Legacy, @@ -115,8 +103,59 @@ impl Transaction { } impl RLPEncode for Transaction { + /// Based on [EIP-2718] + /// Transactions can be encoded in the following formats: + /// A) `TransactionType || Transaction` (Where Transaction type is an 8-bit number between 0 and 0x7f, and Transaction is an rlp encoded transaction of type TransactionType) + /// B) `LegacyTransaction` (An rlp encoded LegacyTransaction) fn encode(&self, buf: &mut dyn bytes::BufMut) { - self.encode_with_type(buf) + match self { + // Legacy transactions don't have a prefix + Transaction::LegacyTransaction(_) => {} + _ => buf.put_u8(self.tx_type() as u8), + } + match self { + Transaction::LegacyTransaction(t) => t.encode(buf), + Transaction::EIP2930Transaction(t) => t.encode(buf), + Transaction::EIP1559Transaction(t) => t.encode(buf), + Transaction::EIP4844Transaction(t) => t.encode(buf), + }; + } +} + +impl RLPDecode for Transaction { + /// Based on [EIP-2718] + /// Transactions can be encoded in the following formats: + /// A) `TransactionType || Transaction` (Where Transaction type is an 8-bit number between 0 and 0x7f, and Transaction is an rlp encoded transaction of type TransactionType) + /// B) `LegacyTransaction` (An rlp encoded LegacyTransaction) + fn decode_unfinished(rlp: &[u8]) -> Result<(Self, &[u8]), RLPDecodeError> { + // Look at the first byte to check if it corresponds to a TransactionType + match rlp.first() { + // First byte is a valid TransactionType + Some(tx_type) if *tx_type < 0x7f => { + // Decode tx based on type + let tx_bytes = &rlp.as_ref()[1..]; + match *tx_type { + // Legacy + 0x0 => LegacyTransaction::decode_unfinished(tx_bytes) + .map(|(tx, rem)| (Transaction::LegacyTransaction(tx), rem)), // TODO: check if this is a real case scenario + // EIP2930 + 0x1 => EIP2930Transaction::decode_unfinished(tx_bytes) + .map(|(tx, rem)| (Transaction::EIP2930Transaction(tx), rem)), + // EIP1559 + 0x2 => EIP1559Transaction::decode_unfinished(tx_bytes) + .map(|(tx, rem)| (Transaction::EIP1559Transaction(tx), rem)), + // EIP4844 + 0x3 => EIP4844Transaction::decode_unfinished(tx_bytes) + .map(|(tx, rem)| (Transaction::EIP4844Transaction(tx), rem)), + ty => Err(RLPDecodeError::Custom(format!( + "Invalid transaction type: {ty}" + ))), + } + } + // LegacyTransaction + _ => LegacyTransaction::decode_unfinished(rlp) + .map(|(tx, rem)| (Transaction::LegacyTransaction(tx), rem)), + } } } From d397b343f8640d47c7ce5734bb702a9cf1f39efb Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 12 Jul 2024 12:56:06 -0300 Subject: [PATCH 04/36] Impl RLPDecode for Withdrawal --- crates/core/src/types/block.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/crates/core/src/types/block.rs b/crates/core/src/types/block.rs index 1feb9ff7b6..6f4b2b06a5 100644 --- a/crates/core/src/types/block.rs +++ b/crates/core/src/types/block.rs @@ -275,6 +275,25 @@ impl RLPEncode for Withdrawal { } } +impl RLPDecode for Withdrawal { + fn decode_unfinished(rlp: &[u8]) -> Result<(Self, &[u8]), crate::rlp::error::RLPDecodeError> { + let decoder = Decoder::new(rlp)?; + let (index, decoder) = decoder.decode_field("index")?; + let (validator_index, decoder) = decoder.decode_field("validator_index")?; + let (address, decoder) = decoder.decode_field("address")?; + let (amount, decoder) = decoder.decode_field("amount")?; + Ok(( + Withdrawal { + index, + validator_index, + address, + amount, + }, + decoder.finish()?, + )) + } +} + // Checks that the gas_limit fits the gas bounds set by its parent block fn check_gas_limit(gas_limit: u64, parent_gas_limit: u64) -> bool { let max_adjustment_delta = parent_gas_limit / GAS_LIMIT_ADJUSTMENT_FACTOR; From 6d6a0f85acc36f92a33c3504b8e85b7af24b66eb Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 12 Jul 2024 12:57:53 -0300 Subject: [PATCH 05/36] Complete api for libmdx --- crates/storage/src/libmdbx.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/crates/storage/src/libmdbx.rs b/crates/storage/src/libmdbx.rs index 1edb9f1b8e..19bb40c23a 100644 --- a/crates/storage/src/libmdbx.rs +++ b/crates/storage/src/libmdbx.rs @@ -5,7 +5,7 @@ use crate::rlp::{ AccountStorageValueRLP, AddressRLP, BlockBodyRLP, BlockHeaderRLP, ReceiptRLP, }; use anyhow::Result; -use ethereum_rust_core::types::AccountInfo; +use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHeader}; use ethereum_rust_core::types::{BlockNumber, Index}; use ethereum_types::Address; use libmdbx::{ @@ -57,10 +57,25 @@ impl StoreEngine for Store { } } + fn get_block_header( + &self, + block_number: u64, + ) -> std::result::Result, StoreError> { + // Read block body from mdbx + let read_value = { + let txn = self.db.begin_read().unwrap(); + txn.get::(block_number.into()) + }; + match read_value { + Ok(value) => Ok(value.map(|a| a.to())), + Err(err) => Err(StoreError::LibmdbxError(err)), + } + } + fn get_block_body( &self, block_number: u64, - ) -> std::result::Result, StoreError> { + ) -> std::result::Result, StoreError> { // Read block body from mdbx let read_value = { let txn = self.db.begin_read().unwrap(); From 63f5d18e5f289a6fb8c3b6b442cf63263a1c6091 Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 12 Jul 2024 14:53:38 -0300 Subject: [PATCH 06/36] Implement getters and setters for block in store api --- crates/storage/src/in_memory.rs | 17 +++++++--- crates/storage/src/lib.rs | 59 +++++++++++++++++++++++++++++---- crates/storage/src/libmdbx.rs | 38 +++++++++++++++++++-- 3 files changed, 99 insertions(+), 15 deletions(-) diff --git a/crates/storage/src/in_memory.rs b/crates/storage/src/in_memory.rs index db6b6794fa..28aff1e004 100644 --- a/crates/storage/src/in_memory.rs +++ b/crates/storage/src/in_memory.rs @@ -1,21 +1,20 @@ use super::{Key, StoreEngine, Value}; use crate::error::StoreError; -use ethereum_rust_core::types::AccountInfo; +use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHeader, BlockNumber}; use ethereum_types::Address; use std::{collections::HashMap, fmt::Debug}; #[derive(Default)] pub struct Store { account_infos: HashMap, + bodies: HashMap, + headers: HashMap, values: HashMap, } impl Store { pub fn new() -> Result { - Ok(Self { - account_infos: HashMap::new(), - values: HashMap::new(), - }) + Ok(Self::default()) } } @@ -41,6 +40,14 @@ impl StoreEngine for Store { fn get_value(&self, key: Key) -> Result>, StoreError> { Ok(self.values.get(&key).cloned()) } + + fn get_block_header(&self, block_number: u64) -> Result, StoreError> { + Ok(self.headers.get(&block_number).cloned()) + } + + fn get_block_body(&self, block_number: u64) -> Result, StoreError> { + Ok(self.bodies.get(&block_number).cloned()) + } } impl Debug for Store { diff --git a/crates/storage/src/lib.rs b/crates/storage/src/lib.rs index f34d808029..e89f0ed4fd 100644 --- a/crates/storage/src/lib.rs +++ b/crates/storage/src/lib.rs @@ -13,7 +13,7 @@ use self::libmdbx::Store as LibmdbxStore; use self::rocksdb::Store as RocksDbStore; #[cfg(feature = "sled")] use self::sled::Store as SledStore; -use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHeader}; +use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHeader, BlockNumber}; use ethereum_types::Address; use std::fmt::Debug; use std::sync::{Arc, Mutex}; @@ -44,11 +44,28 @@ pub trait StoreEngine: Debug + Send { /// Obtain account info fn get_account_info(&self, address: Address) -> Result, StoreError>; - // Obtain block header - fn get_block_header(&self, block_number: u64) -> Result, StoreError>; + /// Add block header + fn add_block_header( + &self, + block_number: BlockNumber, + block_header: BlockHeader, + ) -> Result<(), StoreError>; + + /// Obtain block header + fn get_block_header( + &self, + block_number: BlockNumber, + ) -> Result, StoreError>; + + /// Add block body + fn add_block_body( + &self, + block_number: BlockNumber, + block_body: BlockBody, + ) -> Result<(), StoreError>; - // Obtain block body - fn get_block_body(&self, block_number: u64) -> Result, StoreError>; + /// Obtain block body + fn get_block_body(&self, block_number: BlockNumber) -> Result, StoreError>; /// Set an arbitrary value (used for eventual persistent values: eg. current_block_height) fn set_value(&mut self, key: Key, value: Value) -> Result<(), StoreError>; @@ -117,7 +134,10 @@ impl Store { .get_account_info(address) } - pub fn get_block_header(&self, block_number: u64) -> Result, StoreError> { + pub fn add_block_header( + &self, + block_number: BlockNumber, + ) -> Result, StoreError> { self.engine .clone() .lock() @@ -125,7 +145,32 @@ impl Store { .get_block_header(block_number) } - pub fn get_block_body(&self, block_number: u64) -> Result, StoreError> { + pub fn get_block_header( + &self, + block_number: BlockNumber, + ) -> Result, StoreError> { + self.engine + .clone() + .lock() + .unwrap() + .get_block_header(block_number) + } + + pub fn add_block_body( + &self, + block_number: BlockNumber, + ) -> Result, StoreError> { + self.engine + .clone() + .lock() + .unwrap() + .get_block_body(block_number) + } + + pub fn get_block_body( + &self, + block_number: BlockNumber, + ) -> Result, StoreError> { self.engine .clone() .lock() diff --git a/crates/storage/src/libmdbx.rs b/crates/storage/src/libmdbx.rs index 19bb40c23a..ccd664ad75 100644 --- a/crates/storage/src/libmdbx.rs +++ b/crates/storage/src/libmdbx.rs @@ -57,11 +57,27 @@ impl StoreEngine for Store { } } + fn add_block_header( + &self, + block_number: BlockNumber, + block_header: BlockHeader, + ) -> std::result::Result<(), StoreError> { + // Write block header to mdbx + { + let txn = self.db.begin_readwrite().unwrap(); + match txn.upsert::(block_number.into(), block_header.into()) { + Ok(_) => txn.commit().unwrap(), + Err(err) => return Err(StoreError::LibmdbxError(err)), + } + } + Ok(()) + } + fn get_block_header( &self, - block_number: u64, + block_number: BlockNumber, ) -> std::result::Result, StoreError> { - // Read block body from mdbx + // Read block header from mdbx let read_value = { let txn = self.db.begin_read().unwrap(); txn.get::(block_number.into()) @@ -72,9 +88,25 @@ impl StoreEngine for Store { } } + fn add_block_body( + &self, + block_number: BlockNumber, + block_body: BlockBody, + ) -> std::result::Result<(), StoreError> { + // Write block body to mdbx + { + let txn = self.db.begin_readwrite().unwrap(); + match txn.upsert::(block_number.into(), block_body.into()) { + Ok(_) => txn.commit().unwrap(), + Err(err) => return Err(StoreError::LibmdbxError(err)), + } + } + Ok(()) + } + fn get_block_body( &self, - block_number: u64, + block_number: BlockNumber, ) -> std::result::Result, StoreError> { // Read block body from mdbx let read_value = { From da196001d7c3f9a393d531735d4f37825d892dea Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 12 Jul 2024 15:14:07 -0300 Subject: [PATCH 07/36] Fixes + add test --- crates/storage/src/in_memory.rs | 18 +++++++ crates/storage/src/lib.rs | 4 +- crates/storage/src/libmdbx.rs | 86 ++++++++++++++++++++++++++++++++- 3 files changed, 104 insertions(+), 4 deletions(-) diff --git a/crates/storage/src/in_memory.rs b/crates/storage/src/in_memory.rs index 28aff1e004..9668d0851d 100644 --- a/crates/storage/src/in_memory.rs +++ b/crates/storage/src/in_memory.rs @@ -48,6 +48,24 @@ impl StoreEngine for Store { fn get_block_body(&self, block_number: u64) -> Result, StoreError> { Ok(self.bodies.get(&block_number).cloned()) } + + fn add_block_header( + &mut self, + block_number: BlockNumber, + block_header: BlockHeader, + ) -> Result<(), StoreError> { + self.headers.insert(block_number, block_header); + Ok(()) + } + + fn add_block_body( + &mut self, + block_number: BlockNumber, + block_body: BlockBody, + ) -> Result<(), StoreError> { + self.bodies.insert(block_number, block_body); + Ok(()) + } } impl Debug for Store { diff --git a/crates/storage/src/lib.rs b/crates/storage/src/lib.rs index e89f0ed4fd..a03712ae7b 100644 --- a/crates/storage/src/lib.rs +++ b/crates/storage/src/lib.rs @@ -46,7 +46,7 @@ pub trait StoreEngine: Debug + Send { /// Add block header fn add_block_header( - &self, + &mut self, block_number: BlockNumber, block_header: BlockHeader, ) -> Result<(), StoreError>; @@ -59,7 +59,7 @@ pub trait StoreEngine: Debug + Send { /// Add block body fn add_block_body( - &self, + &mut self, block_number: BlockNumber, block_body: BlockBody, ) -> Result<(), StoreError>; diff --git a/crates/storage/src/libmdbx.rs b/crates/storage/src/libmdbx.rs index ccd664ad75..66fb3e8d82 100644 --- a/crates/storage/src/libmdbx.rs +++ b/crates/storage/src/libmdbx.rs @@ -58,7 +58,7 @@ impl StoreEngine for Store { } fn add_block_header( - &self, + &mut self, block_number: BlockNumber, block_header: BlockHeader, ) -> std::result::Result<(), StoreError> { @@ -89,7 +89,7 @@ impl StoreEngine for Store { } fn add_block_body( - &self, + &mut self, block_number: BlockNumber, block_body: BlockBody, ) -> std::result::Result<(), StoreError> { @@ -179,11 +179,23 @@ pub fn init_db(path: Option>) -> Database { #[cfg(test)] mod tests { + use std::str::FromStr; + + use bytes::Bytes; + use ethereum_rust_core::{ + rlp::decode::RLPDecode, + types::{BlockBody, BlockHeader, Bloom, Transaction}, + }; + use ethereum_types::{Address, H256, U256}; use libmdbx::{ orm::{table, Database, Decodable, Encodable}, table_info, }; + use crate::StoreEngine; + + use super::init_db; + #[test] fn mdbx_smoke_test() { // Declare tables used for the smoke test @@ -278,4 +290,74 @@ mod tests { }; assert_eq!(read_value, Some(value)); } + + #[test] + fn store_and_fetch_block() { + // Create block + let block_header = BlockHeader { + parent_hash: H256::from_str( + "0x1ac1bf1eef97dc6b03daba5af3b89881b7ae4bc1600dc434f450a9ec34d44999", + ) + .unwrap(), + ommers_hash: H256::from_str( + "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + ) + .unwrap(), + coinbase: Address::from_str("0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba").unwrap(), + state_root: H256::from_str( + "0x9de6f95cb4ff4ef22a73705d6ba38c4b927c7bca9887ef5d24a734bb863218d9", + ) + .unwrap(), + transactions_root: H256::from_str( + "0x578602b2b7e3a3291c3eefca3a08bc13c0d194f9845a39b6f3bcf843d9fed79d", + ) + .unwrap(), + receipt_root: H256::from_str( + "0x035d56bac3f47246c5eed0e6642ca40dc262f9144b582f058bc23ded72aa72fa", + ) + .unwrap(), + logs_bloom: Bloom::from([0; 256]), + difficulty: U256::zero(), + number: 1, + gas_limit: 0x016345785d8a0000, + gas_used: 0xa8de, + timestamp: 0x03e8, + extra_data: Bytes::new(), + prev_randao: H256::zero(), + nonce: 0x0000000000000000, + base_fee_per_gas: 0x07, + withdrawals_root: H256::from_str( + "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + ) + .unwrap(), + blob_gas_used: 0x00, + excess_blob_gas: 0x00, + parent_beacon_block_root: H256::zero(), + }; + let block_body = BlockBody { + transactions: vec![Transaction::decode(&hex::decode("02f86c8330182480114e82f618946177843db3138ae69679a54b95cf345ed759450d870aa87bee53800080c080a0151ccc02146b9b11adf516e6787b59acae3e76544fdcd75e77e67c6b598ce65da064c5dd5aae2fbb535830ebbdad0234975cd7ece3562013b63ea18cc0df6c97d4").unwrap()).unwrap(), + Transaction::decode(&hex::decode("f86d80843baa0c4082f618946177843db3138ae69679a54b95cf345ed759450d870aa87bee538000808360306ba0151ccc02146b9b11adf516e6787b59acae3e76544fdcd75e77e67c6b598ce65da064c5dd5aae2fbb535830ebbdad0234975cd7ece3562013b63ea18cc0df6c97d4").unwrap()).unwrap()], + ommers: Default::default(), + withdrawals: Default::default(), + }; + + let block_number = 6; + + let mut storage = super::Store { + db: init_db(None::), + }; + + storage + .add_block_body(block_number, block_body.clone()) + .unwrap(); + storage + .add_block_header(block_number, block_header.clone()) + .unwrap(); + + let fetched_body = storage.get_block_body(block_number).unwrap().unwrap(); + let fetched_header = storage.get_block_header(block_number).unwrap().unwrap(); + + assert_eq!(block_body, fetched_body); + assert_eq!(block_header, fetched_header); + } } From 5e5f792cf81cb835b83b134e8b57a1732cbe5526 Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 12 Jul 2024 15:21:23 -0300 Subject: [PATCH 08/36] Clippy --- crates/core/src/types/transaction.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core/src/types/transaction.rs b/crates/core/src/types/transaction.rs index 2c07556431..f6202373d1 100644 --- a/crates/core/src/types/transaction.rs +++ b/crates/core/src/types/transaction.rs @@ -133,7 +133,7 @@ impl RLPDecode for Transaction { // First byte is a valid TransactionType Some(tx_type) if *tx_type < 0x7f => { // Decode tx based on type - let tx_bytes = &rlp.as_ref()[1..]; + let tx_bytes = &rlp[1..]; match *tx_type { // Legacy 0x0 => LegacyTransaction::decode_unfinished(tx_bytes) From 847782d9e215ed8d0c86a129bcb21c6720d6eb45 Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 12 Jul 2024 15:28:08 -0300 Subject: [PATCH 09/36] Add api skeleton for other db impls --- crates/storage/src/libmdbx.rs | 8 ++++---- crates/storage/src/rocksdb.rs | 29 ++++++++++++++++++++++++++++- crates/storage/src/sled.rs | 29 ++++++++++++++++++++++++++++- 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/crates/storage/src/libmdbx.rs b/crates/storage/src/libmdbx.rs index 66fb3e8d82..eef71d8055 100644 --- a/crates/storage/src/libmdbx.rs +++ b/crates/storage/src/libmdbx.rs @@ -65,7 +65,7 @@ impl StoreEngine for Store { // Write block header to mdbx { let txn = self.db.begin_readwrite().unwrap(); - match txn.upsert::(block_number.into(), block_header.into()) { + match txn.upsert::(block_number, block_header.into()) { Ok(_) => txn.commit().unwrap(), Err(err) => return Err(StoreError::LibmdbxError(err)), } @@ -80,7 +80,7 @@ impl StoreEngine for Store { // Read block header from mdbx let read_value = { let txn = self.db.begin_read().unwrap(); - txn.get::(block_number.into()) + txn.get::(block_number) }; match read_value { Ok(value) => Ok(value.map(|a| a.to())), @@ -96,7 +96,7 @@ impl StoreEngine for Store { // Write block body to mdbx { let txn = self.db.begin_readwrite().unwrap(); - match txn.upsert::(block_number.into(), block_body.into()) { + match txn.upsert::(block_number, block_body.into()) { Ok(_) => txn.commit().unwrap(), Err(err) => return Err(StoreError::LibmdbxError(err)), } @@ -111,7 +111,7 @@ impl StoreEngine for Store { // Read block body from mdbx let read_value = { let txn = self.db.begin_read().unwrap(); - txn.get::(block_number.into()) + txn.get::(block_number) }; match read_value { Ok(value) => Ok(value.map(|a| a.to())), diff --git a/crates/storage/src/rocksdb.rs b/crates/storage/src/rocksdb.rs index 25ea1b6afc..1bc8d771ca 100644 --- a/crates/storage/src/rocksdb.rs +++ b/crates/storage/src/rocksdb.rs @@ -1,7 +1,7 @@ use super::{Key, StoreEngine, Value}; use crate::error::StoreError; use crate::rlp::{AccountInfoRLP, AddressRLP}; -use ethereum_rust_core::types::AccountInfo; +use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHeader, BlockNumber}; use ethereum_types::Address; use libmdbx::orm::{Decodable, Encodable}; use std::fmt::Debug; @@ -106,6 +106,33 @@ impl StoreEngine for Store { }) } + fn add_block_header( + &mut self, + _block_number: BlockNumber, + _block_header: BlockHeader, + ) -> Result<(), StoreError> { + todo!() + } + + fn get_block_header( + &self, + _block_number: BlockNumber, + ) -> Result, StoreError> { + todo!() + } + + fn add_block_body( + &mut self, + _block_number: BlockNumber, + _block_body: BlockBody, + ) -> Result<(), StoreError> { + todo!() + } + + fn get_block_body(&self, _block_number: BlockNumber) -> Result, StoreError> { + todo!() + } + fn set_value(&mut self, key: Key, value: Value) -> Result<(), StoreError> { let (reply_sender, reply_receiver) = sync_channel(0); self.command_sender.send(StoreCommand::Put( diff --git a/crates/storage/src/sled.rs b/crates/storage/src/sled.rs index a606b4b52b..5a3b78f2e6 100644 --- a/crates/storage/src/sled.rs +++ b/crates/storage/src/sled.rs @@ -1,7 +1,7 @@ use super::{Key, StoreEngine, Value}; use crate::error::StoreError; use crate::rlp::{AccountInfoRLP, AddressRLP}; -use ethereum_rust_core::types::AccountInfo; +use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHeader, BlockNumber}; use ethereum_types::Address; use libmdbx::orm::{Decodable, Encodable}; use sled::Db; @@ -46,6 +46,33 @@ impl StoreEngine for Store { }) } + fn add_block_header( + &mut self, + _block_number: BlockNumber, + _block_header: BlockHeader, + ) -> Result<(), StoreError> { + todo!() + } + + fn get_block_header( + &self, + _block_number: BlockNumber, + ) -> Result, StoreError> { + todo!() + } + + fn add_block_body( + &mut self, + _block_number: BlockNumber, + _block_body: BlockBody, + ) -> Result<(), StoreError> { + todo!() + } + + fn get_block_body(&self, _block_number: BlockNumber) -> Result, StoreError> { + todo!() + } + fn set_value(&mut self, key: Key, value: Value) -> Result<(), StoreError> { let _ = self.values.insert(key, value); Ok(()) From 9e485c5b4090292efc219d57779a92f75739ac7f Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 12 Jul 2024 16:49:47 -0300 Subject: [PATCH 10/36] Move test to main module + fix api --- crates/storage/src/lib.rs | 91 ++++++++++++++++++++++++++++++++--- crates/storage/src/libmdbx.rs | 82 ------------------------------- 2 files changed, 84 insertions(+), 89 deletions(-) diff --git a/crates/storage/src/lib.rs b/crates/storage/src/lib.rs index a03712ae7b..fe0486836f 100644 --- a/crates/storage/src/lib.rs +++ b/crates/storage/src/lib.rs @@ -137,12 +137,13 @@ impl Store { pub fn add_block_header( &self, block_number: BlockNumber, - ) -> Result, StoreError> { + block_header: BlockHeader, + ) -> Result<(), StoreError> { self.engine .clone() .lock() .unwrap() - .get_block_header(block_number) + .add_block_header(block_number, block_header) } pub fn get_block_header( @@ -159,12 +160,13 @@ impl Store { pub fn add_block_body( &self, block_number: BlockNumber, - ) -> Result, StoreError> { + block_body: BlockBody, + ) -> Result<(), StoreError> { self.engine .clone() .lock() .unwrap() - .get_block_body(block_number) + .add_block_body(block_number, block_body) } pub fn get_block_body( @@ -181,11 +183,14 @@ impl Store { #[cfg(test)] mod tests { - use std::{env, fs}; + use std::{env, fs, str::FromStr}; use bytes::Bytes; - use ethereum_rust_core::types; - use ethereum_types::U256; + use ethereum_rust_core::{ + rlp::decode::RLPDecode, + types::{self, Bloom, Transaction}, + }; + use ethereum_types::{H256, U256}; use super::*; @@ -194,6 +199,7 @@ mod tests { fn test_in_memory_store() { let store = Store::new("test", EngineType::InMemory).unwrap(); test_store_account(store.clone()); + test_store_block(store.clone()); } #[cfg(feature = "libmdbx")] @@ -203,6 +209,7 @@ mod tests { remove_test_dbs("test.mdbx"); let store = Store::new("test.mdbx", EngineType::Libmdbx).unwrap(); test_store_account(store.clone()); + test_store_block(store.clone()); remove_test_dbs("test.mdbx"); } @@ -214,6 +221,7 @@ mod tests { remove_test_dbs("test.sled"); let store = Store::new("test.sled", EngineType::Sled).unwrap(); test_store_account(store.clone()); + // test_store_block(store.clone()); Unimplemented remove_test_dbs("test.sled"); } @@ -225,6 +233,7 @@ mod tests { remove_test_dbs("test.rocksdb"); let store = Store::new("test.rocksdb", EngineType::Sled).unwrap(); test_store_account(store.clone()); + // test_store_block(store.clone()); Unimplemented remove_test_dbs("test.rocksdb"); } @@ -269,4 +278,72 @@ mod tests { } } } + + fn test_store_block(store: Store) { + let (block_header, block_body) = create_block_for_testing(); + let block_number = 6; + + store + .add_block_header(block_number, block_header.clone()) + .unwrap(); + store + .add_block_body(block_number, block_body.clone()) + .unwrap(); + + let stored_header = store.get_block_header(block_number).unwrap().unwrap(); + let stored_body = store.get_block_body(block_number).unwrap().unwrap(); + + assert_eq!(stored_header, block_header); + assert_eq!(stored_body, block_body); + } + + fn create_block_for_testing() -> (BlockHeader, BlockBody) { + let block_header = BlockHeader { + parent_hash: H256::from_str( + "0x1ac1bf1eef97dc6b03daba5af3b89881b7ae4bc1600dc434f450a9ec34d44999", + ) + .unwrap(), + ommers_hash: H256::from_str( + "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + ) + .unwrap(), + coinbase: Address::from_str("0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba").unwrap(), + state_root: H256::from_str( + "0x9de6f95cb4ff4ef22a73705d6ba38c4b927c7bca9887ef5d24a734bb863218d9", + ) + .unwrap(), + transactions_root: H256::from_str( + "0x578602b2b7e3a3291c3eefca3a08bc13c0d194f9845a39b6f3bcf843d9fed79d", + ) + .unwrap(), + receipt_root: H256::from_str( + "0x035d56bac3f47246c5eed0e6642ca40dc262f9144b582f058bc23ded72aa72fa", + ) + .unwrap(), + logs_bloom: Bloom::from([0; 256]), + difficulty: U256::zero(), + number: 1, + gas_limit: 0x016345785d8a0000, + gas_used: 0xa8de, + timestamp: 0x03e8, + extra_data: Bytes::new(), + prev_randao: H256::zero(), + nonce: 0x0000000000000000, + base_fee_per_gas: 0x07, + withdrawals_root: H256::from_str( + "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + ) + .unwrap(), + blob_gas_used: 0x00, + excess_blob_gas: 0x00, + parent_beacon_block_root: H256::zero(), + }; + let block_body = BlockBody { + transactions: vec![Transaction::decode(&hex::decode("02f86c8330182480114e82f618946177843db3138ae69679a54b95cf345ed759450d870aa87bee53800080c080a0151ccc02146b9b11adf516e6787b59acae3e76544fdcd75e77e67c6b598ce65da064c5dd5aae2fbb535830ebbdad0234975cd7ece3562013b63ea18cc0df6c97d4").unwrap()).unwrap(), + Transaction::decode(&hex::decode("f86d80843baa0c4082f618946177843db3138ae69679a54b95cf345ed759450d870aa87bee538000808360306ba0151ccc02146b9b11adf516e6787b59acae3e76544fdcd75e77e67c6b598ce65da064c5dd5aae2fbb535830ebbdad0234975cd7ece3562013b63ea18cc0df6c97d4").unwrap()).unwrap()], + ommers: Default::default(), + withdrawals: Default::default(), + }; + (block_header, block_body) + } } diff --git a/crates/storage/src/libmdbx.rs b/crates/storage/src/libmdbx.rs index eef71d8055..66daa6b61c 100644 --- a/crates/storage/src/libmdbx.rs +++ b/crates/storage/src/libmdbx.rs @@ -179,23 +179,11 @@ pub fn init_db(path: Option>) -> Database { #[cfg(test)] mod tests { - use std::str::FromStr; - - use bytes::Bytes; - use ethereum_rust_core::{ - rlp::decode::RLPDecode, - types::{BlockBody, BlockHeader, Bloom, Transaction}, - }; - use ethereum_types::{Address, H256, U256}; use libmdbx::{ orm::{table, Database, Decodable, Encodable}, table_info, }; - use crate::StoreEngine; - - use super::init_db; - #[test] fn mdbx_smoke_test() { // Declare tables used for the smoke test @@ -290,74 +278,4 @@ mod tests { }; assert_eq!(read_value, Some(value)); } - - #[test] - fn store_and_fetch_block() { - // Create block - let block_header = BlockHeader { - parent_hash: H256::from_str( - "0x1ac1bf1eef97dc6b03daba5af3b89881b7ae4bc1600dc434f450a9ec34d44999", - ) - .unwrap(), - ommers_hash: H256::from_str( - "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - ) - .unwrap(), - coinbase: Address::from_str("0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba").unwrap(), - state_root: H256::from_str( - "0x9de6f95cb4ff4ef22a73705d6ba38c4b927c7bca9887ef5d24a734bb863218d9", - ) - .unwrap(), - transactions_root: H256::from_str( - "0x578602b2b7e3a3291c3eefca3a08bc13c0d194f9845a39b6f3bcf843d9fed79d", - ) - .unwrap(), - receipt_root: H256::from_str( - "0x035d56bac3f47246c5eed0e6642ca40dc262f9144b582f058bc23ded72aa72fa", - ) - .unwrap(), - logs_bloom: Bloom::from([0; 256]), - difficulty: U256::zero(), - number: 1, - gas_limit: 0x016345785d8a0000, - gas_used: 0xa8de, - timestamp: 0x03e8, - extra_data: Bytes::new(), - prev_randao: H256::zero(), - nonce: 0x0000000000000000, - base_fee_per_gas: 0x07, - withdrawals_root: H256::from_str( - "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - ) - .unwrap(), - blob_gas_used: 0x00, - excess_blob_gas: 0x00, - parent_beacon_block_root: H256::zero(), - }; - let block_body = BlockBody { - transactions: vec![Transaction::decode(&hex::decode("02f86c8330182480114e82f618946177843db3138ae69679a54b95cf345ed759450d870aa87bee53800080c080a0151ccc02146b9b11adf516e6787b59acae3e76544fdcd75e77e67c6b598ce65da064c5dd5aae2fbb535830ebbdad0234975cd7ece3562013b63ea18cc0df6c97d4").unwrap()).unwrap(), - Transaction::decode(&hex::decode("f86d80843baa0c4082f618946177843db3138ae69679a54b95cf345ed759450d870aa87bee538000808360306ba0151ccc02146b9b11adf516e6787b59acae3e76544fdcd75e77e67c6b598ce65da064c5dd5aae2fbb535830ebbdad0234975cd7ece3562013b63ea18cc0df6c97d4").unwrap()).unwrap()], - ommers: Default::default(), - withdrawals: Default::default(), - }; - - let block_number = 6; - - let mut storage = super::Store { - db: init_db(None::), - }; - - storage - .add_block_body(block_number, block_body.clone()) - .unwrap(); - storage - .add_block_header(block_number, block_header.clone()) - .unwrap(); - - let fetched_body = storage.get_block_body(block_number).unwrap().unwrap(); - let fetched_header = storage.get_block_header(block_number).unwrap().unwrap(); - - assert_eq!(block_body, fetched_body); - assert_eq!(block_header, fetched_header); - } } From 7e98b8af173a52188a6d71992f46a6d770f229c4 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 15 Jul 2024 17:59:28 -0300 Subject: [PATCH 11/36] Add mapping between block hash & block number to store api --- crates/core/src/types/block.rs | 1 + crates/storage/src/in_memory.rs | 16 ++++++++++++- crates/storage/src/lib.rs | 12 +++++++++- crates/storage/src/libmdbx.rs | 41 +++++++++++++++++++++++++++++++-- crates/storage/src/rlp.rs | 3 ++- crates/storage/src/rocksdb.rs | 14 ++++++++++- crates/storage/src/sled.rs | 14 ++++++++++- 7 files changed, 94 insertions(+), 7 deletions(-) diff --git a/crates/core/src/types/block.rs b/crates/core/src/types/block.rs index 6f4b2b06a5..6b54e7f1a4 100644 --- a/crates/core/src/types/block.rs +++ b/crates/core/src/types/block.rs @@ -22,6 +22,7 @@ use std::cmp::{max, Ordering}; use super::Transaction; pub type BlockNumber = u64; +pub type BlockHash = H256; pub type Bloom = [u8; 256]; use lazy_static::lazy_static; diff --git a/crates/storage/src/in_memory.rs b/crates/storage/src/in_memory.rs index 9668d0851d..2402b39ad2 100644 --- a/crates/storage/src/in_memory.rs +++ b/crates/storage/src/in_memory.rs @@ -1,12 +1,13 @@ use super::{Key, StoreEngine, Value}; use crate::error::StoreError; -use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHeader, BlockNumber}; +use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHash, BlockHeader, BlockNumber}; use ethereum_types::Address; use std::{collections::HashMap, fmt::Debug}; #[derive(Default)] pub struct Store { account_infos: HashMap, + block_numbers: HashMap, bodies: HashMap, headers: HashMap, values: HashMap, @@ -66,6 +67,19 @@ impl StoreEngine for Store { self.bodies.insert(block_number, block_body); Ok(()) } + + fn add_block_number( + &mut self, + block_hash: BlockHash, + block_number: BlockNumber, + ) -> Result<(), StoreError> { + self.block_numbers.insert(block_hash, block_number); + Ok(()) + } + + fn get_block_number(&self, block_hash: BlockHash) -> Result, StoreError> { + Ok(self.block_numbers.get(&block_hash).copied()) + } } impl Debug for Store { diff --git a/crates/storage/src/lib.rs b/crates/storage/src/lib.rs index fe0486836f..c2ee0907a2 100644 --- a/crates/storage/src/lib.rs +++ b/crates/storage/src/lib.rs @@ -13,7 +13,7 @@ use self::libmdbx::Store as LibmdbxStore; use self::rocksdb::Store as RocksDbStore; #[cfg(feature = "sled")] use self::sled::Store as SledStore; -use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHeader, BlockNumber}; +use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHash, BlockHeader, BlockNumber}; use ethereum_types::Address; use std::fmt::Debug; use std::sync::{Arc, Mutex}; @@ -67,6 +67,16 @@ pub trait StoreEngine: Debug + Send { /// Obtain block body fn get_block_body(&self, block_number: BlockNumber) -> Result, StoreError>; + /// Add block body + fn add_block_number( + &mut self, + block_hash: BlockHash, + block_number: BlockNumber, + ) -> Result<(), StoreError>; + + /// Obtain block number + fn get_block_number(&self, block_hash: BlockHash) -> Result, StoreError>; + /// Set an arbitrary value (used for eventual persistent values: eg. current_block_height) fn set_value(&mut self, key: Key, value: Value) -> Result<(), StoreError>; diff --git a/crates/storage/src/libmdbx.rs b/crates/storage/src/libmdbx.rs index 66daa6b61c..0f1283bf6c 100644 --- a/crates/storage/src/libmdbx.rs +++ b/crates/storage/src/libmdbx.rs @@ -2,10 +2,10 @@ use super::{Key, StoreEngine, Value}; use crate::error::StoreError; use crate::rlp::{ AccountCodeHashRLP, AccountCodeRLP, AccountInfoRLP, AccountStorageKeyRLP, - AccountStorageValueRLP, AddressRLP, BlockBodyRLP, BlockHeaderRLP, ReceiptRLP, + AccountStorageValueRLP, AddressRLP, BlockBodyRLP, BlockHashRLP, BlockHeaderRLP, ReceiptRLP, }; use anyhow::Result; -use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHeader}; +use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHash, BlockHeader}; use ethereum_rust_core::types::{BlockNumber, Index}; use ethereum_types::Address; use libmdbx::{ @@ -119,6 +119,37 @@ impl StoreEngine for Store { } } + fn add_block_number( + &mut self, + block_hash: BlockHash, + block_number: BlockNumber, + ) -> std::result::Result<(), StoreError> { + // Write block number to mdbx + { + let txn = self.db.begin_readwrite().unwrap(); + match txn.upsert::(block_hash.into(), block_number.into()) { + Ok(_) => txn.commit().unwrap(), + Err(err) => return Err(StoreError::LibmdbxError(err)), + } + } + Ok(()) + } + + fn get_block_number( + &self, + block_hash: BlockHash, + ) -> std::result::Result, StoreError> { + // Read block number from mdbx + let read_value = { + let txn = self.db.begin_read().unwrap(); + txn.get::(block_hash.into()) + }; + match read_value { + Ok(value) => Ok(value.map(|a| a.into())), + Err(err) => Err(StoreError::LibmdbxError(err)), + } + } + fn set_value(&mut self, _key: Key, _value: Value) -> Result<(), StoreError> { todo!() } @@ -135,6 +166,12 @@ impl Debug for Store { } // Define tables + +table!( + /// Block hash to number table. + ( BlockNumbers ) BlockHashRLP => BlockNumber +); + table!( /// Block headers table. ( Headers ) BlockNumber => BlockHeaderRLP diff --git a/crates/storage/src/rlp.rs b/crates/storage/src/rlp.rs index 6cc9feba2a..01fa8284c7 100644 --- a/crates/storage/src/rlp.rs +++ b/crates/storage/src/rlp.rs @@ -2,7 +2,7 @@ use std::marker::PhantomData; use ethereum_rust_core::{ rlp::{decode::RLPDecode, encode::RLPEncode}, - types::{AccountInfo, BlockBody, BlockHeader, Receipt}, + types::{AccountInfo, BlockBody, BlockHash, BlockHeader, Receipt}, Address, }; use libmdbx::orm::{Decodable, Encodable}; @@ -19,6 +19,7 @@ pub struct AccountStorageKeyRLP(pub [u8; 32]); pub struct AccountStorageValueRLP(pub [u8; 32]); // Block types +pub type BlockHashRLP = Rlp; pub type BlockHeaderRLP = Rlp; pub type BlockBodyRLP = Rlp; diff --git a/crates/storage/src/rocksdb.rs b/crates/storage/src/rocksdb.rs index 1bc8d771ca..e8a0e06024 100644 --- a/crates/storage/src/rocksdb.rs +++ b/crates/storage/src/rocksdb.rs @@ -1,7 +1,7 @@ use super::{Key, StoreEngine, Value}; use crate::error::StoreError; use crate::rlp::{AccountInfoRLP, AddressRLP}; -use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHeader, BlockNumber}; +use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHash, BlockHeader, BlockNumber}; use ethereum_types::Address; use libmdbx::orm::{Decodable, Encodable}; use std::fmt::Debug; @@ -133,6 +133,18 @@ impl StoreEngine for Store { todo!() } + fn add_block_number( + &mut self, + _block_hash: BlockHash, + _block_number: BlockNumber, + ) -> Result<(), StoreError> { + todo!() + } + + fn get_block_number(&self, _block_hash: BlockHash) -> Result, StoreError> { + todo!() + } + fn set_value(&mut self, key: Key, value: Value) -> Result<(), StoreError> { let (reply_sender, reply_receiver) = sync_channel(0); self.command_sender.send(StoreCommand::Put( diff --git a/crates/storage/src/sled.rs b/crates/storage/src/sled.rs index 5a3b78f2e6..0334a267df 100644 --- a/crates/storage/src/sled.rs +++ b/crates/storage/src/sled.rs @@ -1,7 +1,7 @@ use super::{Key, StoreEngine, Value}; use crate::error::StoreError; use crate::rlp::{AccountInfoRLP, AddressRLP}; -use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHeader, BlockNumber}; +use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHash, BlockHeader, BlockNumber}; use ethereum_types::Address; use libmdbx::orm::{Decodable, Encodable}; use sled::Db; @@ -73,6 +73,18 @@ impl StoreEngine for Store { todo!() } + fn add_block_number( + &mut self, + _block_hash: BlockHash, + _block_number: BlockNumber, + ) -> Result<(), StoreError> { + todo!() + } + + fn get_block_number(&self, _block_hash: BlockHash) -> Result, StoreError> { + todo!() + } + fn set_value(&mut self, key: Key, value: Value) -> Result<(), StoreError> { let _ = self.values.insert(key, value); Ok(()) From 23133aa8e81447f119b9c64d578befba699b4f3c Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 15 Jul 2024 18:11:19 -0300 Subject: [PATCH 12/36] reafctor: Remove unwraps from libmdx impl of Store --- crates/storage/src/error.rs | 2 +- crates/storage/src/libmdbx.rs | 84 +++++++++-------------------------- 2 files changed, 21 insertions(+), 65 deletions(-) diff --git a/crates/storage/src/error.rs b/crates/storage/src/error.rs index ea28b5ec21..cdcb89693c 100644 --- a/crates/storage/src/error.rs +++ b/crates/storage/src/error.rs @@ -9,7 +9,7 @@ pub enum StoreError { DecodeError, #[cfg(feature = "libmdbx")] #[error("Libmdbx error: {0}")] - LibmdbxError(anyhow::Error), + LibmdbxError(#[from] anyhow::Error), #[cfg(feature = "rocksdb")] #[error("Rocksdb error: {0}")] RocksDbError(#[from] rocksdb::Error), diff --git a/crates/storage/src/libmdbx.rs b/crates/storage/src/libmdbx.rs index 0f1283bf6c..89c16252c9 100644 --- a/crates/storage/src/libmdbx.rs +++ b/crates/storage/src/libmdbx.rs @@ -35,26 +35,15 @@ impl StoreEngine for Store { account_info: AccountInfo, ) -> Result<(), StoreError> { // Write account to mdbx - { - let txn = self.db.begin_readwrite().unwrap(); - match txn.upsert::(address.into(), account_info.into()) { - Ok(_) => txn.commit().unwrap(), - Err(err) => return Err(StoreError::LibmdbxError(err)), - } - } - Ok(()) + let txn = self.db.begin_readwrite()?; + txn.upsert::(address.into(), account_info.into())?; + Ok(txn.commit()?) } fn get_account_info(&self, address: Address) -> Result, StoreError> { // Read account from mdbx - let read_value = { - let txn = self.db.begin_read().unwrap(); - txn.get::(address.into()) - }; - match read_value { - Ok(value) => Ok(value.map(|a| a.to())), - Err(err) => Err(StoreError::LibmdbxError(err)), - } + let txn = self.db.begin_read()?; + Ok(txn.get::(address.into())?.map(|a| a.to())) } fn add_block_header( @@ -63,14 +52,9 @@ impl StoreEngine for Store { block_header: BlockHeader, ) -> std::result::Result<(), StoreError> { // Write block header to mdbx - { - let txn = self.db.begin_readwrite().unwrap(); - match txn.upsert::(block_number, block_header.into()) { - Ok(_) => txn.commit().unwrap(), - Err(err) => return Err(StoreError::LibmdbxError(err)), - } - } - Ok(()) + let txn = self.db.begin_readwrite()?; + txn.upsert::(block_number, block_header.into())?; + Ok(txn.commit()?) } fn get_block_header( @@ -78,14 +62,8 @@ impl StoreEngine for Store { block_number: BlockNumber, ) -> std::result::Result, StoreError> { // Read block header from mdbx - let read_value = { - let txn = self.db.begin_read().unwrap(); - txn.get::(block_number) - }; - match read_value { - Ok(value) => Ok(value.map(|a| a.to())), - Err(err) => Err(StoreError::LibmdbxError(err)), - } + let txn = self.db.begin_read()?; + Ok(txn.get::(block_number)?.map(|h| h.to())) } fn add_block_body( @@ -94,14 +72,9 @@ impl StoreEngine for Store { block_body: BlockBody, ) -> std::result::Result<(), StoreError> { // Write block body to mdbx - { - let txn = self.db.begin_readwrite().unwrap(); - match txn.upsert::(block_number, block_body.into()) { - Ok(_) => txn.commit().unwrap(), - Err(err) => return Err(StoreError::LibmdbxError(err)), - } - } - Ok(()) + let txn = self.db.begin_readwrite()?; + txn.upsert::(block_number, block_body.into())?; + Ok(txn.commit()?) } fn get_block_body( @@ -109,14 +82,8 @@ impl StoreEngine for Store { block_number: BlockNumber, ) -> std::result::Result, StoreError> { // Read block body from mdbx - let read_value = { - let txn = self.db.begin_read().unwrap(); - txn.get::(block_number) - }; - match read_value { - Ok(value) => Ok(value.map(|a| a.to())), - Err(err) => Err(StoreError::LibmdbxError(err)), - } + let txn = self.db.begin_read()?; + Ok(txn.get::(block_number)?.map(|b| b.to())) } fn add_block_number( @@ -125,14 +92,9 @@ impl StoreEngine for Store { block_number: BlockNumber, ) -> std::result::Result<(), StoreError> { // Write block number to mdbx - { - let txn = self.db.begin_readwrite().unwrap(); - match txn.upsert::(block_hash.into(), block_number.into()) { - Ok(_) => txn.commit().unwrap(), - Err(err) => return Err(StoreError::LibmdbxError(err)), - } - } - Ok(()) + let txn = self.db.begin_readwrite()?; + txn.upsert::(block_hash.into(), block_number)?; + Ok(txn.commit()?) } fn get_block_number( @@ -140,14 +102,8 @@ impl StoreEngine for Store { block_hash: BlockHash, ) -> std::result::Result, StoreError> { // Read block number from mdbx - let read_value = { - let txn = self.db.begin_read().unwrap(); - txn.get::(block_hash.into()) - }; - match read_value { - Ok(value) => Ok(value.map(|a| a.into())), - Err(err) => Err(StoreError::LibmdbxError(err)), - } + let txn = self.db.begin_read()?; + Ok(txn.get::(block_hash.into())?) } fn set_value(&mut self, _key: Key, _value: Value) -> Result<(), StoreError> { From ffeccbf538971616df7098147fed75d5776fa739 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 15 Jul 2024 18:18:13 -0300 Subject: [PATCH 13/36] Add methods to store --- crates/storage/src/lib.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/crates/storage/src/lib.rs b/crates/storage/src/lib.rs index c2ee0907a2..72c4ccca53 100644 --- a/crates/storage/src/lib.rs +++ b/crates/storage/src/lib.rs @@ -189,6 +189,29 @@ impl Store { .unwrap() .get_block_body(block_number) } + + pub fn add_block_number( + &self, + block_hash: BlockHash, + block_number: BlockNumber, + ) -> Result<(), StoreError> { + self.engine + .clone() + .lock() + .unwrap() + .add_block_number(block_hash, block_number) + } + + pub fn get_block_number( + &self, + block_hash: BlockHash, + ) -> Result, StoreError> { + self.engine + .clone() + .lock() + .unwrap() + .get_block_number(block_hash) + } } #[cfg(test)] From 2ab77f55d0a9e3824ed77d5817b31acf66bf5c21 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 15 Jul 2024 18:22:52 -0300 Subject: [PATCH 14/36] Add test --- crates/storage/src/lib.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/crates/storage/src/lib.rs b/crates/storage/src/lib.rs index 72c4ccca53..362f2ad09b 100644 --- a/crates/storage/src/lib.rs +++ b/crates/storage/src/lib.rs @@ -233,6 +233,7 @@ mod tests { let store = Store::new("test", EngineType::InMemory).unwrap(); test_store_account(store.clone()); test_store_block(store.clone()); + test_store_block_number(store.clone()); } #[cfg(feature = "libmdbx")] @@ -243,6 +244,7 @@ mod tests { let store = Store::new("test.mdbx", EngineType::Libmdbx).unwrap(); test_store_account(store.clone()); test_store_block(store.clone()); + test_store_block_number(store.clone()); remove_test_dbs("test.mdbx"); } @@ -255,6 +257,7 @@ mod tests { let store = Store::new("test.sled", EngineType::Sled).unwrap(); test_store_account(store.clone()); // test_store_block(store.clone()); Unimplemented + // test_store_block_number(store.clone()); Unimplemented remove_test_dbs("test.sled"); } @@ -267,6 +270,7 @@ mod tests { let store = Store::new("test.rocksdb", EngineType::Sled).unwrap(); test_store_account(store.clone()); // test_store_block(store.clone()); Unimplemented + // test_store_block_number(store.clone()); Unimplemented remove_test_dbs("test.rocksdb"); } @@ -379,4 +383,17 @@ mod tests { }; (block_header, block_body) } + + fn test_store_block_number(store: Store) { + let block_hash = H256::random(); + let block_number = 6; + + store + .add_block_number(block_hash, block_number.clone()) + .unwrap(); + + let stored_number = store.get_block_number(block_hash).unwrap().unwrap(); + + assert_eq!(stored_number, block_number); + } } From fe7ba643b95fae992b07aecee1aaa23b283bdab8 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 15 Jul 2024 18:23:34 -0300 Subject: [PATCH 15/36] clippy --- crates/storage/src/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/storage/src/lib.rs b/crates/storage/src/lib.rs index 362f2ad09b..8ba0be2183 100644 --- a/crates/storage/src/lib.rs +++ b/crates/storage/src/lib.rs @@ -388,9 +388,7 @@ mod tests { let block_hash = H256::random(); let block_number = 6; - store - .add_block_number(block_hash, block_number.clone()) - .unwrap(); + store.add_block_number(block_hash, block_number).unwrap(); let stored_number = store.get_block_number(block_hash).unwrap().unwrap(); From 682fa90c8611943b106eada3c1b18979cf8ec3ae Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 15 Jul 2024 18:25:32 -0300 Subject: [PATCH 16/36] Add table to init --- crates/storage/src/libmdbx.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/storage/src/libmdbx.rs b/crates/storage/src/libmdbx.rs index 89c16252c9..f6258b145a 100644 --- a/crates/storage/src/libmdbx.rs +++ b/crates/storage/src/libmdbx.rs @@ -157,6 +157,7 @@ dupsort!( /// will be temporary. pub fn init_db(path: Option>) -> Database { let tables = [ + table_info!(BlockNumbers), table_info!(Headers), table_info!(Bodies), table_info!(AccountInfos), From 78fee7cb9f9817c147c50962336583235eb03486 Mon Sep 17 00:00:00 2001 From: Federica Date: Thu, 11 Jul 2024 15:46:09 -0300 Subject: [PATCH 17/36] Parse GetBlockByNumber request --- crates/rpc/src/eth/block.rs | 37 ++++++++++++++++++++++++++++++++++++- crates/rpc/src/lib.rs | 15 ++++++++++++--- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/crates/rpc/src/eth/block.rs b/crates/rpc/src/eth/block.rs index d5c4c85806..02fc4b4817 100644 --- a/crates/rpc/src/eth/block.rs +++ b/crates/rpc/src/eth/block.rs @@ -1,7 +1,42 @@ +use serde::Deserialize; use serde_json::Value; use crate::utils::RpcErr; -pub fn get_block_by_number() -> Result { +pub struct GetBlockByNumberRequest { + pub block: BlockIdentifier, + pub hydrated: bool, +} + +#[derive(Deserialize)] +enum BlockIdentifier { + Number(u64), + Tag(BlockTag), +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +enum BlockTag { + Earliest, + Finalized, + Safe, + Latest, + Pending, +} + +impl GetBlockByNumberRequest { + pub fn parse(params: &Option>) -> Option { + let params = params.as_ref()?; + if params.len() != 2 { + return None; + }; + Some(GetBlockByNumberRequest { + block: serde_json::from_value(params[0].clone()).ok()?, + hydrated: serde_json::from_value(params[1].clone()).ok()?, + }) + } +} + +pub fn get_block_by_number(request: &GetBlockByNumberRequest) -> Result { Ok(Value::Null) } diff --git a/crates/rpc/src/lib.rs b/crates/rpc/src/lib.rs index 467cd82ac3..720ad5361f 100644 --- a/crates/rpc/src/lib.rs +++ b/crates/rpc/src/lib.rs @@ -2,7 +2,10 @@ use std::{future::IntoFuture, net::SocketAddr}; use axum::{routing::post, Json, Router}; use engine::{ExchangeCapabilitiesRequest, NewPayloadV3Request}; -use eth::{block, client}; +use eth::{ + block::{self, GetBlockByNumberRequest}, + client, +}; use serde_json::Value; use tokio::net::TcpListener; use tracing::info; @@ -60,7 +63,10 @@ pub fn map_requests(req: &RpcRequest) -> Result { } "eth_chainId" => client::chain_id(), "eth_syncing" => client::syncing(), - "eth_getBlockByNumber" => block::get_block_by_number(), + "eth_getBlockByNumber" => { + let request = GetBlockByNumberRequest::parse(&req.params).ok_or(RpcErr::BadParams)?; + block::get_block_by_number(&request) + } "engine_forkchoiceUpdatedV3" => engine::forkchoice_updated_v3(), "engine_newPayloadV3" => { let request = @@ -77,7 +83,10 @@ pub async fn handle_http_request(body: String) -> Json { let res: Result = match req.method.as_str() { "eth_chainId" => client::chain_id(), "eth_syncing" => client::syncing(), - "eth_getBlockByNumber" => block::get_block_by_number(), + "eth_getBlockByNumber" => { + let request = GetBlockByNumberRequest::parse(&req.params).unwrap(); + block::get_block_by_number(&request) + } "admin_nodeInfo" => admin::node_info(), _ => Err(RpcErr::MethodNotFound), }; From d154f5caaa43a408b36203b22572152c863dc58d Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 12 Jul 2024 12:03:02 -0300 Subject: [PATCH 18/36] Add state to rpc handler --- crates/rpc/Cargo.toml | 1 + crates/rpc/src/lib.rs | 9 ++++++--- ethereum_rust/src/main.rs | 4 +++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/crates/rpc/Cargo.toml b/crates/rpc/Cargo.toml index 1678f0d5c9..b6c478c367 100644 --- a/crates/rpc/Cargo.toml +++ b/crates/rpc/Cargo.toml @@ -14,3 +14,4 @@ tokio.workspace = true tracing.workspace = true tracing-subscriber.workspace = true ethereum_rust-core.workspace = true +ethereum_rust-storage.workspace = true diff --git a/crates/rpc/src/lib.rs b/crates/rpc/src/lib.rs index 720ad5361f..fd9606e9ec 100644 --- a/crates/rpc/src/lib.rs +++ b/crates/rpc/src/lib.rs @@ -16,11 +16,14 @@ mod engine; mod eth; mod utils; -pub async fn start_api(http_addr: SocketAddr, authrpc_addr: SocketAddr) { +use ethereum_rust_storage::Store; +use axum::extract::State; + +pub async fn start_api(http_addr: SocketAddr, authrpc_addr: SocketAddr, storage: Store) { let http_router = Router::new().route("/", post(handle_http_request)); let http_listener = TcpListener::bind(http_addr).await.unwrap(); - let authrpc_router = Router::new().route("/", post(handle_authrpc_request)); + let authrpc_router = Router::new().route("/", post(handle_authrpc_request)).with_state(storage); let authrpc_listener = TcpListener::bind(authrpc_addr).await.unwrap(); let authrpc_server = axum::serve(authrpc_listener, authrpc_router) @@ -43,7 +46,7 @@ async fn shutdown_signal() { .expect("failed to install Ctrl+C handler"); } -pub async fn handle_authrpc_request(body: String) -> Json { +pub async fn handle_authrpc_request( State(_state): State, body: String) -> Json { let req: RpcRequest = serde_json::from_str(&body).unwrap(); let res = map_requests(&req); rpc_response(req.id, res) diff --git a/ethereum_rust/src/main.rs b/ethereum_rust/src/main.rs index b16c3c9650..a0f62fcd22 100644 --- a/ethereum_rust/src/main.rs +++ b/ethereum_rust/src/main.rs @@ -4,6 +4,7 @@ use std::{ io::{self, BufReader}, net::{SocketAddr, ToSocketAddrs}, }; +use ethereum_rust_storage::{EngineType, Store}; use tokio::try_join; use tracing::{warn, Level}; use tracing_subscriber::FmtSubscriber; @@ -71,7 +72,8 @@ async fn main() { let _genesis = read_genesis_file(genesis_file_path); - let rpc_api = ethereum_rust_rpc::start_api(http_socket_addr, authrpc_socket_addr); + let storage = Store::new("temp.json", EngineType::InMemory).unwrap(); + let rpc_api = ethereum_rust_rpc::start_api(http_socket_addr, authrpc_socket_addr, storage); let networking = ethereum_rust_net::start_network(udp_socket_addr, tcp_socket_addr, bootnodes); try_join!(tokio::spawn(rpc_api), tokio::spawn(networking)).unwrap(); From f56738c6c7d67a79c993361bf73d5c9eba976e2f Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 12 Jul 2024 12:05:44 -0300 Subject: [PATCH 19/36] Add state to rpc handler + fmt --- crates/rpc/src/lib.rs | 18 +++++++++++------- ethereum_rust/src/main.rs | 4 ++-- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/crates/rpc/src/lib.rs b/crates/rpc/src/lib.rs index fd9606e9ec..5cc5f3ce64 100644 --- a/crates/rpc/src/lib.rs +++ b/crates/rpc/src/lib.rs @@ -16,14 +16,18 @@ mod engine; mod eth; mod utils; -use ethereum_rust_storage::Store; use axum::extract::State; +use ethereum_rust_storage::Store; pub async fn start_api(http_addr: SocketAddr, authrpc_addr: SocketAddr, storage: Store) { - let http_router = Router::new().route("/", post(handle_http_request)); + let http_router = Router::new() + .route("/", post(handle_http_request)) + .with_state(storage.clone()); let http_listener = TcpListener::bind(http_addr).await.unwrap(); - let authrpc_router = Router::new().route("/", post(handle_authrpc_request)).with_state(storage); + let authrpc_router = Router::new() + .route("/", post(handle_authrpc_request)) + .with_state(storage); let authrpc_listener = TcpListener::bind(authrpc_addr).await.unwrap(); let authrpc_server = axum::serve(authrpc_listener, authrpc_router) @@ -46,13 +50,13 @@ async fn shutdown_signal() { .expect("failed to install Ctrl+C handler"); } -pub async fn handle_authrpc_request( State(_state): State, body: String) -> Json { +pub async fn handle_authrpc_request(State(storage): State, body: String) -> Json { let req: RpcRequest = serde_json::from_str(&body).unwrap(); - let res = map_requests(&req); + let res = map_requests(&req, storage); rpc_response(req.id, res) } -pub fn map_requests(req: &RpcRequest) -> Result { +pub fn map_requests(req: &RpcRequest, storage: Store) -> Result { match req.method.as_str() { "engine_exchangeCapabilities" => { let capabilities: ExchangeCapabilitiesRequest = req @@ -80,7 +84,7 @@ pub fn map_requests(req: &RpcRequest) -> Result { } } -pub async fn handle_http_request(body: String) -> Json { +pub async fn handle_http_request(State(storage): State, body: String) -> Json { let req: RpcRequest = serde_json::from_str(&body).unwrap(); let res: Result = match req.method.as_str() { diff --git a/ethereum_rust/src/main.rs b/ethereum_rust/src/main.rs index a0f62fcd22..ec194c93fb 100644 --- a/ethereum_rust/src/main.rs +++ b/ethereum_rust/src/main.rs @@ -1,10 +1,10 @@ use ethereum_rust_core::types::Genesis; use ethereum_rust_net::bootnode::BootNode; +use ethereum_rust_storage::{EngineType, Store}; use std::{ io::{self, BufReader}, net::{SocketAddr, ToSocketAddrs}, }; -use ethereum_rust_storage::{EngineType, Store}; use tokio::try_join; use tracing::{warn, Level}; use tracing_subscriber::FmtSubscriber; @@ -72,7 +72,7 @@ async fn main() { let _genesis = read_genesis_file(genesis_file_path); - let storage = Store::new("temp.json", EngineType::InMemory).unwrap(); + let storage = Store::new("temp.json", EngineType::InMemory).unwrap(); let rpc_api = ethereum_rust_rpc::start_api(http_socket_addr, authrpc_socket_addr, storage); let networking = ethereum_rust_net::start_network(udp_socket_addr, tcp_socket_addr, bootnodes); From 62a3f87cc1b59aadd2afdb6607909340dea247e0 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 15 Jul 2024 17:18:31 -0300 Subject: [PATCH 20/36] Impl getBlockByNumber --- crates/core/src/types/block.rs | 2 ++ crates/rpc/src/eth/block.rs | 28 ++++++++++++++++++++++++---- crates/rpc/src/utils.rs | 5 +++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/crates/core/src/types/block.rs b/crates/core/src/types/block.rs index f52b844c6a..a9bcaf561e 100644 --- a/crates/core/src/types/block.rs +++ b/crates/core/src/types/block.rs @@ -22,6 +22,8 @@ use std::cmp::{max, Ordering}; use super::Transaction; +pub use serializable::BlockSerializable; + pub type BlockNumber = u64; pub type BlockHash = H256; diff --git a/crates/rpc/src/eth/block.rs b/crates/rpc/src/eth/block.rs index 02fc4b4817..4595a81576 100644 --- a/crates/rpc/src/eth/block.rs +++ b/crates/rpc/src/eth/block.rs @@ -2,6 +2,7 @@ use serde::Deserialize; use serde_json::Value; use crate::utils::RpcErr; +use ethereum_rust_core::types::BlockSerializable; pub struct GetBlockByNumberRequest { pub block: BlockIdentifier, @@ -9,14 +10,15 @@ pub struct GetBlockByNumberRequest { } #[derive(Deserialize)] -enum BlockIdentifier { +pub enum BlockIdentifier { Number(u64), + #[allow(unused)] Tag(BlockTag), } #[derive(Deserialize)] #[serde(rename_all = "camelCase")] -enum BlockTag { +pub enum BlockTag { Earliest, Finalized, Safe, @@ -37,6 +39,24 @@ impl GetBlockByNumberRequest { } } -pub fn get_block_by_number(request: &GetBlockByNumberRequest) -> Result { - Ok(Value::Null) +pub fn get_block_by_number( + request: &GetBlockByNumberRequest, + storage: Store, +) -> Result { + let block_number = match request.block { + BlockIdentifier::Tag(_) => unimplemented!("Obtain block number from tag"), + BlockIdentifier::Number(block_number) => block_number, + }; + let header = storage.get_block_header(block_number); + let body = storage.get_block_body(block_number); + let (header, body) = match (header, body) { + (Ok(Some(header)), Ok(Some(body))) => (header, body), + // Block not found + (Ok(_), Ok(_)) => return Ok(Value::Null), + // DB error + _ => return Err(RpcErr::Internal), + }; + let block = BlockSerializable::from_block(header, body, request.hydrated); + + serde_json::to_value(&block).map_err(|_| RpcErr::Internal) } diff --git a/crates/rpc/src/utils.rs b/crates/rpc/src/utils.rs index 6f02b52fb6..2c965ee8ff 100644 --- a/crates/rpc/src/utils.rs +++ b/crates/rpc/src/utils.rs @@ -5,6 +5,7 @@ pub enum RpcErr { MethodNotFound, BadParams, UnsuportedFork, + Internal, } impl From for RpcErrorMetadata { @@ -22,6 +23,10 @@ impl From for RpcErrorMetadata { code: -38005, message: "Unsupported fork".to_string(), }, + RpcErr::Internal => RpcErrorMetadata { + code: -32603, + message: "Internal Error".to_string(), + }, } } } From f8fba015eb3699d6180a35dfb7b497e25d3bab44 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 15 Jul 2024 17:40:11 -0300 Subject: [PATCH 21/36] Add getBlockByHash wip --- crates/rpc/src/eth/block.rs | 36 +++++++++++++++++++++++++++++++++++- crates/rpc/src/lib.rs | 10 +++++++++- crates/storage/src/lib.rs | 2 +- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/crates/rpc/src/eth/block.rs b/crates/rpc/src/eth/block.rs index 4595a81576..91176bd6a7 100644 --- a/crates/rpc/src/eth/block.rs +++ b/crates/rpc/src/eth/block.rs @@ -2,13 +2,18 @@ use serde::Deserialize; use serde_json::Value; use crate::utils::RpcErr; -use ethereum_rust_core::types::BlockSerializable; +use ethereum_rust_core::{types::BlockSerializable, H256}; pub struct GetBlockByNumberRequest { pub block: BlockIdentifier, pub hydrated: bool, } +pub struct GetBlockByHashRequest { + pub block: H256, + pub hydrated: bool, +} + #[derive(Deserialize)] pub enum BlockIdentifier { Number(u64), @@ -39,6 +44,19 @@ impl GetBlockByNumberRequest { } } +impl GetBlockByHashRequest { + pub fn parse(params: &Option>) -> Option { + let params = params.as_ref()?; + if params.len() != 2 { + return None; + }; + Some(GetBlockByHashRequest { + block: serde_json::from_value(params[0].clone()).ok()?, + hydrated: serde_json::from_value(params[1].clone()).ok()?, + }) + } +} + pub fn get_block_by_number( request: &GetBlockByNumberRequest, storage: Store, @@ -60,3 +78,19 @@ pub fn get_block_by_number( serde_json::to_value(&block).map_err(|_| RpcErr::Internal) } + +pub fn get_block_by_hash(request: &GetBlockByHashRequest, storage: Store) -> Result { + let block_number = 0; + let header = storage.get_block_header(block_number); + let body = storage.get_block_body(block_number); + let (header, body) = match (header, body) { + (Ok(Some(header)), Ok(Some(body))) => (header, body), + // Block not found + (Ok(_), Ok(_)) => return Ok(Value::Null), + // DB error + _ => return Err(RpcErr::Internal), + }; + let block = BlockSerializable::from_block(header, body, request.hydrated); + + serde_json::to_value(&block).map_err(|_| RpcErr::Internal) +} diff --git a/crates/rpc/src/lib.rs b/crates/rpc/src/lib.rs index 5cc5f3ce64..c56363678e 100644 --- a/crates/rpc/src/lib.rs +++ b/crates/rpc/src/lib.rs @@ -3,7 +3,7 @@ use std::{future::IntoFuture, net::SocketAddr}; use axum::{routing::post, Json, Router}; use engine::{ExchangeCapabilitiesRequest, NewPayloadV3Request}; use eth::{ - block::{self, GetBlockByNumberRequest}, + block::{self, GetBlockByHashRequest, GetBlockByNumberRequest}, client, }; use serde_json::Value; @@ -74,6 +74,10 @@ pub fn map_requests(req: &RpcRequest, storage: Store) -> Result { let request = GetBlockByNumberRequest::parse(&req.params).ok_or(RpcErr::BadParams)?; block::get_block_by_number(&request) } + "eth_getBlockByHash" => { + let request = GetBlockByHashRequest::parse(&req.params).ok_or(RpcErr::BadParams)?; + block::get_block_by_hash(&request, storage) + } "engine_forkchoiceUpdatedV3" => engine::forkchoice_updated_v3(), "engine_newPayloadV3" => { let request = @@ -94,6 +98,10 @@ pub async fn handle_http_request(State(storage): State, body: String) -> let request = GetBlockByNumberRequest::parse(&req.params).unwrap(); block::get_block_by_number(&request) } + "eth_getBlockByHash" => { + let request = GetBlockByHashRequest::parse(&req.params).unwrap(); + block::get_block_by_hash(&request, storage) + } "admin_nodeInfo" => admin::node_info(), _ => Err(RpcErr::MethodNotFound), }; diff --git a/crates/storage/src/lib.rs b/crates/storage/src/lib.rs index 6a55561247..1b67d5fa27 100644 --- a/crates/storage/src/lib.rs +++ b/crates/storage/src/lib.rs @@ -224,7 +224,7 @@ mod tests { types::{self, Transaction}, Bloom, }; - use ethereum_types::{H256, U256}; + use ethereum_types::{Bloom, H256, U256}; use super::*; From 87d2ce0b61c9fb5f3c31f530eef4ba072b721ab5 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 15 Jul 2024 18:49:07 -0300 Subject: [PATCH 22/36] Complete getBlockByHash --- crates/rpc/src/eth/block.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/crates/rpc/src/eth/block.rs b/crates/rpc/src/eth/block.rs index 91176bd6a7..ff575a3337 100644 --- a/crates/rpc/src/eth/block.rs +++ b/crates/rpc/src/eth/block.rs @@ -2,7 +2,7 @@ use serde::Deserialize; use serde_json::Value; use crate::utils::RpcErr; -use ethereum_rust_core::{types::BlockSerializable, H256}; +use ethereum_rust_core::types::{BlockHash, BlockSerializable}; pub struct GetBlockByNumberRequest { pub block: BlockIdentifier, @@ -10,7 +10,7 @@ pub struct GetBlockByNumberRequest { } pub struct GetBlockByHashRequest { - pub block: H256, + pub block: BlockHash, pub hydrated: bool, } @@ -80,7 +80,11 @@ pub fn get_block_by_number( } pub fn get_block_by_hash(request: &GetBlockByHashRequest, storage: Store) -> Result { - let block_number = 0; + let block_number = match storage.get_block_number(request.block) { + Ok(Some(number)) => number, + Ok(_) => return Ok(Value::Null), + _ => return Err(RpcErr::Internal), + }; let header = storage.get_block_header(block_number); let body = storage.get_block_body(block_number); let (header, body) = match (header, body) { From d729b60768c32aa8bf068f49bc016fcf2f9c67b9 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 15 Jul 2024 18:56:23 -0300 Subject: [PATCH 23/36] fmt --- crates/rpc/src/eth/block.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rpc/src/eth/block.rs b/crates/rpc/src/eth/block.rs index ff575a3337..63b9cb87eb 100644 --- a/crates/rpc/src/eth/block.rs +++ b/crates/rpc/src/eth/block.rs @@ -83,7 +83,7 @@ pub fn get_block_by_hash(request: &GetBlockByHashRequest, storage: Store) -> Res let block_number = match storage.get_block_number(request.block) { Ok(Some(number)) => number, Ok(_) => return Ok(Value::Null), - _ => return Err(RpcErr::Internal), + _ => return Err(RpcErr::Internal), }; let header = storage.get_block_header(block_number); let body = storage.get_block_body(block_number); From 631dfa7ec9c6beb0f3b841ea6d1722b9b9e29fb8 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 16 Jul 2024 14:05:05 -0300 Subject: [PATCH 24/36] Fixes --- crates/rpc/src/eth/block.rs | 1 + crates/rpc/src/lib.rs | 4 ++-- crates/storage/src/lib.rs | 2 +- ethereum_rust/src/main.rs | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/crates/rpc/src/eth/block.rs b/crates/rpc/src/eth/block.rs index 63b9cb87eb..cc3bfa6fab 100644 --- a/crates/rpc/src/eth/block.rs +++ b/crates/rpc/src/eth/block.rs @@ -1,3 +1,4 @@ +use ethereum_rust_storage::Store; use serde::Deserialize; use serde_json::Value; diff --git a/crates/rpc/src/lib.rs b/crates/rpc/src/lib.rs index c56363678e..e10216028e 100644 --- a/crates/rpc/src/lib.rs +++ b/crates/rpc/src/lib.rs @@ -72,7 +72,7 @@ pub fn map_requests(req: &RpcRequest, storage: Store) -> Result { "eth_syncing" => client::syncing(), "eth_getBlockByNumber" => { let request = GetBlockByNumberRequest::parse(&req.params).ok_or(RpcErr::BadParams)?; - block::get_block_by_number(&request) + block::get_block_by_number(&request, storage) } "eth_getBlockByHash" => { let request = GetBlockByHashRequest::parse(&req.params).ok_or(RpcErr::BadParams)?; @@ -96,7 +96,7 @@ pub async fn handle_http_request(State(storage): State, body: String) -> "eth_syncing" => client::syncing(), "eth_getBlockByNumber" => { let request = GetBlockByNumberRequest::parse(&req.params).unwrap(); - block::get_block_by_number(&request) + block::get_block_by_number(&request, storage) } "eth_getBlockByHash" => { let request = GetBlockByHashRequest::parse(&req.params).unwrap(); diff --git a/crates/storage/src/lib.rs b/crates/storage/src/lib.rs index 1b67d5fa27..6a55561247 100644 --- a/crates/storage/src/lib.rs +++ b/crates/storage/src/lib.rs @@ -224,7 +224,7 @@ mod tests { types::{self, Transaction}, Bloom, }; - use ethereum_types::{Bloom, H256, U256}; + use ethereum_types::{H256, U256}; use super::*; diff --git a/ethereum_rust/src/main.rs b/ethereum_rust/src/main.rs index ec194c93fb..69cc6ce3c9 100644 --- a/ethereum_rust/src/main.rs +++ b/ethereum_rust/src/main.rs @@ -72,7 +72,7 @@ async fn main() { let _genesis = read_genesis_file(genesis_file_path); - let storage = Store::new("temp.json", EngineType::InMemory).unwrap(); + let storage = Store::new("storage.db", EngineType::InMemory).unwrap(); let rpc_api = ethereum_rust_rpc::start_api(http_socket_addr, authrpc_socket_addr, storage); let networking = ethereum_rust_net::start_network(udp_socket_addr, tcp_socket_addr, bootnodes); From 2828593de0ba993996d0294c66079b34a3d4de34 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 16 Jul 2024 14:50:14 -0300 Subject: [PATCH 25/36] Add tracing --- crates/rpc/src/eth/block.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/crates/rpc/src/eth/block.rs b/crates/rpc/src/eth/block.rs index cc3bfa6fab..1bba0a3347 100644 --- a/crates/rpc/src/eth/block.rs +++ b/crates/rpc/src/eth/block.rs @@ -1,6 +1,9 @@ +use std::fmt::Display; + use ethereum_rust_storage::Store; use serde::Deserialize; use serde_json::Value; +use tracing::info; use crate::utils::RpcErr; use ethereum_rust_core::types::{BlockHash, BlockSerializable}; @@ -62,6 +65,7 @@ pub fn get_block_by_number( request: &GetBlockByNumberRequest, storage: Store, ) -> Result { + info!("Requested block with number: {}", request.block); let block_number = match request.block { BlockIdentifier::Tag(_) => unimplemented!("Obtain block number from tag"), BlockIdentifier::Number(block_number) => block_number, @@ -81,6 +85,7 @@ pub fn get_block_by_number( } pub fn get_block_by_hash(request: &GetBlockByHashRequest, storage: Store) -> Result { + info!("Requested block with hash: {}", request.block); let block_number = match storage.get_block_number(request.block) { Ok(Some(number)) => number, Ok(_) => return Ok(Value::Null), @@ -99,3 +104,18 @@ pub fn get_block_by_hash(request: &GetBlockByHashRequest, storage: Store) -> Res serde_json::to_value(&block).map_err(|_| RpcErr::Internal) } + +impl Display for BlockIdentifier { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + BlockIdentifier::Number(num) => num.fmt(f), + BlockIdentifier::Tag(tag) => match tag { + BlockTag::Earliest => "Earliest".fmt(f), + BlockTag::Finalized => "Finalized".fmt(f), + BlockTag::Safe => "Safe".fmt(f), + BlockTag::Latest => "Latest".fmt(f), + BlockTag::Pending => "Pending".fmt(f), + }, + } + } +} From 4de8f4525a250362ae13efc9ea5234ef2d57763a Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 16 Jul 2024 15:20:29 -0300 Subject: [PATCH 26/36] Remove from attribute from StoreError::Libmdx --- crates/storage/src/error.rs | 2 +- crates/storage/src/libmdbx.rs | 66 ++++++++++++++++++++++++----------- 2 files changed, 47 insertions(+), 21 deletions(-) diff --git a/crates/storage/src/error.rs b/crates/storage/src/error.rs index cdcb89693c..ea28b5ec21 100644 --- a/crates/storage/src/error.rs +++ b/crates/storage/src/error.rs @@ -9,7 +9,7 @@ pub enum StoreError { DecodeError, #[cfg(feature = "libmdbx")] #[error("Libmdbx error: {0}")] - LibmdbxError(#[from] anyhow::Error), + LibmdbxError(anyhow::Error), #[cfg(feature = "rocksdb")] #[error("Rocksdb error: {0}")] RocksDbError(#[from] rocksdb::Error), diff --git a/crates/storage/src/libmdbx.rs b/crates/storage/src/libmdbx.rs index f6258b145a..2cff9e1b63 100644 --- a/crates/storage/src/libmdbx.rs +++ b/crates/storage/src/libmdbx.rs @@ -35,15 +35,22 @@ impl StoreEngine for Store { account_info: AccountInfo, ) -> Result<(), StoreError> { // Write account to mdbx - let txn = self.db.begin_readwrite()?; - txn.upsert::(address.into(), account_info.into())?; - Ok(txn.commit()?) + let txn = self + .db + .begin_readwrite() + .map_err(StoreError::LibmdbxError)?; + txn.upsert::(address.into(), account_info.into()) + .map_err(StoreError::LibmdbxError)?; + txn.commit().map_err(StoreError::LibmdbxError) } fn get_account_info(&self, address: Address) -> Result, StoreError> { // Read account from mdbx - let txn = self.db.begin_read()?; - Ok(txn.get::(address.into())?.map(|a| a.to())) + let txn = self.db.begin_read().map_err(StoreError::LibmdbxError)?; + Ok(txn + .get::(address.into()) + .map_err(StoreError::LibmdbxError)? + .map(|a| a.to())) } fn add_block_header( @@ -52,9 +59,13 @@ impl StoreEngine for Store { block_header: BlockHeader, ) -> std::result::Result<(), StoreError> { // Write block header to mdbx - let txn = self.db.begin_readwrite()?; - txn.upsert::(block_number, block_header.into())?; - Ok(txn.commit()?) + let txn = self + .db + .begin_readwrite() + .map_err(StoreError::LibmdbxError)?; + txn.upsert::(block_number, block_header.into()) + .map_err(StoreError::LibmdbxError)?; + txn.commit().map_err(StoreError::LibmdbxError) } fn get_block_header( @@ -62,8 +73,11 @@ impl StoreEngine for Store { block_number: BlockNumber, ) -> std::result::Result, StoreError> { // Read block header from mdbx - let txn = self.db.begin_read()?; - Ok(txn.get::(block_number)?.map(|h| h.to())) + let txn = self.db.begin_read().map_err(StoreError::LibmdbxError)?; + Ok(txn + .get::(block_number) + .map_err(StoreError::LibmdbxError)? + .map(|h| h.to())) } fn add_block_body( @@ -72,9 +86,13 @@ impl StoreEngine for Store { block_body: BlockBody, ) -> std::result::Result<(), StoreError> { // Write block body to mdbx - let txn = self.db.begin_readwrite()?; - txn.upsert::(block_number, block_body.into())?; - Ok(txn.commit()?) + let txn = self + .db + .begin_readwrite() + .map_err(StoreError::LibmdbxError)?; + txn.upsert::(block_number, block_body.into()) + .map_err(StoreError::LibmdbxError)?; + txn.commit().map_err(StoreError::LibmdbxError) } fn get_block_body( @@ -82,8 +100,11 @@ impl StoreEngine for Store { block_number: BlockNumber, ) -> std::result::Result, StoreError> { // Read block body from mdbx - let txn = self.db.begin_read()?; - Ok(txn.get::(block_number)?.map(|b| b.to())) + let txn = self.db.begin_read().map_err(StoreError::LibmdbxError)?; + Ok(txn + .get::(block_number) + .map_err(StoreError::LibmdbxError)? + .map(|b| b.to())) } fn add_block_number( @@ -92,9 +113,13 @@ impl StoreEngine for Store { block_number: BlockNumber, ) -> std::result::Result<(), StoreError> { // Write block number to mdbx - let txn = self.db.begin_readwrite()?; - txn.upsert::(block_hash.into(), block_number)?; - Ok(txn.commit()?) + let txn = self + .db + .begin_readwrite() + .map_err(StoreError::LibmdbxError)?; + txn.upsert::(block_hash.into(), block_number) + .map_err(StoreError::LibmdbxError)?; + txn.commit().map_err(StoreError::LibmdbxError) } fn get_block_number( @@ -102,8 +127,9 @@ impl StoreEngine for Store { block_hash: BlockHash, ) -> std::result::Result, StoreError> { // Read block number from mdbx - let txn = self.db.begin_read()?; - Ok(txn.get::(block_hash.into())?) + let txn = self.db.begin_read().map_err(StoreError::LibmdbxError)?; + txn.get::(block_hash.into()) + .map_err(StoreError::LibmdbxError) } fn set_value(&mut self, _key: Key, _value: Value) -> Result<(), StoreError> { From 6e023e18fa89d06636ac62ef3dda2664bc29242c Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 16 Jul 2024 15:34:39 -0300 Subject: [PATCH 27/36] Collect store tests in test_store_suite --- crates/storage/src/lib.rs | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/crates/storage/src/lib.rs b/crates/storage/src/lib.rs index 6a55561247..0e327d3be7 100644 --- a/crates/storage/src/lib.rs +++ b/crates/storage/src/lib.rs @@ -232,9 +232,7 @@ mod tests { #[test] fn test_in_memory_store() { let store = Store::new("test", EngineType::InMemory).unwrap(); - test_store_account(store.clone()); - test_store_block(store.clone()); - test_store_block_number(store.clone()); + test_store_suite(store); } #[cfg(feature = "libmdbx")] @@ -243,10 +241,7 @@ mod tests { // Removing preexistent DBs in case of a failed previous test remove_test_dbs("test.mdbx"); let store = Store::new("test.mdbx", EngineType::Libmdbx).unwrap(); - test_store_account(store.clone()); - test_store_block(store.clone()); - test_store_block_number(store.clone()); - + test_store_suite(store); remove_test_dbs("test.mdbx"); } @@ -256,10 +251,7 @@ mod tests { // Removing preexistent DBs in case of a failed previous test remove_test_dbs("test.sled"); let store = Store::new("test.sled", EngineType::Sled).unwrap(); - test_store_account(store.clone()); - // test_store_block(store.clone()); Unimplemented - // test_store_block_number(store.clone()); Unimplemented - + test_store_suite(store); remove_test_dbs("test.sled"); } @@ -269,13 +261,16 @@ mod tests { // Removing preexistent DBs in case of a failed previous test remove_test_dbs("test.rocksdb"); let store = Store::new("test.rocksdb", EngineType::Sled).unwrap(); - test_store_account(store.clone()); - // test_store_block(store.clone()); Unimplemented - // test_store_block_number(store.clone()); Unimplemented - + test_store_suite(store); remove_test_dbs("test.rocksdb"); } + fn test_store_suite(store: Store) { + test_store_account(store.clone()); + test_store_block(store.clone()); + test_store_block_number(store.clone()); + } + fn test_store_account(mut store: Store) { let address = Address::random(); let code = Bytes::new(); From 30aee3ca4ebbe5d345ece31f013fc905db7c16a1 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 17 Jul 2024 15:19:21 -0300 Subject: [PATCH 28/36] Add eth_getBalance endpoint --- crates/rpc/src/eth/mod.rs | 1 + crates/rpc/src/lib.rs | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/crates/rpc/src/eth/mod.rs b/crates/rpc/src/eth/mod.rs index 45d639ba51..b73a811654 100644 --- a/crates/rpc/src/eth/mod.rs +++ b/crates/rpc/src/eth/mod.rs @@ -1,2 +1,3 @@ +pub(crate) mod account; pub(crate) mod block; pub(crate) mod client; diff --git a/crates/rpc/src/lib.rs b/crates/rpc/src/lib.rs index 2b87f3f9ba..33f1db4df2 100644 --- a/crates/rpc/src/lib.rs +++ b/crates/rpc/src/lib.rs @@ -3,6 +3,7 @@ use std::{future::IntoFuture, net::SocketAddr}; use axum::{routing::post, Json, Router}; use engine::{ExchangeCapabilitiesRequest, NewPayloadV3Request}; use eth::{ + account::{self, GetBalanceRequest}, block::{self, GetBlockByHashRequest, GetBlockByNumberRequest}, client, }; @@ -88,6 +89,10 @@ pub fn map_requests(req: &RpcRequest, storage: Store) -> Result { let request = GetBlockByHashRequest::parse(&req.params).ok_or(RpcErr::BadParams)?; block::get_block_by_hash(&request, storage) } + "eth_getBalance" => { + let request = GetBalanceRequest::parse(&req.params).ok_or(RpcErr::BadParams)?; + account::get_balance(&request, storage) + } "engine_forkchoiceUpdatedV3" => engine::forkchoice_updated_v3(), "engine_newPayloadV3" => { let request = From 13262e91c75b1767dbe119d8ce6056c2ba8d41fd Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 17 Jul 2024 15:24:17 -0300 Subject: [PATCH 29/36] Push file --- crates/rpc/src/eth/account.rs | 42 +++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 crates/rpc/src/eth/account.rs diff --git a/crates/rpc/src/eth/account.rs b/crates/rpc/src/eth/account.rs new file mode 100644 index 0000000000..1a8a8aa6d3 --- /dev/null +++ b/crates/rpc/src/eth/account.rs @@ -0,0 +1,42 @@ +use ethereum_rust_storage::Store; +use serde_json::Value; +use tracing::info; + +use crate::utils::RpcErr; +use ethereum_rust_core::Address; + +use super::block::BlockIdentifier; + +pub struct GetBalanceRequest { + pub address: Address, + pub block: BlockIdentifier, +} + +impl GetBalanceRequest { + pub fn parse(params: &Option>) -> Option { + let params = params.as_ref()?; + if params.len() != 2 { + return None; + }; + Some(GetBalanceRequest { + address: serde_json::from_value(params[0].clone()).ok()?, + block: serde_json::from_value(params[1].clone()).ok()?, + }) + } +} + +pub fn get_balance(request: &GetBalanceRequest, storage: Store) -> Result { + info!( + "Requested balance of account {} at block {}", + request.address, request.block + ); + let account = match storage.get_account_info(request.address) { + Ok(Some(account)) => account, + // Block not found + Ok(_) => return Ok(Value::Null), + // DB error + _ => return Err(RpcErr::Internal), + }; + + serde_json::to_value(&format!("{:#x}", account.balance)).map_err(|_| RpcErr::Internal) +} From d97b5d83a257041770a1da90001dff53098308bb Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 17 Jul 2024 15:28:35 -0300 Subject: [PATCH 30/36] Fix comment --- crates/rpc/src/eth/account.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rpc/src/eth/account.rs b/crates/rpc/src/eth/account.rs index 1a8a8aa6d3..dcefb672a6 100644 --- a/crates/rpc/src/eth/account.rs +++ b/crates/rpc/src/eth/account.rs @@ -32,7 +32,7 @@ pub fn get_balance(request: &GetBalanceRequest, storage: Store) -> Result account, - // Block not found + // Account not found Ok(_) => return Ok(Value::Null), // DB error _ => return Err(RpcErr::Internal), From bfa249ad59a1633f8be93c94aab43b3d59f35cf0 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 17 Jul 2024 15:31:05 -0300 Subject: [PATCH 31/36] clippy --- crates/rpc/src/eth/account.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rpc/src/eth/account.rs b/crates/rpc/src/eth/account.rs index dcefb672a6..1f784f095d 100644 --- a/crates/rpc/src/eth/account.rs +++ b/crates/rpc/src/eth/account.rs @@ -38,5 +38,5 @@ pub fn get_balance(request: &GetBalanceRequest, storage: Store) -> Result return Err(RpcErr::Internal), }; - serde_json::to_value(&format!("{:#x}", account.balance)).map_err(|_| RpcErr::Internal) + serde_json::to_value(format!("{:#x}", account.balance)).map_err(|_| RpcErr::Internal) } From cd8edfbca8c14b89f99e074caaf79d6f4044b398 Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 17 Jul 2024 17:30:20 -0300 Subject: [PATCH 32/36] Add endpoint + store api methods --- crates/rpc/src/eth/account.rs | 34 +++++++++++++++++++++++++++++++ crates/storage/src/in_memory.rs | 13 +++++++++++- crates/storage/src/lib.rs | 36 ++++++++++++++++++++++++++++++++- crates/storage/src/libmdbx.rs | 20 ++++++++++++++++++ crates/storage/src/rocksdb.rs | 9 +++++++++ crates/storage/src/sled.rs | 9 +++++++++ 6 files changed, 119 insertions(+), 2 deletions(-) diff --git a/crates/rpc/src/eth/account.rs b/crates/rpc/src/eth/account.rs index 1f784f095d..58d26d9fbd 100644 --- a/crates/rpc/src/eth/account.rs +++ b/crates/rpc/src/eth/account.rs @@ -12,6 +12,11 @@ pub struct GetBalanceRequest { pub block: BlockIdentifier, } +pub struct GetCodeRequest { + pub address: Address, + pub block: BlockIdentifier, +} + impl GetBalanceRequest { pub fn parse(params: &Option>) -> Option { let params = params.as_ref()?; @@ -25,6 +30,19 @@ impl GetBalanceRequest { } } +impl GetCodeRequest { + pub fn parse(params: &Option>) -> Option { + let params = params.as_ref()?; + if params.len() != 2 { + return None; + }; + Some(GetCodeRequest { + address: serde_json::from_value(params[0].clone()).ok()?, + block: serde_json::from_value(params[1].clone()).ok()?, + }) + } +} + pub fn get_balance(request: &GetBalanceRequest, storage: Store) -> Result { info!( "Requested balance of account {} at block {}", @@ -40,3 +58,19 @@ pub fn get_balance(request: &GetBalanceRequest, storage: Store) -> Result Result { + info!( + "Requested balance of account {} at block {}", + request.address, request.block + ); + let code = match storage.get_code_by_account_address(request.address) { + Ok(Some(code)) => code, + // Account not found + Ok(_) => return Ok(Value::Null), + // DB error + _ => return Err(RpcErr::Internal), + }; + + serde_json::to_value(format!("0x{:x}", code)).map_err(|_| RpcErr::Internal) +} diff --git a/crates/storage/src/in_memory.rs b/crates/storage/src/in_memory.rs index 2402b39ad2..8a1aea537f 100644 --- a/crates/storage/src/in_memory.rs +++ b/crates/storage/src/in_memory.rs @@ -1,7 +1,7 @@ use super::{Key, StoreEngine, Value}; use crate::error::StoreError; use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHash, BlockHeader, BlockNumber}; -use ethereum_types::Address; +use ethereum_types::{Address, H256}; use std::{collections::HashMap, fmt::Debug}; #[derive(Default)] @@ -11,6 +11,8 @@ pub struct Store { bodies: HashMap, headers: HashMap, values: HashMap, + // Maps code hashes to code + account_codes: HashMap, } impl Store { @@ -80,6 +82,15 @@ impl StoreEngine for Store { fn get_block_number(&self, block_hash: BlockHash) -> Result, StoreError> { Ok(self.block_numbers.get(&block_hash).copied()) } + + fn add_account_code(&mut self, code_hash: H256, code: Bytes) -> Result<(), StoreError> { + self.account_codes.insert(code_hash, code); + Ok(()) + } + + fn get_account_code(&self, code_hash: H256) -> Result, StoreError> { + Ok(self.account_codes.get(&code_hash)) + } } impl Debug for Store { diff --git a/crates/storage/src/lib.rs b/crates/storage/src/lib.rs index 0e327d3be7..c9cdb4f257 100644 --- a/crates/storage/src/lib.rs +++ b/crates/storage/src/lib.rs @@ -14,7 +14,7 @@ use self::rocksdb::Store as RocksDbStore; #[cfg(feature = "sled")] use self::sled::Store as SledStore; use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHash, BlockHeader, BlockNumber}; -use ethereum_types::Address; +use ethereum_types::{Address, H256}; use std::fmt::Debug; use std::sync::{Arc, Mutex}; @@ -82,6 +82,12 @@ pub trait StoreEngine: Debug + Send { /// Retrieve a stored value under Key fn get_value(&self, key: Key) -> Result, StoreError>; + + /// Add account code + fn add_account_code(&mut self, code_hash: H256, code: Bytes) -> Result<(), StoreError>; + + /// Obtain account code + fn get_account_code(&self, code_hash: H256) -> Result, StoreError>; } #[derive(Debug, Clone)] @@ -212,6 +218,22 @@ impl Store { .unwrap() .get_block_number(block_hash) } + + pub fn add_account_code(&self, code_hash: H256, code: Bytes) -> Result<(), StoreError> { + self.engine + .clone() + .lock() + .unwrap() + .add_account_code(code_hash, code) + } + + pub fn get_account_code(&self, code_hash: H256) -> Result, StoreError> { + self.engine + .clone() + .lock() + .unwrap() + .get_account_code(code_hash) + } } #[cfg(test)] @@ -269,6 +291,7 @@ mod tests { test_store_account(store.clone()); test_store_block(store.clone()); test_store_block_number(store.clone()); + test_get_account_code(store.clone()); } fn test_store_account(mut store: Store) { @@ -390,4 +413,15 @@ mod tests { assert_eq!(stored_number, block_number); } + + fn test_store_account_code(store: Store) { + let code_hash = H256::random(); + let code = Bytes::from("kiwi"); + + store.add_account_code(code_hash, code).unwrap(); + + let stored_code = store.get_account_code(code_hash).unwrap().unwrap(); + + assert_eq!(stored_code, code); + } } diff --git a/crates/storage/src/libmdbx.rs b/crates/storage/src/libmdbx.rs index 2cff9e1b63..003214adcc 100644 --- a/crates/storage/src/libmdbx.rs +++ b/crates/storage/src/libmdbx.rs @@ -139,6 +139,26 @@ impl StoreEngine for Store { fn get_value(&self, _key: Key) -> Result, StoreError> { todo!() } + + fn add_account_code(&mut self, code_hash: H256, code: Bytes) -> Result<(), StoreError> { + // Write account code to mdbx + let txn = self + .db + .begin_readwrite() + .map_err(StoreError::LibmdbxError)?; + txn.upsert::(code_hash, code.into()) + .map_err(StoreError::LibmdbxError)?; + txn.commit().map_err(StoreError::LibmdbxError) + } + + fn get_account_code(&self, code_hash: H256) -> Result, StoreError> { + // Read account code from mdbx + let txn = self.db.begin_read().map_err(StoreError::LibmdbxError)?; + Ok(txn + .get::(code_hash) + .map_err(StoreError::LibmdbxError)? + .map(|b| b.to())) + } } impl Debug for Store { diff --git a/crates/storage/src/rocksdb.rs b/crates/storage/src/rocksdb.rs index e8a0e06024..b0f59b5d8a 100644 --- a/crates/storage/src/rocksdb.rs +++ b/crates/storage/src/rocksdb.rs @@ -1,6 +1,7 @@ use super::{Key, StoreEngine, Value}; use crate::error::StoreError; use crate::rlp::{AccountInfoRLP, AddressRLP}; +use bytes::Bytes; use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHash, BlockHeader, BlockNumber}; use ethereum_types::Address; use libmdbx::orm::{Decodable, Encodable}; @@ -165,6 +166,14 @@ impl StoreEngine for Store { reply_receiver.recv()? } + + fn add_account_code(&mut self, _code_hash: H256, _code: Bytes) -> Result<(), StoreError> { + todo!() + } + + fn get_account_code(&self, _code_hash: H256) -> Result, StoreError> { + todo!() + } } impl Debug for Store { diff --git a/crates/storage/src/sled.rs b/crates/storage/src/sled.rs index 0334a267df..144dc436e1 100644 --- a/crates/storage/src/sled.rs +++ b/crates/storage/src/sled.rs @@ -1,6 +1,7 @@ use super::{Key, StoreEngine, Value}; use crate::error::StoreError; use crate::rlp::{AccountInfoRLP, AddressRLP}; +use bytes::Bytes; use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHash, BlockHeader, BlockNumber}; use ethereum_types::Address; use libmdbx::orm::{Decodable, Encodable}; @@ -93,6 +94,14 @@ impl StoreEngine for Store { fn get_value(&self, key: Key) -> Result>, StoreError> { Ok(self.values.get(key)?.map(|value| value.to_vec())) } + + fn add_account_code(&mut self, _code_hash: H256, _code: Bytes) -> Result<(), StoreError> { + todo!() + } + + fn get_account_code(&self, _code_hash: H256) -> Result, StoreError> { + todo!() + } } impl Debug for Store { From 5ed85a55d47223f46cf81ee44d3717c05c0a479c Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 17 Jul 2024 17:34:50 -0300 Subject: [PATCH 33/36] add get_code_by_account_address method to store --- crates/storage/src/lib.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/crates/storage/src/lib.rs b/crates/storage/src/lib.rs index c9cdb4f257..fc937c1bfe 100644 --- a/crates/storage/src/lib.rs +++ b/crates/storage/src/lib.rs @@ -86,8 +86,18 @@ pub trait StoreEngine: Debug + Send { /// Add account code fn add_account_code(&mut self, code_hash: H256, code: Bytes) -> Result<(), StoreError>; - /// Obtain account code + /// Obtain account code via code hash fn get_account_code(&self, code_hash: H256) -> Result, StoreError>; + + + /// Obtain account code via account address + fn get_code_by_account_address(&self, address: Address) -> Result, StoreError> { + let code_hash = match self.get_account_info(address) { + Ok(Some(acc_info)) => acc_info.code_hash, + ret => return ret, + }; + self.get_account_code(code_hash) + } } #[derive(Debug, Clone)] From 7b7e4fe50e79ab0fba7b89576f3a0b613175e0ef Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 17 Jul 2024 17:47:41 -0300 Subject: [PATCH 34/36] Fix --- crates/storage/src/in_memory.rs | 3 ++- crates/storage/src/lib.rs | 20 ++++++++++++++++---- crates/storage/src/libmdbx.rs | 9 +++++---- crates/storage/src/rlp.rs | 7 ++++--- crates/storage/src/rocksdb.rs | 2 +- crates/storage/src/sled.rs | 2 +- 6 files changed, 29 insertions(+), 14 deletions(-) diff --git a/crates/storage/src/in_memory.rs b/crates/storage/src/in_memory.rs index 8a1aea537f..ecb9d0e21f 100644 --- a/crates/storage/src/in_memory.rs +++ b/crates/storage/src/in_memory.rs @@ -1,5 +1,6 @@ use super::{Key, StoreEngine, Value}; use crate::error::StoreError; +use bytes::Bytes; use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHash, BlockHeader, BlockNumber}; use ethereum_types::{Address, H256}; use std::{collections::HashMap, fmt::Debug}; @@ -89,7 +90,7 @@ impl StoreEngine for Store { } fn get_account_code(&self, code_hash: H256) -> Result, StoreError> { - Ok(self.account_codes.get(&code_hash)) + Ok(self.account_codes.get(&code_hash).cloned()) } } diff --git a/crates/storage/src/lib.rs b/crates/storage/src/lib.rs index fc937c1bfe..0b821b3d5e 100644 --- a/crates/storage/src/lib.rs +++ b/crates/storage/src/lib.rs @@ -13,6 +13,7 @@ use self::libmdbx::Store as LibmdbxStore; use self::rocksdb::Store as RocksDbStore; #[cfg(feature = "sled")] use self::sled::Store as SledStore; +use bytes::Bytes; use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHash, BlockHeader, BlockNumber}; use ethereum_types::{Address, H256}; use std::fmt::Debug; @@ -89,12 +90,12 @@ pub trait StoreEngine: Debug + Send { /// Obtain account code via code hash fn get_account_code(&self, code_hash: H256) -> Result, StoreError>; - /// Obtain account code via account address fn get_code_by_account_address(&self, address: Address) -> Result, StoreError> { let code_hash = match self.get_account_info(address) { Ok(Some(acc_info)) => acc_info.code_hash, - ret => return ret, + Ok(None) => return Ok(None), + Err(error) => return Err(error), }; self.get_account_code(code_hash) } @@ -244,6 +245,17 @@ impl Store { .unwrap() .get_account_code(code_hash) } + + pub fn get_code_by_account_address( + &self, + address: Address, + ) -> Result, StoreError> { + self.engine + .clone() + .lock() + .unwrap() + .get_code_by_account_address(address) + } } #[cfg(test)] @@ -301,7 +313,7 @@ mod tests { test_store_account(store.clone()); test_store_block(store.clone()); test_store_block_number(store.clone()); - test_get_account_code(store.clone()); + test_store_account_code(store.clone()); } fn test_store_account(mut store: Store) { @@ -428,7 +440,7 @@ mod tests { let code_hash = H256::random(); let code = Bytes::from("kiwi"); - store.add_account_code(code_hash, code).unwrap(); + store.add_account_code(code_hash, code.clone()).unwrap(); let stored_code = store.get_account_code(code_hash).unwrap().unwrap(); diff --git a/crates/storage/src/libmdbx.rs b/crates/storage/src/libmdbx.rs index 003214adcc..ca4e1bee97 100644 --- a/crates/storage/src/libmdbx.rs +++ b/crates/storage/src/libmdbx.rs @@ -5,9 +5,10 @@ use crate::rlp::{ AccountStorageValueRLP, AddressRLP, BlockBodyRLP, BlockHashRLP, BlockHeaderRLP, ReceiptRLP, }; use anyhow::Result; +use bytes::Bytes; use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHash, BlockHeader}; use ethereum_rust_core::types::{BlockNumber, Index}; -use ethereum_types::Address; +use ethereum_types::{Address, H256}; use libmdbx::{ dupsort, orm::{table, Database}, @@ -146,7 +147,7 @@ impl StoreEngine for Store { .db .begin_readwrite() .map_err(StoreError::LibmdbxError)?; - txn.upsert::(code_hash, code.into()) + txn.upsert::(code_hash.into(), code.into()) .map_err(StoreError::LibmdbxError)?; txn.commit().map_err(StoreError::LibmdbxError) } @@ -155,9 +156,9 @@ impl StoreEngine for Store { // Read account code from mdbx let txn = self.db.begin_read().map_err(StoreError::LibmdbxError)?; Ok(txn - .get::(code_hash) + .get::(code_hash.into()) .map_err(StoreError::LibmdbxError)? - .map(|b| b.to())) + .map(|b| b.to().into())) } } diff --git a/crates/storage/src/rlp.rs b/crates/storage/src/rlp.rs index 01fa8284c7..98c0d29ae2 100644 --- a/crates/storage/src/rlp.rs +++ b/crates/storage/src/rlp.rs @@ -1,17 +1,18 @@ use std::marker::PhantomData; +use bytes::Bytes; use ethereum_rust_core::{ rlp::{decode::RLPDecode, encode::RLPEncode}, types::{AccountInfo, BlockBody, BlockHash, BlockHeader, Receipt}, - Address, + Address, H256, }; use libmdbx::orm::{Decodable, Encodable}; // Account types pub type AddressRLP = Rlp
; pub type AccountInfoRLP = Rlp; -pub type AccountCodeHashRLP = Rlp>; -pub type AccountCodeRLP = Rlp>; +pub type AccountCodeHashRLP = Rlp; +pub type AccountCodeRLP = Rlp; // TODO: these structs were changed after a merge. // See if we can reuse Rlp struct diff --git a/crates/storage/src/rocksdb.rs b/crates/storage/src/rocksdb.rs index b0f59b5d8a..d66662ffce 100644 --- a/crates/storage/src/rocksdb.rs +++ b/crates/storage/src/rocksdb.rs @@ -3,7 +3,7 @@ use crate::error::StoreError; use crate::rlp::{AccountInfoRLP, AddressRLP}; use bytes::Bytes; use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHash, BlockHeader, BlockNumber}; -use ethereum_types::Address; +use ethereum_types::{Address, H256}; use libmdbx::orm::{Decodable, Encodable}; use std::fmt::Debug; use std::sync::mpsc::{channel, sync_channel, Receiver, Sender, SyncSender}; diff --git a/crates/storage/src/sled.rs b/crates/storage/src/sled.rs index 144dc436e1..8175d4595b 100644 --- a/crates/storage/src/sled.rs +++ b/crates/storage/src/sled.rs @@ -3,7 +3,7 @@ use crate::error::StoreError; use crate::rlp::{AccountInfoRLP, AddressRLP}; use bytes::Bytes; use ethereum_rust_core::types::{AccountInfo, BlockBody, BlockHash, BlockHeader, BlockNumber}; -use ethereum_types::Address; +use ethereum_types::{Address, H256}; use libmdbx::orm::{Decodable, Encodable}; use sled::Db; use std::fmt::Debug; From ec4f7c3c0deaebd3bb0e19ac0adaee541b0c959d Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 17 Jul 2024 17:52:05 -0300 Subject: [PATCH 35/36] Add rpc call + update tracing --- crates/rpc/src/eth/account.rs | 2 +- crates/rpc/src/lib.rs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/rpc/src/eth/account.rs b/crates/rpc/src/eth/account.rs index 58d26d9fbd..6c5f378280 100644 --- a/crates/rpc/src/eth/account.rs +++ b/crates/rpc/src/eth/account.rs @@ -61,7 +61,7 @@ pub fn get_balance(request: &GetBalanceRequest, storage: Store) -> Result Result { info!( - "Requested balance of account {} at block {}", + "Requested code of account {} at block {}", request.address, request.block ); let code = match storage.get_code_by_account_address(request.address) { diff --git a/crates/rpc/src/lib.rs b/crates/rpc/src/lib.rs index 33f1db4df2..b1fa5b719f 100644 --- a/crates/rpc/src/lib.rs +++ b/crates/rpc/src/lib.rs @@ -93,6 +93,10 @@ pub fn map_requests(req: &RpcRequest, storage: Store) -> Result { let request = GetBalanceRequest::parse(&req.params).ok_or(RpcErr::BadParams)?; account::get_balance(&request, storage) } + "eth_getCode" => { + let request = GetCodeRequest::parse(&req.params).ok_or(RpcErr::BadParams)?; + account::get_code(&request, storage) + } "engine_forkchoiceUpdatedV3" => engine::forkchoice_updated_v3(), "engine_newPayloadV3" => { let request = From cac3a99f2ff385120a6a7bcb391e9562fa93dd1b Mon Sep 17 00:00:00 2001 From: Federica Date: Wed, 17 Jul 2024 17:58:18 -0300 Subject: [PATCH 36/36] fix --- crates/rpc/src/lib.rs | 2 +- crates/storage/src/libmdbx.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/rpc/src/lib.rs b/crates/rpc/src/lib.rs index b1fa5b719f..690e2cdfa2 100644 --- a/crates/rpc/src/lib.rs +++ b/crates/rpc/src/lib.rs @@ -3,7 +3,7 @@ use std::{future::IntoFuture, net::SocketAddr}; use axum::{routing::post, Json, Router}; use engine::{ExchangeCapabilitiesRequest, NewPayloadV3Request}; use eth::{ - account::{self, GetBalanceRequest}, + account::{self, GetBalanceRequest, GetCodeRequest}, block::{self, GetBlockByHashRequest, GetBlockByNumberRequest}, client, }; diff --git a/crates/storage/src/libmdbx.rs b/crates/storage/src/libmdbx.rs index ca4e1bee97..3c60b65707 100644 --- a/crates/storage/src/libmdbx.rs +++ b/crates/storage/src/libmdbx.rs @@ -158,7 +158,7 @@ impl StoreEngine for Store { Ok(txn .get::(code_hash.into()) .map_err(StoreError::LibmdbxError)? - .map(|b| b.to().into())) + .map(|b| b.to())) } }