Skip to content

Commit

Permalink
feat(rpc): add impls for gasprice and max priority fee
Browse files Browse the repository at this point in the history
  • Loading branch information
mattsse committed Apr 29, 2023
1 parent ebf13ec commit d270c85
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 25 deletions.
6 changes: 6 additions & 0 deletions crates/primitives/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ impl SealedBlock {
}
}

impl From<SealedBlock> for Block {
fn from(block: SealedBlock) -> Self {
block.unseal()
}
}

impl Deref for SealedBlock {
type Target = SealedHeader;
fn deref(&self) -> &Self::Target {
Expand Down
8 changes: 4 additions & 4 deletions crates/rpc/rpc-api/src/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ pub trait EthApi {
#[method(name = "eth_gasPrice")]
async fn gas_price(&self) -> Result<U256>;

/// Introduced in EIP-1159, returns suggestion for the priority for dynamic fee transactions.
#[method(name = "eth_maxPriorityFeePerGas")]
async fn max_priority_fee_per_gas(&self) -> Result<U256>;

/// Returns the Transaction fee history
///
/// Introduced in EIP-1159 for getting information on the appropriate priority fee to use.
Expand All @@ -191,10 +195,6 @@ pub trait EthApi {
reward_percentiles: Option<Vec<f64>>,
) -> Result<FeeHistory>;

/// Returns the current maxPriorityFeePerGas per gas in wei.
#[method(name = "eth_maxPriorityFeePerGas")]
async fn max_priority_fee_per_gas(&self) -> Result<U256>;

/// Returns whether the client is actively mining new blocks.
#[method(name = "eth_mining")]
async fn is_mining(&self) -> Result<bool>;
Expand Down
4 changes: 2 additions & 2 deletions crates/rpc/rpc-builder/tests/it/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,14 @@ where
EthApiClient::send_transaction(client, transaction_request).await.unwrap_err();
EthApiClient::hashrate(client).await.unwrap();
EthApiClient::submit_hashrate(client, U256::default(), H256::default()).await.unwrap();
EthApiClient::gas_price(client).await.unwrap();
EthApiClient::max_priority_fee_per_gas(client).await.unwrap();

// Unimplemented
assert!(is_unimplemented(
EthApiClient::get_proof(client, address, vec![], None).await.err().unwrap()
));
assert!(is_unimplemented(EthApiClient::author(client).await.err().unwrap()));
assert!(is_unimplemented(EthApiClient::gas_price(client).await.err().unwrap()));
assert!(is_unimplemented(EthApiClient::max_priority_fee_per_gas(client).await.err().unwrap()));
assert!(is_unimplemented(EthApiClient::is_mining(client).await.err().unwrap()));
assert!(is_unimplemented(EthApiClient::get_work(client).await.err().unwrap()));
assert!(is_unimplemented(
Expand Down
36 changes: 26 additions & 10 deletions crates/rpc/rpc/src/eth/api/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
eth::error::{EthApiError, EthResult},
EthApi,
};
use reth_primitives::BlockId;
use reth_primitives::{BlockId};
use reth_provider::{BlockProvider, EvmEnvProvider, StateProviderFactory};
use reth_rpc_types::{Block, Index, RichBlock};

Expand Down Expand Up @@ -56,30 +56,46 @@ where
Ok(self.cache().get_block_transactions(block_hash).await?.map(|txs| txs.len()))
}

/// Returns the rpc block object for the given block id.
///
/// If `full` is true, the block object will contain all transaction objects, otherwise it will
/// only contain the transaction hashes.
/// Returns the block header for the given block id.
pub(crate) async fn header(
&self,
block_id: impl Into<BlockId>,
) -> EthResult<Option<reth_primitives::SealedHeader>> {
Ok(self.block(block_id).await?.map(|block| block.header))
}

/// Returns the block object for the given block id.
pub(crate) async fn block(
&self,
block_id: impl Into<BlockId>,
full: bool,
) -> EthResult<Option<RichBlock>> {
) -> EthResult<Option<reth_primitives::SealedBlock>> {
let block_id = block_id.into();
// TODO support pending block
let block_hash = match self.client().block_hash_for_id(block_id)? {
Some(block_hash) => block_hash,
None => return Ok(None),
};

let block = match self.cache().get_block(block_hash).await? {
Ok(self.cache().get_block(block_hash).await?.map(|block| block.seal(block_hash)))
}

/// Returns the populated rpc block object for the given block id.
///
/// If `full` is true, the block object will contain all transaction objects, otherwise it will
/// only contain the transaction hashes.
pub(crate) async fn rpc_block(
&self,
block_id: impl Into<BlockId>,
full: bool,
) -> EthResult<Option<RichBlock>> {
let block = match self.block(block_id).await? {
Some(block) => block,
None => return Ok(None),
};

let block_hash = block.hash;
let total_difficulty =
self.client().header_td(&block_hash)?.ok_or(EthApiError::UnknownBlockNumber)?;
let block = Block::from_block(block, total_difficulty, full.into(), Some(block_hash))?;
let block = Block::from_block(block.into(), total_difficulty, full.into(), Some(block_hash))?;
Ok(Some(block.into()))
}
}
24 changes: 23 additions & 1 deletion crates/rpc/rpc/src/eth/api/fees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
EthApi,
};
use reth_network_api::NetworkInfo;
use reth_primitives::{BlockId, U256};
use reth_primitives::{BlockId, BlockNumberOrTag, U256};
use reth_provider::{BlockProvider, EvmEnvProvider, StateProviderFactory};
use reth_rpc_types::{FeeHistory, FeeHistoryCacheItem, TxGasAndReward};
use reth_transaction_pool::TransactionPool;
Expand All @@ -17,6 +17,28 @@ where
Client: BlockProvider + StateProviderFactory + EvmEnvProvider + 'static,
Network: NetworkInfo + Send + Sync + 'static,
{

/// Returns a suggestion for a gas price for legacy transactions.
///
/// See also: <https://github.com/ethereum/pm/issues/328#issuecomment-853234014>
pub(crate) async fn gas_price(
&self,
) -> EthResult<U256> {
let header = self.block(BlockNumberOrTag::Latest);
let suggested_tip = self.suggested_priority_fee();
let (header, suggested_tip) = futures::try_join!(header, suggested_tip)?;
let base_fee = header.and_then(|h|h.base_fee_per_gas).unwrap_or_default();
Ok(suggested_tip + U256::from(base_fee))
}

/// Returns a suggestion for the priority fee (the tip)
pub(crate) async fn suggested_priority_fee(
&self,
) -> EthResult<U256> {
// TODO: properly implement sampling https://github.com/ethereum/pm/issues/328#issuecomment-853234014
Ok(U256::from(1e9 as u64))
}

/// Reports the fee history, for the given amount of blocks, up until the newest block
/// provided.
pub(crate) async fn fee_history(
Expand Down
21 changes: 13 additions & 8 deletions crates/rpc/rpc/src/eth/api/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ where
/// Handler for: `eth_getBlockByHash`
async fn block_by_hash(&self, hash: H256, full: bool) -> Result<Option<RichBlock>> {
trace!(target: "rpc::eth", ?hash, ?full, "Serving eth_getBlockByHash");
Ok(EthApi::block(self, hash, full).await?)
Ok(EthApi::rpc_block(self, hash, full).await?)
}

/// Handler for: `eth_getBlockByNumber`
Expand All @@ -83,7 +83,7 @@ where
full: bool,
) -> Result<Option<RichBlock>> {
trace!(target: "rpc::eth", ?number, ?full, "Serving eth_getBlockByNumber");
Ok(EthApi::block(self, number, full).await?)
Ok(EthApi::rpc_block(self, number, full).await?)
}

/// Handler for: `eth_getBlockTransactionCountByHash`
Expand Down Expand Up @@ -248,7 +248,17 @@ where

/// Handler for: `eth_gasPrice`
async fn gas_price(&self) -> Result<U256> {
Err(internal_rpc_err("unimplemented"))
trace!(target: "rpc::eth", "Serving eth_gasPrice");
return Ok(EthApi::gas_price(self)
.await?)
}


/// Handler for: `eth_maxPriorityFeePerGas`
async fn max_priority_fee_per_gas(&self) -> Result<U256> {
trace!(target: "rpc::eth", "Serving eth_maxPriorityFeePerGas");
return Ok(EthApi::suggested_priority_fee(self)
.await?)
}

// FeeHistory is calculated based on lazy evaluation of fees for historical blocks, and further
Expand All @@ -271,11 +281,6 @@ where
.await?)
}

/// Handler for: `eth_maxPriorityFeePerGas`
async fn max_priority_fee_per_gas(&self) -> Result<U256> {
Err(internal_rpc_err("unimplemented"))
}

/// Handler for: `eth_mining`
async fn is_mining(&self) -> Result<bool> {
Err(internal_rpc_err("unimplemented"))
Expand Down

0 comments on commit d270c85

Please sign in to comment.