fix(rpc): fallback to basefee when calculating fee fields (#1800)

Co-authored-by: Georgios Konstantopoulos <me@gakonst.com>
This commit is contained in:
Matthias Seitz
2023-03-17 00:50:33 +01:00
committed by GitHub
parent 7f5ac990eb
commit 090bbe7836
3 changed files with 30 additions and 25 deletions

View File

@@ -1,4 +1,4 @@
use reth_primitives::{AccessList, Address, Bytes, U128, U256, U64};
use reth_primitives::{AccessList, Address, Bytes, U256, U64};
use serde::{Deserialize, Serialize};
/// Call request
@@ -10,11 +10,11 @@ pub struct CallRequest {
/// To
pub to: Option<Address>,
/// Gas Price
pub gas_price: Option<U128>,
pub gas_price: Option<U256>,
/// EIP-1559 Max base fee the caller is willing to pay
pub max_fee_per_gas: Option<U128>,
pub max_fee_per_gas: Option<U256>,
/// EIP-1559 Priority fee the caller is paying to the block author
pub max_priority_fee_per_gas: Option<U128>,
pub max_priority_fee_per_gas: Option<U256>,
/// Gas
pub gas: Option<U256>,
/// Value

View File

@@ -2,7 +2,7 @@
use crate::result::{internal_rpc_err, rpc_err};
use jsonrpsee::{core::Error as RpcError, types::error::INVALID_PARAMS_CODE};
use reth_primitives::{constants::SELECTOR_LEN, Address, Bytes, U128, U256};
use reth_primitives::{constants::SELECTOR_LEN, Address, Bytes, U256};
use reth_rpc_types::{error::EthRpcErrorCode, BlockError};
use reth_transaction_pool::error::{InvalidPoolTransactionError, PoolError};
use revm::primitives::{EVMError, ExecutionResult, Halt, OutOfGasError, Output};
@@ -31,15 +31,15 @@ pub enum EthApiError {
#[error("Prevrandao not in th EVM's environment after merge")]
PrevrandaoNotSet,
#[error("Conflicting fee values in request. Both legacy gasPrice {gas_price} and maxFeePerGas {max_fee_per_gas} set")]
ConflictingRequestGasPrice { gas_price: U128, max_fee_per_gas: U128 },
ConflictingRequestGasPrice { gas_price: U256, max_fee_per_gas: U256 },
#[error("Conflicting fee values in request. Both legacy gasPrice {gas_price} maxFeePerGas {max_fee_per_gas} and maxPriorityFeePerGas {max_priority_fee_per_gas} set")]
ConflictingRequestGasPriceAndTipSet {
gas_price: U128,
max_fee_per_gas: U128,
max_priority_fee_per_gas: U128,
gas_price: U256,
max_fee_per_gas: U256,
max_priority_fee_per_gas: U256,
},
#[error("Conflicting fee values in request. Legacy gasPrice {gas_price} and maxPriorityFeePerGas {max_priority_fee_per_gas} set")]
RequestLegacyGasPriceAndTipSet { gas_price: U128, max_priority_fee_per_gas: U128 },
RequestLegacyGasPriceAndTipSet { gas_price: U256, max_priority_fee_per_gas: U256 },
#[error(transparent)]
InvalidTransaction(#[from] InvalidTransactionError),
/// Thrown when constructing an RPC block from a primitive block data failed.

View File

@@ -1,7 +1,7 @@
//! utilities for working with revm
use crate::eth::error::{EthApiError, EthResult, InvalidTransactionError};
use reth_primitives::{AccessList, Address, U128, U256};
use reth_primitives::{AccessList, Address, U256};
use reth_rpc_types::CallRequest;
use revm::{
precompile::{Precompiles, SpecId as PrecompilesSpecId},
@@ -83,8 +83,12 @@ pub(crate) fn create_txn_env(block_env: &BlockEnv, request: CallRequest) -> EthR
chain_id,
} = request;
let CallFees { max_priority_fee_per_gas, gas_price } =
CallFees::ensure_fees(gas_price, max_fee_per_gas, max_priority_fee_per_gas)?;
let CallFees { max_priority_fee_per_gas, gas_price } = CallFees::ensure_fees(
gas_price,
max_fee_per_gas,
max_priority_fee_per_gas,
block_env.basefee,
)?;
let gas_limit = gas.unwrap_or(block_env.gas_limit.min(U256::from(u64::MAX)));
@@ -112,7 +116,7 @@ pub(crate) struct CallFees {
max_priority_fee_per_gas: Option<U256>,
/// Unified gas price setting
///
/// Will be `0` if unset in request
/// Will be the configured `basefee` if unset in the request
///
/// `gasPrice` for legacy,
/// `maxFeePerGas` for EIP-1559
@@ -122,22 +126,26 @@ pub(crate) struct CallFees {
// === impl CallFees ===
impl CallFees {
/// Ensures the fields of a [CallRequest] are not conflicting
/// Ensures the fields of a [CallRequest] are not conflicting.
///
/// If no `gasPrice` or `maxFeePerGas` is set, then the `gas_price` in the response will
/// fallback to the given `basefee`.
fn ensure_fees(
call_gas_price: Option<U128>,
call_max_fee: Option<U128>,
call_priority_fee: Option<U128>,
call_gas_price: Option<U256>,
call_max_fee: Option<U256>,
call_priority_fee: Option<U256>,
base_fee: U256,
) -> EthResult<CallFees> {
match (call_gas_price, call_max_fee, call_priority_fee) {
(gas_price, None, None) => {
// request for a legacy transaction
// set everything to zero
let gas_price = gas_price.unwrap_or_default();
Ok(CallFees { gas_price: U256::from(gas_price), max_priority_fee_per_gas: None })
let gas_price = gas_price.unwrap_or(base_fee);
Ok(CallFees { gas_price, max_priority_fee_per_gas: None })
}
(None, max_fee_per_gas, max_priority_fee_per_gas) => {
// request for eip-1559 transaction
let max_fee = max_fee_per_gas.unwrap_or_default();
let max_fee = max_fee_per_gas.unwrap_or(base_fee);
if let Some(max_priority) = max_priority_fee_per_gas {
if max_priority > max_fee {
@@ -148,10 +156,7 @@ impl CallFees {
)
}
}
Ok(CallFees {
gas_price: U256::from(max_fee),
max_priority_fee_per_gas: max_priority_fee_per_gas.map(U256::from),
})
Ok(CallFees { gas_price: max_fee, max_priority_fee_per_gas })
}
(Some(gas_price), Some(max_fee_per_gas), Some(max_priority_fee_per_gas)) => {
Err(EthApiError::ConflictingRequestGasPriceAndTipSet {