diff --git a/lib/ain-evm/src/block.rs b/lib/ain-evm/src/block.rs index 0fca831ba7..8c34469c83 100644 --- a/lib/ain-evm/src/block.rs +++ b/lib/ain-evm/src/block.rs @@ -12,7 +12,7 @@ use statrs::statistics::{Data, OrderStatistics}; use crate::{ storage::{traits::BlockStorage, Storage}, - Result, + EVMError, Result, }; pub struct BlockService { @@ -76,31 +76,57 @@ impl BlockService { parent_base_fee: U256, base_fee_max_change_denominator: U256, initial_base_fee: U256, - ) -> U256 { + ) -> Result { match parent_gas_used.cmp(&parent_gas_target) { - Ordering::Equal => parent_base_fee, + Ordering::Equal => Ok(parent_base_fee), Ordering::Greater => { let gas_used_delta = parent_gas_used - parent_gas_target; - let base_fee_per_gas_delta = max( - parent_base_fee * gas_used_delta - / parent_gas_target - / base_fee_max_change_denominator, - U256::one(), - ); - - max(parent_base_fee + base_fee_per_gas_delta, initial_base_fee) + let base_fee_per_gas_delta = self.get_base_fee_per_gas_delta( + gas_used_delta, + parent_gas_target, + parent_base_fee, + base_fee_max_change_denominator, + )?; + Ok(max( + parent_base_fee + base_fee_per_gas_delta, + initial_base_fee, + )) } Ordering::Less => { let gas_used_delta = parent_gas_target - parent_gas_used; - let base_fee_per_gas_delta = parent_base_fee * gas_used_delta - / parent_gas_target - / base_fee_max_change_denominator; - - max(parent_base_fee - base_fee_per_gas_delta, initial_base_fee) + let base_fee_per_gas_delta = self.get_base_fee_per_gas_delta( + gas_used_delta, + parent_gas_target, + parent_base_fee, + base_fee_max_change_denominator, + )?; + Ok(max( + parent_base_fee - base_fee_per_gas_delta, + initial_base_fee, + )) } } } + fn get_base_fee_per_gas_delta( + &self, + gas_used_delta: u64, + parent_gas_target: u64, + parent_base_fee: U256, + base_fee_max_change_denominator: U256, + ) -> Result { + Ok(max( + parent_base_fee + .checked_mul(gas_used_delta.into()) + .and_then(|x| x.checked_div(parent_gas_target.into())) + .and_then(|x| x.checked_div(base_fee_max_change_denominator)) + .ok_or_else(|| { + format_err!("Unsatisfied bounds calculating base_fee_per_gas_delta") + })?, + U256::one(), + )) + } + pub fn get_base_fee( &self, parent_gas_used: u64, @@ -108,7 +134,7 @@ impl BlockService { parent_base_fee: U256, base_fee_max_change_denominator: U256, initial_base_fee: U256, - ) -> U256 { + ) -> Result { self.base_fee_calculation( parent_gas_used, parent_gas_target, @@ -135,17 +161,17 @@ impl BlockService { .get_block_by_hash(&parent_hash)? .ok_or(format_err!("Parent block not found"))?; let parent_base_fee = parent_block.header.base_fee; - let parent_gas_used = parent_block.header.gas_used.as_u64(); + let parent_gas_used = u64::try_from(parent_block.header.gas_used)?; let parent_gas_target = - parent_block.header.gas_limit.as_u64() / elasticity_multiplier.as_u64(); + u64::try_from(parent_block.header.gas_limit / elasticity_multiplier)?; // safe to use normal division since we know elasticity_multiplier is non-zero - Ok(self.get_base_fee( + self.get_base_fee( parent_gas_used, parent_gas_target, parent_base_fee, base_fee_max_change_denominator, INITIAL_BASE_FEE, - )) + ) } pub fn calculate_next_block_base_fee(&self) -> Result { @@ -180,21 +206,25 @@ impl BlockService { let oldest_block = blocks.last().unwrap().header.number; - let (mut base_fee_per_gas, mut gas_used_ratio): (Vec, Vec) = blocks - .iter() - .map(|block| { + let (mut base_fee_per_gas, mut gas_used_ratio) = blocks.iter().try_fold( + (Vec::new(), Vec::new()), + |(mut base_fee_per_gas, mut gas_used_ratio), block| { trace!("[fee_history] Processing block {}", block.header.number); let base_fee = block.header.base_fee; let gas_ratio = if block.header.gas_limit == U256::zero() { f64::default() // empty block } else { - block.header.gas_used.as_u64() as f64 / block.header.gas_limit.as_u64() as f64 + u64::try_from(block.header.gas_used)? as f64 + / u64::try_from(block.header.gas_limit)? as f64 }; - (base_fee, gas_ratio) - }) - .unzip(); + base_fee_per_gas.push(base_fee); + gas_used_ratio.push(gas_ratio); + + Ok::<_, EVMError>((base_fee_per_gas, gas_used_ratio)) + }, + )?; let reward = if priority_fee_percentile.is_empty() { None @@ -235,8 +265,8 @@ impl BlockService { let mut block_rewards = Vec::new(); let priority_fees = block_eip_tx .iter() - .map(|tx| tx.max_priority_fee_per_gas.as_u64() as f64) - .collect::>(); + .map(|tx| Ok(u64::try_from(tx.max_priority_fee_per_gas)? as f64)) + .collect::>>()?; let mut data = Data::new(priority_fees); for pct in &priority_fee_percentile { @@ -317,7 +347,7 @@ impl BlockService { continue; } TransactionAny::EIP1559(t) => { - priority_fees.push(t.max_priority_fee_per_gas.as_u64() as f64); + priority_fees.push(u64::try_from(t.max_priority_fee_per_gas)? as f64); } } } diff --git a/lib/ain-evm/src/core.rs b/lib/ain-evm/src/core.rs index edae8d53e7..d7ba3c7fe4 100644 --- a/lib/ain-evm/src/core.rs +++ b/lib/ain-evm/src/core.rs @@ -220,7 +220,7 @@ impl EVMCoreService { parent_hash: genesis.parent_hash.unwrap_or_default(), mix_hash: genesis.mix_hash.unwrap_or_default(), nonce: genesis.nonce.unwrap_or_default(), - timestamp: genesis.timestamp.unwrap_or_default().as_u64(), + timestamp: u64::try_from(genesis.timestamp.unwrap_or_default())?, difficulty: genesis.difficulty.unwrap_or_default(), base_fee: genesis.base_fee.unwrap_or(INITIAL_BASE_FEE), }, diff --git a/lib/ain-evm/src/gas.rs b/lib/ain-evm/src/gas.rs index 7c1470b7a9..5a6dce3b15 100644 --- a/lib/ain-evm/src/gas.rs +++ b/lib/ain-evm/src/gas.rs @@ -23,7 +23,7 @@ fn get_tx_cost(signed_tx: &SignedTx) -> TransactionCost { pub fn check_tx_intrinsic_gas(signed_tx: &SignedTx) -> Result<()> { const CONFIG: Config = Config::shanghai(); - let mut gasometer = Gasometer::new(signed_tx.gas_limit().as_u64(), &CONFIG); + let mut gasometer = Gasometer::new(u64::try_from(signed_tx.gas_limit())?, &CONFIG); let tx_cost = get_tx_cost(signed_tx); match gasometer.record_transaction(tx_cost) { diff --git a/lib/ain-evm/src/storage/block_store.rs b/lib/ain-evm/src/storage/block_store.rs index eda2b6845a..5ef99c52e7 100644 --- a/lib/ain-evm/src/storage/block_store.rs +++ b/lib/ain-evm/src/storage/block_store.rs @@ -243,7 +243,7 @@ impl BlockStore { .or(U256::from_str_radix(s, 16)) .unwrap_or_else(|_| U256::zero()) }; - let s_to_h256 = |s: &str| H256::from_str(&s).unwrap_or(H256::zero()); + let s_to_h256 = |s: &str| H256::from_str(s).unwrap_or(H256::zero()); match arg { DumpArg::All => { diff --git a/lib/ain-evm/src/storage/db.rs b/lib/ain-evm/src/storage/db.rs index 15c9214165..3184844360 100644 --- a/lib/ain-evm/src/storage/db.rs +++ b/lib/ain-evm/src/storage/db.rs @@ -388,7 +388,6 @@ where }); self.backend .iterator_cf::(self.handle(), iterator_mode) - .into_iter() .filter_map(|k| { k.ok().and_then(|(k, v)| { let value = bincode::deserialize(&v).ok()?; diff --git a/lib/ain-grpc/src/rpc/eth.rs b/lib/ain-grpc/src/rpc/eth.rs index 1f41e7ca41..1240e117f4 100644 --- a/lib/ain-grpc/src/rpc/eth.rs +++ b/lib/ain-grpc/src/rpc/eth.rs @@ -336,6 +336,10 @@ impl MetachainRPCServer for MetachainRPCModule { .get_attributes_or_default() .map_err(to_jsonrpsee_custom_error)? .block_gas_limit; + let gas_limit = gas + .unwrap_or(U256::from(max_gas_per_block)) + .try_into() + .map_err(to_jsonrpsee_custom_error)?; let TxResponse { data, .. } = self .handler .core @@ -350,7 +354,7 @@ impl MetachainRPCServer for MetachainRPCModule { data: &input .map(|d| d.0) .unwrap_or(data.map(|d| d.0).unwrap_or_default()), - gas_limit: gas.unwrap_or(U256::from(max_gas_per_block)).as_u64(), + gas_limit, gas_price, max_fee_per_gas, access_list: access_list.unwrap_or_default(), @@ -539,7 +543,10 @@ impl MetachainRPCServer for MetachainRPCModule { ) -> RpcResult> { self.handler .storage - .get_transaction_by_block_hash_and_index(&hash, index.as_usize()) + .get_transaction_by_block_hash_and_index( + &hash, + index.try_into().map_err(to_jsonrpsee_custom_error)?, + ) .map_err(to_jsonrpsee_custom_error)? .map_or(Ok(None), |tx| { let tx_hash = &tx.hash(); @@ -572,7 +579,10 @@ impl MetachainRPCServer for MetachainRPCModule { ) -> RpcResult> { self.handler .storage - .get_transaction_by_block_number_and_index(&number, index.as_usize()) + .get_transaction_by_block_number_and_index( + &number, + index.try_into().map_err(to_jsonrpsee_custom_error)?, + ) .map_err(to_jsonrpsee_custom_error)? .map_or(Ok(None), |tx| { let tx_hash = &tx.hash(); @@ -808,6 +818,11 @@ impl MetachainRPCServer for MetachainRPCModule { .get_attributes_or_default() .map_err(to_jsonrpsee_custom_error)? .block_gas_limit; + let gas_limit = gas + .unwrap_or(U256::from(gas_limit)) + .try_into() + .map_err(to_jsonrpsee_custom_error)?; + let TxResponse { used_gas, .. } = self .handler .core @@ -816,7 +831,7 @@ impl MetachainRPCServer for MetachainRPCModule { to, value: value.unwrap_or_default(), data: &data.map(|d| d.0).unwrap_or_default(), - gas_limit: gas.unwrap_or(U256::from(gas_limit)).as_u64(), + gas_limit, gas_price, max_fee_per_gas, access_list: access_list.unwrap_or_default(), @@ -870,14 +885,11 @@ impl MetachainRPCServer for MetachainRPCModule { priority_fee_percentile: Vec, ) -> RpcResult { let first_block_number = self.block_number_to_u256(Some(first_block))?; + let block_count = block_count.try_into().map_err(to_jsonrpsee_custom_error)?; let fee_history = self .handler .block - .fee_history( - block_count.as_usize(), - first_block_number, - priority_fee_percentile, - ) + .fee_history(block_count, first_block_number, priority_fee_percentile) .map_err(|e| Error::Custom(format!("{e:?}")))?; Ok(RpcFeeHistory::from(fee_history)) @@ -1027,10 +1039,8 @@ impl MetachainRPCServer for MetachainRPCModule { } fn get_filter_changes(&self, filter_id: U256) -> RpcResult { - let filter = self - .handler - .filters - .get_filter(filter_id.as_usize()) + let filter = usize::try_from(filter_id) + .and_then(|id| self.handler.filters.get_filter(id)) .map_err(to_jsonrpsee_custom_error)?; let res = match filter { @@ -1054,23 +1064,24 @@ impl MetachainRPCServer for MetachainRPCModule { .map(LogResult::from) .collect(); - self.handler - .filters - .update_last_block(filter_id.as_usize(), current_block_height) + usize::try_from(filter_id) + .and_then(|id| { + self.handler + .filters + .update_last_block(id, current_block_height) + }) .map_err(to_jsonrpsee_custom_error)?; GetFilterChangesResult::Logs(logs) } Filter::NewBlock(_) => GetFilterChangesResult::NewBlock( - self.handler - .filters - .get_entries_from_filter(filter_id.as_usize()) + usize::try_from(filter_id) + .and_then(|id| self.handler.filters.get_entries_from_filter(id)) .map_err(to_jsonrpsee_custom_error)?, ), Filter::NewPendingTransactions(_) => GetFilterChangesResult::NewPendingTransactions( - self.handler - .filters - .get_entries_from_filter(filter_id.as_usize()) + usize::try_from(filter_id) + .and_then(|id| self.handler.filters.get_entries_from_filter(id)) .map_err(to_jsonrpsee_custom_error)?, ), }; @@ -1079,14 +1090,14 @@ impl MetachainRPCServer for MetachainRPCModule { } fn uninstall_filter(&self, filter_id: U256) -> RpcResult { - Ok(self.handler.filters.delete_filter(filter_id.as_usize())) + let filter_id = usize::try_from(filter_id).map_err(to_jsonrpsee_custom_error)?; + + Ok(self.handler.filters.delete_filter(filter_id)) } fn get_filter_logs(&self, filter_id: U256) -> RpcResult> { - let filter = self - .handler - .filters - .get_filter(filter_id.as_usize()) + let filter = usize::try_from(filter_id) + .and_then(|id| self.handler.filters.get_filter(id)) .map_err(to_jsonrpsee_custom_error)?; match filter { diff --git a/lib/ain-rs-exports/src/evm.rs b/lib/ain-rs-exports/src/evm.rs index ca1f601eaf..7b8c85c31a 100644 --- a/lib/ain-rs-exports/src/evm.rs +++ b/lib/ain-rs-exports/src/evm.rs @@ -509,7 +509,7 @@ fn unsafe_construct_block_in_q( failed_transactions, total_burnt_fees, total_priority_fees, - block_number: block_number.as_u64(), + block_number: u64::try_from(block_number)?, }) } } @@ -829,7 +829,7 @@ fn get_tx_hash(raw_tx: &str) -> Result { #[ffi_fallible] fn unsafe_get_target_block_in_q(queue_id: u64) -> Result { let target_block = unsafe { SERVICES.evm.core.get_target_block_in(queue_id)? }; - Ok(target_block.as_u64()) + Ok(u64::try_from(target_block)?) } /// Checks if the given address is a smart contract