Skip to content

Commit

Permalink
Esad/enhance u256 to u64 conversion (#492)
Browse files Browse the repository at this point in the history
* use register_async_method in ledgerdb rpcs

* remove convert_u256_to_u64 function
  • Loading branch information
eyusufatik authored May 5, 2024
1 parent 0875c37 commit 640b528
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 70 deletions.
8 changes: 3 additions & 5 deletions crates/ethereum-rpc/src/gas_price/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<C: sov_modules_api::Context> {
// Assuming number_to_hash and cache are always in sync
Expand Down Expand Up @@ -36,7 +34,7 @@ impl<C: sov_modules_api::Context> BlockCache<C> {
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()));
}
Expand All @@ -49,7 +47,7 @@ impl<C: sov_modules_api::Context> BlockCache<C> {

// 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());
Expand Down Expand Up @@ -83,7 +81,7 @@ impl<C: sov_modules_api::Context> BlockCache<C> {

// 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);
Expand Down
19 changes: 10 additions & 9 deletions crates/ethereum-rpc/src/gas_price/fee_history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -95,7 +93,7 @@ impl<C: sov_modules_api::Context> FeeHistoryCache<C> {
&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);
}
}
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -250,11 +248,14 @@ impl FeeHistoryEntry {
///
/// Note: This does not calculate the rewards for the block.
pub fn new(block: &Rich<Block>) -> 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 {
Expand Down
37 changes: 1 addition & 36 deletions crates/ethereum-rpc/src/gas_price/gas_oracle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ impl<C: sov_modules_api::Context> GasPriceOracle<C> {
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 {
Expand Down Expand Up @@ -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();
Expand All @@ -481,8 +472,6 @@ pub(crate) fn convert_u256_to_u128(u256: reth_primitives::U256) -> Result<u128,

#[cfg(test)]
mod tests {
use proptest::arbitrary::any;
use proptest::proptest;
use reth_primitives::constants::GWEI_TO_WEI;

use super::*;
Expand All @@ -497,28 +486,4 @@ mod tests {
fn ignore_price_sanity() {
assert_eq!(DEFAULT_IGNORE_PRICE, U256::from(2u64));
}

proptest! {

#[test]
fn converts_back_and_forth(input in any::<u64>()) {
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);
}
}
}
22 changes: 10 additions & 12 deletions crates/ethereum-rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -562,7 +560,7 @@ fn register_rpc_methods<C: sov_modules_api::Context, Da: DaService>(
let evm = Evm::<C>::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()),
};

Expand Down Expand Up @@ -624,15 +622,15 @@ fn register_rpc_methods<C: sov_modules_api::Context, Da: DaService>(
.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<GethDebugTracingOptions> = params.optional_next()?;

Expand Down
9 changes: 1 addition & 8 deletions crates/evm/src/query.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::array::TryFromSliceError;
use std::collections::BTreeMap;
use std::ops::{Range, RangeInclusive};

Expand Down Expand Up @@ -900,7 +899,7 @@ impl<C: sov_modules_api::Context> Evm<C> {

// 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);

Expand Down Expand Up @@ -1654,12 +1653,6 @@ fn map_out_of_gas_err<C: sov_modules_api::Context>(
}
}

fn convert_u256_to_u64(u256: reth_primitives::U256) -> Result<u64, TryFromSliceError> {
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]
Expand Down

0 comments on commit 640b528

Please sign in to comment.