Skip to content

Commit

Permalink
refactor!: change many U256 type to U64 (#1591)
Browse files Browse the repository at this point in the history
* refactor: change many U256 type to U64
* change some safe as_u64 to low_u64 & cargo fmt
* refactor the gas price and limit check
* refactor prepay gas calculation
* revert max gas limit
* fix e2e test
* Update eth_getBalance.test.js
* remove useless code

This PR is substitute for #1539

Some mainly changes:
* Change the type of `nonce` from `U256` to `U64` according to the [EIP-2681](https://eips.ethereum.org/EIPS/eip-2681) limit the account nonce to be between `0` and `2^64-1`.
 * Change the type of `gas_limit` from `U256` to `U64`. According to the current gas cost of the most complex ethereum transaction is on the order of million, `U64` is enough.
* Change the type of `chain_id` from `U256` to `U64` according to  [metamask limit](https://gist.github.com/rekmarks/a47bd5f2525936c4b8eee31a16345553). The [`ChainId` opcode](https://eips.ethereum.org/EIPS/eip-1344) returns a 256-bit value, so it should not larger than `U256::MAX / 2 - 35`.This issue does not lead to consensus in Ethereum community, however,  I think limit the max chain ID to `4503599627370476` is enough currently. Many temporary L2/L3 need a unique chain ID is the demand of variable-lenght chain ID in foreseeable future. But we do not have the demand now. If the day comes, we can change the chain ID type to `U256` even without hardfork.
* Set the [`Default Max Price`](https://github.com/ethereum/go-ethereum/blob/be65b47/eth/gasprice/gasprice.go#L38) as `500` Gwei that is same as go-ethereum. Meanwhile, change the type of `gas_price` from `U256` to `U64`.

---------

Co-authored-by: sunchengzhu <[email protected]>
Co-authored-by: Flouse <[email protected]>
  • Loading branch information
3 people authored Dec 4, 2023
1 parent 05a124d commit b90612d
Show file tree
Hide file tree
Showing 45 changed files with 300 additions and 265 deletions.
5 changes: 3 additions & 2 deletions common/config-parser/src/types/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ use common_crypto::Secp256k1RecoverablePrivateKey;
use protocol::{
codec::{decode_256bits_key, deserialize_address},
types::{
HardforkInfoInner, Header, Key256Bits, Metadata, H160, H256, RLP_EMPTY_LIST, RLP_NULL, U256,
HardforkInfoInner, Header, Key256Bits, Metadata, H160, H256, RLP_EMPTY_LIST, RLP_NULL,
U256, U64,
},
};

Expand All @@ -36,7 +37,7 @@ pub struct ChainSpec {
pub struct Genesis {
pub timestamp: u64,
pub hardforks: Vec<HardforkName>,
pub base_fee_per_gas: U256,
pub base_fee_per_gas: U64,
pub chain_id: u64,
}

Expand Down
17 changes: 10 additions & 7 deletions core/api/src/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ use protocol::trie::Trie as _;
use protocol::types::{
Account, BigEndianHash, Block, BlockNumber, Bytes, CkbRelatedInfo, EthAccountProof,
EthStorageProof, ExecutorContext, HardforkInfo, HardforkInfoInner, Hash, Header, Hex, Metadata,
Proposal, Receipt, SignedTransaction, TxResp, H160, H256, MAX_BLOCK_GAS_LIMIT, NIL_DATA,
RLP_NULL, U256,
Proposal, Receipt, SignedTransaction, TxResp, H160, H256, NIL_DATA, RLP_NULL, U256, U64,
};
use protocol::{
async_trait, codec::ProtocolCodec, constants::MAX_BLOCK_GAS_LIMIT, trie, ProtocolResult,
};
use protocol::{async_trait, codec::ProtocolCodec, trie, ProtocolResult};

use core_executor::{
system_contract::metadata::MetadataHandle, AxonExecutor, AxonExecutorReadOnlyAdapter, MPTTrie,
Expand Down Expand Up @@ -193,8 +194,8 @@ where
_ctx: Context,
from: Option<H160>,
to: Option<H160>,
gas_price: Option<U256>,
gas_limit: Option<U256>,
gas_price: Option<U64>,
gas_limit: Option<U64>,
value: U256,
data: Vec<u8>,
estimate: bool,
Expand All @@ -203,7 +204,9 @@ where
) -> ProtocolResult<TxResp> {
let mut exec_ctx = ExecutorContext::from(mock_header);
exec_ctx.origin = from.unwrap_or_default();
exec_ctx.gas_price = gas_price.unwrap_or_else(U256::one);
exec_ctx.gas_price = gas_price
.map(|p| U256::from(p.low_u64()))
.unwrap_or_else(U256::one);

let backend = AxonExecutorReadOnlyAdapter::from_root(
state_root,
Expand All @@ -212,7 +215,7 @@ where
exec_ctx,
)?;
let gas_limit = gas_limit
.map(|gas| gas.as_u64())
.map(|gas| gas.low_u64())
.unwrap_or(MAX_BLOCK_GAS_LIMIT);

Ok(AxonExecutor.call(&backend, gas_limit, from, to, value, data, estimate))
Expand Down
4 changes: 2 additions & 2 deletions core/api/src/jsonrpc/impl/axon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl<Adapter: APIAdapter + 'static> AxonRpcServer for AxonRpcImpl<Adapter> {
BlockId::Hash(hash) => self.adapter.get_block_by_hash(Context::new(), hash).await,
BlockId::Num(num) => {
self.adapter
.get_block_by_number(Context::new(), Some(num.as_u64()))
.get_block_by_number(Context::new(), Some(num.low_u64()))
.await
}
BlockId::Latest => self.adapter.get_block_by_number(Context::new(), None).await,
Expand All @@ -52,7 +52,7 @@ impl<Adapter: APIAdapter + 'static> AxonRpcServer for AxonRpcImpl<Adapter> {
async fn get_metadata_by_number(&self, block_number: U256) -> RpcResult<Metadata> {
let ret = self
.adapter
.get_metadata_by_number(Context::new(), Some(block_number.as_u64()))
.get_metadata_by_number(Context::new(), Some(block_number.low_u64()))
.await
.map_err(|e| RpcError::Internal(e.to_string()))?;

Expand Down
4 changes: 2 additions & 2 deletions core/api/src/jsonrpc/impl/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ where

match from {
BlockId::Num(n) => {
if n.as_u64() < header.number {
if n.low_u64() < header.number {
filter.from_block = Some(BlockId::Num(U64::from(header.number + 1)));
}
}
Expand Down Expand Up @@ -302,7 +302,7 @@ where
let (start, end) = {
let convert = |id: &BlockId| -> BlockNumber {
match id {
BlockId::Num(n) => n.as_u64(),
BlockId::Num(n) => n.low_u64(),
BlockId::Earliest => 0,
_ => latest_number,
}
Expand Down
66 changes: 35 additions & 31 deletions core/api/src/jsonrpc/impl/web3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ use jsonrpsee::core::RpcResult;

use common_apm::metrics_rpc;
use core_executor::is_system_contract_address_format;
use protocol::constants::{
BASE_FEE_PER_GAS, MAX_FEE_HISTORY, MAX_GAS_LIMIT, MAX_GAS_PRICE, MEMPOOL_REFRESH_TIMEOUT,
MIN_TRANSACTION_GAS_LIMIT,
};
use protocol::traits::{APIAdapter, Context};
use protocol::types::{
Block, BlockNumber, Bytes, EthAccountProof, Hash, Header, Hex, Proposal, Receipt,
SignedTransaction, TxResp, UnverifiedTransaction, BASE_FEE_PER_GAS, H160, H256,
MAX_FEE_HISTORY, MAX_RPC_GAS_CAP, MIN_TRANSACTION_GAS_LIMIT, U256, U64,
SignedTransaction, TxResp, UnverifiedTransaction, H160, H256, U256, U64,
};
use protocol::{
async_trait, codec::ProtocolCodec, lazy::PROTOCOL_VERSION, tokio::time::sleep, ProtocolResult,
MEMPOOL_REFRESH_TIMEOUT,
};

use crate::jsonrpc::web3_types::{
Expand All @@ -27,7 +29,7 @@ pub(crate) const MAX_LOG_NUM: usize = 10000;

pub struct Web3RpcImpl<Adapter> {
adapter: Arc<Adapter>,
max_gas_cap: U256,
max_gas_cap: U64,
log_filter_max_block_range: u64,
}

Expand Down Expand Up @@ -92,36 +94,36 @@ impl<Adapter: APIAdapter> Web3RpcImpl<Adapter> {
async fn calculate_rewards(
&self,
block_number: u64,
base_fee_par_gas: U256,
base_fee_par_gas: U64,
txs: Vec<H256>,
reward_percentiles: Vec<f64>,
reward: &mut Vec<Vec<U256>>,
reward: &mut Vec<Vec<U64>>,
) -> Result<(), RpcError> {
let receipts = self
.adapter
.get_receipts_by_hashes(Context::new(), block_number, &txs)
.await
.map_err(|e| RpcError::Internal(e.to_string()))?;

let effective_priority_fees: Vec<U256> = receipts
let effective_priority_fees: Vec<U64> = receipts
.iter()
.map(|receipt| {
receipt
.as_ref()
.map(|r| r.used_gas.saturating_sub(base_fee_par_gas))
.unwrap_or(U256::zero())
.unwrap_or(U64::zero())
})
.collect();

let reward_vec: Vec<U256> = reward_percentiles
let reward_vec: Vec<U64> = reward_percentiles
.iter()
.map(|percentile| {
let index =
calculate_effective_priority_fees_index(percentile, &effective_priority_fees);
effective_priority_fees
.get(index)
.cloned()
.unwrap_or(U256::zero())
.unwrap_or(U64::zero())
})
.collect();

Expand All @@ -135,7 +137,7 @@ impl<Adapter: APIAdapter> Web3RpcImpl<Adapter> {
height: Option<u64>,
block_count: U256,
reward_percentiles: &Option<Vec<f64>>,
) -> Result<(u64, Vec<U256>, Vec<f64>, Vec<Vec<U256>>), RpcError> {
) -> Result<(u64, Vec<U64>, Vec<f64>, Vec<Vec<U64>>), RpcError> {
let latest_block = self
.adapter
.get_block_by_number(Context::new(), height)
Expand All @@ -148,9 +150,9 @@ impl<Adapter: APIAdapter> Web3RpcImpl<Adapter> {
.saturating_sub(block_count.as_u64())
.saturating_add(1);

let mut bash_fee_per_gases: Vec<U256> = Vec::new();
let mut bash_fee_per_gases: Vec<U64> = Vec::new();
let mut gas_used_ratios: Vec<f64> = Vec::new();
let mut reward: Vec<Vec<U256>> = Vec::new();
let mut reward: Vec<Vec<U64>> = Vec::new();

for i in oldest_block_number..=latest_block_number {
let block = match self
Expand Down Expand Up @@ -198,11 +200,11 @@ impl<Adapter: APIAdapter + 'static> Web3RpcServer for Web3RpcImpl<Adapter> {

let gas_price = utx.unsigned.gas_price();

if gas_price == U256::zero() {
if gas_price == U64::zero() {
return Err(RpcError::GasPriceIsZero.into());
}

if gas_price >= U256::from(u64::MAX) {
if gas_price > MAX_GAS_PRICE {
return Err(RpcError::GasPriceIsTooLarge.into());
}

Expand Down Expand Up @@ -414,12 +416,12 @@ impl<Adapter: APIAdapter + 'static> Web3RpcServer for Web3RpcImpl<Adapter> {

#[metrics_rpc("eth_call")]
async fn call(&self, req: Web3CallRequest, block_id: Option<BlockId>) -> RpcResult<Hex> {
if req.gas_price.unwrap_or_default() > U256::from(u64::MAX) {
if req.gas.unwrap_or_default() > MAX_GAS_LIMIT.into() {
return Err(RpcError::GasLimitIsTooLarge.into());
}

if req.gas.unwrap_or_default() > U256::from(MAX_RPC_GAS_CAP) {
return Err(RpcError::GasLimitIsTooLarge.into());
if req.gas_price.unwrap_or_default() > MAX_GAS_PRICE {
return Err(RpcError::GasPriceIsTooLarge.into());
}

if let Some(call_addr) = req.to {
Expand Down Expand Up @@ -451,15 +453,17 @@ impl<Adapter: APIAdapter + 'static> Web3RpcServer for Web3RpcImpl<Adapter> {
#[metrics_rpc("eth_estimateGas")]
async fn estimate_gas(&self, req: Web3CallRequest, number: Option<BlockId>) -> RpcResult<U256> {
if let Some(gas_limit) = req.gas.as_ref() {
if gas_limit == &U256::zero() {
if gas_limit == &U64::zero() {
return Err(RpcError::GasPriceIsZero.into());
}
}

if let Some(price) = req.gas_price.as_ref() {
if price >= &U256::from(u64::MAX) {
return Err(RpcError::GasPriceIsTooLarge.into());
}
if req.gas.unwrap_or_default() > MAX_GAS_LIMIT.into() {
return Err(RpcError::GasLimitIsTooLarge.into());
}

if req.gas_price.unwrap_or_default() > MAX_GAS_PRICE {
return Err(RpcError::GasPriceIsTooLarge.into());
}

if let Some(call_addr) = req.to {
Expand All @@ -469,7 +473,7 @@ impl<Adapter: APIAdapter + 'static> Web3RpcServer for Web3RpcImpl<Adapter> {
}

let num = match number {
Some(BlockId::Num(n)) => Some(n.as_u64()),
Some(BlockId::Num(n)) => Some(n.low_u64()),
_ => None,
};
let data_bytes = req
Expand Down Expand Up @@ -688,7 +692,7 @@ impl<Adapter: APIAdapter + 'static> Web3RpcServer for Web3RpcImpl<Adapter> {
let (start, end) = {
let convert = |id: BlockId| -> BlockNumber {
match id {
BlockId::Num(n) => n.as_u64(),
BlockId::Num(n) => n.low_u64(),
BlockId::Earliest => 0,
_ => latest_number,
}
Expand Down Expand Up @@ -780,7 +784,7 @@ impl<Adapter: APIAdapter + 'static> Web3RpcServer for Web3RpcImpl<Adapter> {
match newest_block {
BlockId::Num(number) => {
let (oldest_block_number, bash_fee_per_gases, gas_used_ratios, reward) = self
.inner_fee_history(number.as_u64().into(), blocks_count, &reward_percentiles)
.inner_fee_history(number.low_u64().into(), blocks_count, &reward_percentiles)
.await?;

match reward_percentiles {
Expand Down Expand Up @@ -861,7 +865,7 @@ impl<Adapter: APIAdapter + 'static> Web3RpcServer for Web3RpcImpl<Adapter> {
gas_used_ratio,
}));
}
let mut reward: Vec<Vec<U256>> = Vec::new();
let mut reward: Vec<Vec<U64>> = Vec::new();
self.calculate_rewards(
first_block.header.number,
first_block.header.base_fee_per_gas,
Expand Down Expand Up @@ -1064,9 +1068,9 @@ fn check_reward_percentiles(reward_percentiles: &Option<Vec<f64>>) -> RpcResult<

// Calculates the gas used ratio for the block.
fn calculate_gas_used_ratio(block: &Block) -> f64 {
(block.header.gas_limit != U256::zero())
(block.header.gas_limit != U64::zero())
.then(|| {
block.header.gas_used.as_u64() as f64 / block.header.gas_limit.as_u64() as f64 * 100f64
block.header.gas_used.low_u64() as f64 / block.header.gas_limit.as_u64() as f64 * 100f64
})
.unwrap_or(0f64)
}
Expand All @@ -1075,14 +1079,14 @@ fn calculate_gas_used_ratio(block: &Block) -> f64 {
// vector.
fn calculate_effective_priority_fees_index(
percentile: &f64,
effective_priority_fees: &Vec<U256>,
effective_priority_fees: &Vec<U64>,
) -> usize {
((percentile * effective_priority_fees.len() as f64 / 100f64).floor() as usize)
.saturating_sub(1)
}

// Get the base fee per gas for the next block.
fn next_block_base_fee_per_gas() -> U256 {
fn next_block_base_fee_per_gas() -> U64 {
BASE_FEE_PER_GAS.into()
}

Expand Down
Loading

0 comments on commit b90612d

Please sign in to comment.