From 640b528f9def725bbec5d630ae112c39ffb8d393 Mon Sep 17 00:00:00 2001 From: Esad Yusuf Atik Date: Sun, 5 May 2024 20:24:56 +0300 Subject: [PATCH] Esad/enhance u256 to u64 conversion (#492) * use register_async_method in ledgerdb rpcs * remove convert_u256_to_u64 function --- crates/ethereum-rpc/src/gas_price/cache.rs | 8 ++-- .../ethereum-rpc/src/gas_price/fee_history.rs | 19 +++++----- .../ethereum-rpc/src/gas_price/gas_oracle.rs | 37 +------------------ crates/ethereum-rpc/src/lib.rs | 22 +++++------ crates/evm/src/query.rs | 9 +---- 5 files changed, 25 insertions(+), 70 deletions(-) diff --git a/crates/ethereum-rpc/src/gas_price/cache.rs b/crates/ethereum-rpc/src/gas_price/cache.rs index e77295fe8..31610c266 100644 --- a/crates/ethereum-rpc/src/gas_price/cache.rs +++ b/crates/ethereum-rpc/src/gas_price/cache.rs @@ -6,8 +6,6 @@ use reth_rpc_types::{Block, BlockTransactions, Rich, TransactionReceipt}; use schnellru::{ByLength, LruMap}; use sov_modules_api::WorkingSet; -use super::gas_oracle::convert_u256_to_u64; - /// Cache for gas oracle pub struct BlockCache { // Assuming number_to_hash and cache are always in sync @@ -36,7 +34,7 @@ impl BlockCache { let mut number_to_hash = self.number_to_hash.lock().unwrap(); if let Some(block) = cache.get(&block_hash) { // Even though block is in cache, ask number_to_hash to keep it in sync - let number = convert_u256_to_u64(block.header.number.unwrap_or_default()); + let number: u64 = block.header.number.unwrap_or_default().saturating_to(); number_to_hash.get(&number); return Ok(Some(block.clone())); } @@ -49,7 +47,7 @@ impl BlockCache { // Add block to cache if it exists if let Some(block) = &block { - let number = convert_u256_to_u64(block.header.number.unwrap_or_default()); + let number: u64 = block.header.number.unwrap_or_default().saturating_to(); number_to_hash.insert(number, block_hash); cache.insert(block_hash, block.clone()); @@ -83,7 +81,7 @@ impl BlockCache { // Add block to cache if it exists if let Some(block) = &block { - let number = convert_u256_to_u64(block.header.number.unwrap_or_default()); + let number: u64 = block.header.number.unwrap_or_default().saturating_to(); let hash = block.header.hash.unwrap_or_default(); number_to_hash.insert(number, hash); diff --git a/crates/ethereum-rpc/src/gas_price/fee_history.rs b/crates/ethereum-rpc/src/gas_price/fee_history.rs index af90c7309..07db7e4e8 100644 --- a/crates/ethereum-rpc/src/gas_price/fee_history.rs +++ b/crates/ethereum-rpc/src/gas_price/fee_history.rs @@ -12,9 +12,7 @@ use serde::{Deserialize, Serialize}; use sov_modules_api::WorkingSet; use super::cache::BlockCache; -use super::gas_oracle::{ - convert_u256_to_u128, convert_u256_to_u64, effective_gas_tip, MAX_HEADER_HISTORY, -}; +use super::gas_oracle::{convert_u256_to_u128, effective_gas_tip, MAX_HEADER_HISTORY}; /// Settings for the [FeeHistoryCache]. #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] @@ -95,7 +93,7 @@ impl FeeHistoryCache { &receipts, ) .unwrap_or_default(); - let block_number = convert_u256_to_u64(block.header.number.unwrap_or_default()); + let block_number: u64 = block.header.number.unwrap_or_default().saturating_to(); entries.insert(block_number, fee_history_entry); } } @@ -183,7 +181,7 @@ pub(crate) fn calculate_reward_percentiles_for_block( // While we will sum up the gas again later, it is worth // noting that the order of the transactions will be different, // so the sum will also be different for each receipt. - let cumulative_gas_used = convert_u256_to_u64(receipt.cumulative_gas_used); + let cumulative_gas_used: u64 = receipt.cumulative_gas_used.saturating_to(); let gas_used = cumulative_gas_used - *previous_gas; *previous_gas = cumulative_gas_used; @@ -250,11 +248,14 @@ impl FeeHistoryEntry { /// /// Note: This does not calculate the rewards for the block. pub fn new(block: &Rich) -> Self { - let base_fee_per_gas = - convert_u256_to_u64(block.header.base_fee_per_gas.unwrap_or_default()); + let base_fee_per_gas: u64 = block + .header + .base_fee_per_gas + .unwrap_or_default() + .saturating_to(); - let gas_used = convert_u256_to_u64(block.header.gas_used); - let gas_limit = convert_u256_to_u64(block.header.gas_limit); + let gas_used: u64 = block.header.gas_used.saturating_to(); + let gas_limit: u64 = block.header.gas_limit.saturating_to(); let gas_used_ratio = gas_used as f64 / gas_limit as f64; FeeHistoryEntry { diff --git a/crates/ethereum-rpc/src/gas_price/gas_oracle.rs b/crates/ethereum-rpc/src/gas_price/gas_oracle.rs index 5cf5e787f..c37c4548a 100644 --- a/crates/ethereum-rpc/src/gas_price/gas_oracle.rs +++ b/crates/ethereum-rpc/src/gas_price/gas_oracle.rs @@ -264,7 +264,7 @@ impl GasPriceOracle { let mut results = Vec::new(); let mut populated_blocks = 0; - let header_number = convert_u256_to_u64(header.number.unwrap()); + let header_number: u64 = header.number.unwrap().saturating_to(); // we only check a maximum of 2 * max_block_history, or the number of blocks in the chain let max_blocks = if self.oracle_config.max_block_history * 2 > header_number { @@ -456,15 +456,6 @@ pub(crate) fn effective_gas_tip( } } -/// Takes only 8 least significant bytes -pub fn convert_u256_to_u64(u256: U256) -> u64 { - let bytes: [u8; 32] = u256.to_be_bytes(); - // 32 - 24 = 8, so it should always fit into destination array. - // Unless allocation or something weird - let bytes: [u8; 8] = bytes[24..].try_into().unwrap(); - u64::from_be_bytes(bytes) -} - #[allow(dead_code)] pub(crate) fn convert_u64_to_u256(u64: u64) -> reth_primitives::U256 { let bytes: [u8; 8] = u64.to_be_bytes(); @@ -481,8 +472,6 @@ pub(crate) fn convert_u256_to_u128(u256: reth_primitives::U256) -> Result()) { - let mut bytes: [u8; 32] = [0; 32]; - for (i, b) in input.to_be_bytes().into_iter().enumerate() { - let idx = 24 + i; - bytes[idx] = b; - } - - - let u256 = U256::from_be_slice(&bytes); - let output = convert_u256_to_u64(u256); - - assert_eq!(input, output); - } - - #[test] - fn convert_u256_to_u64_doesnt_panic(input in any::<[u8; 32]>()) { - let u256 = U256::from_be_slice(&input); - let _output = convert_u256_to_u64(u256); - } - } } diff --git a/crates/ethereum-rpc/src/lib.rs b/crates/ethereum-rpc/src/lib.rs index 12e1a44e8..b3a9dd10e 100644 --- a/crates/ethereum-rpc/src/lib.rs +++ b/crates/ethereum-rpc/src/lib.rs @@ -29,8 +29,6 @@ use sov_modules_api::WorkingSet; use sov_rollup_interface::services::da::DaService; use tracing::info; -use crate::gas_price::gas_oracle::convert_u256_to_u64; - const MAX_TRACE_BLOCK: u32 = 1000; #[derive(Clone)] @@ -562,7 +560,7 @@ fn register_rpc_methods( let evm = Evm::::default(); let block_number = match block_number { BlockNumberOrTag::Number(block_number) => block_number, - BlockNumberOrTag::Latest => convert_u256_to_u64(evm.block_number(&mut working_set)?), + BlockNumberOrTag::Latest => evm.block_number(&mut working_set)?.saturating_to(), _ => return Err(EthApiError::Unsupported("Earliest, pending, safe and finalized are not supported for debug_traceBlockByNumber").into()), }; @@ -624,15 +622,15 @@ fn register_rpc_methods( .get_transaction_by_hash(tx_hash, &mut working_set) .unwrap() .ok_or_else(|| EthApiError::UnknownBlockOrTxIndex)?; - let trace_index = convert_u256_to_u64( - tx.transaction_index - .expect("Tx index must be set for tx inside block"), - ); - - let block_number = convert_u256_to_u64( - tx.block_number - .expect("Block number must be set for tx inside block"), - ); + let trace_index: u64 = tx + .transaction_index + .expect("Tx index must be set for tx inside block") + .saturating_to(); + + let block_number: u64 = tx + .block_number + .expect("Block number must be set for tx inside block") + .saturating_to(); let opts: Option = params.optional_next()?; diff --git a/crates/evm/src/query.rs b/crates/evm/src/query.rs index b8ef322b9..68a56b5b0 100644 --- a/crates/evm/src/query.rs +++ b/crates/evm/src/query.rs @@ -1,4 +1,3 @@ -use std::array::TryFromSliceError; use std::collections::BTreeMap; use std::ops::{Range, RangeInclusive}; @@ -900,7 +899,7 @@ impl Evm { // if the provided gas limit is less than computed cap, use that let gas_limit = std::cmp::min(U256::from(tx_env.gas_limit), highest_gas_limit); - tx_env.gas_limit = convert_u256_to_u64(gas_limit).unwrap(); + tx_env.gas_limit = gas_limit.saturating_to(); let evm_db = self.get_db(working_set); @@ -1654,12 +1653,6 @@ fn map_out_of_gas_err( } } -fn convert_u256_to_u64(u256: reth_primitives::U256) -> Result { - let bytes: [u8; 32] = u256.to_be_bytes(); - let bytes: [u8; 8] = bytes[24..].try_into()?; - Ok(u64::from_be_bytes(bytes)) -} - /// Updates the highest and lowest gas limits for binary search /// based on the result of the execution #[inline]