Port to reth 1.6.0-dev

This commit is contained in:
sprites0
2025-08-21 05:55:48 -04:00
parent 239ee5f8e8
commit 4be1aa83de
24 changed files with 1721 additions and 1749 deletions

View File

@ -1,263 +1,59 @@
use std::{future::Future, sync::Arc};
use crate::{
chainspec::HlChainSpec,
node::{
primitives::TransactionSigned,
rpc::{HlEthApi, HlNodeCore},
},
HlBlock,
};
use alloy_consensus::{BlockHeader, ReceiptEnvelope, TxType};
use alloy_primitives::B256;
use crate::node::rpc::HlEthApi;
use reth::{
api::NodeTypes,
builder::FullNodeComponents,
primitives::{Receipt, SealedHeader, TransactionMeta},
providers::{BlockReaderIdExt, ProviderHeader, ReceiptProvider, TransactionsProvider},
rpc::{
eth::EthApiTypes,
server_types::eth::{
error::FromEvmError, receipt::build_receipt, EthApiError, PendingBlock,
},
types::{BlockId, TransactionReceipt},
rpc::server_types::eth::{
builder::config::PendingBlockKind, error::FromEvmError, EthApiError, PendingBlock,
},
transaction_pool::{PoolTransaction, TransactionPool},
};
use reth_chainspec::{EthChainSpec, EthereumHardforks};
use reth_evm::{ConfigureEvm, NextBlockEnvAttributes};
use reth_primitives::{NodePrimitives, SealedBlock};
use reth_primitives_traits::{BlockBody as _, RecoveredBlock, SignedTransaction as _};
use reth_provider::{
BlockIdReader, BlockReader, ChainSpecProvider, HeaderProvider, ProviderBlock, ProviderReceipt,
ProviderTx, StateProviderFactory,
};
use reth_rpc_eth_api::{
helpers::{EthBlocks, LoadBlock, LoadPendingBlock, LoadReceipt, SpawnBlocking},
types::RpcTypes,
FromEthApiError, RpcConvert, RpcNodeCore, RpcNodeCoreExt, RpcReceipt,
helpers::{
pending_block::PendingEnvBuilder, EthBlocks, LoadBlock, LoadPendingBlock, LoadReceipt,
}, RpcConvert, RpcNodeCore
};
fn is_system_tx(tx: &TransactionSigned) -> bool {
tx.is_system_transaction()
}
impl<N> EthBlocks for HlEthApi<N>
impl<N, Rpc> EthBlocks for HlEthApi<N, Rpc>
where
Self: LoadBlock<
Error = EthApiError,
NetworkTypes: RpcTypes<Receipt = TransactionReceipt>,
Provider: BlockReader<Transaction = TransactionSigned, Receipt = Receipt>,
>,
N: HlNodeCore<Provider: ChainSpecProvider<ChainSpec = HlChainSpec> + HeaderProvider>,
N: RpcNodeCore,
EthApiError: FromEvmError<N::Evm>,
Rpc: RpcConvert<Primitives = N::Primitives, Error = EthApiError>,
{
async fn block_receipts(
&self,
block_id: BlockId,
) -> Result<Option<Vec<RpcReceipt<Self::NetworkTypes>>>, Self::Error>
where
Self: LoadReceipt,
{
if let Some((block, receipts)) = self.load_block_and_receipts(block_id).await? {
let block_number = block.number();
let base_fee = block.base_fee_per_gas();
let block_hash = block.hash();
let excess_blob_gas = block.excess_blob_gas();
let timestamp = block.timestamp();
let blob_params = self.provider().chain_spec().blob_params_at_timestamp(timestamp);
return block
.body()
.transactions()
.iter()
.zip(receipts.iter())
.filter(|(tx, _)| !is_system_tx(tx))
.enumerate()
.map(|(idx, (tx, receipt))| {
let meta = TransactionMeta {
tx_hash: *tx.tx_hash(),
index: idx as u64,
block_hash,
block_number,
base_fee,
excess_blob_gas,
timestamp,
};
build_receipt(tx, meta, receipt, &receipts, blob_params, |receipt_with_bloom| {
match receipt.tx_type {
TxType::Legacy => ReceiptEnvelope::Legacy(receipt_with_bloom),
TxType::Eip2930 => ReceiptEnvelope::Eip2930(receipt_with_bloom),
TxType::Eip1559 => ReceiptEnvelope::Eip1559(receipt_with_bloom),
TxType::Eip4844 => ReceiptEnvelope::Eip4844(receipt_with_bloom),
TxType::Eip7702 => ReceiptEnvelope::Eip7702(receipt_with_bloom),
}
})
})
.collect::<Result<Vec<_>, Self::Error>>()
.map(Some);
}
Ok(None)
}
}
impl<N> LoadBlock for HlEthApi<N>
impl<N, Rpc> LoadBlock for HlEthApi<N, Rpc>
where
Self: LoadPendingBlock
+ SpawnBlocking
+ RpcNodeCoreExt<
Pool: TransactionPool<
Transaction: PoolTransaction<Consensus = ProviderTx<Self::Provider>>,
>,
> + RpcNodeCore<Provider: BlockReader<Block = crate::HlBlock>>,
N: HlNodeCore,
N: RpcNodeCore,
EthApiError: FromEvmError<N::Evm>,
Rpc: RpcConvert<Primitives = N::Primitives, Error = EthApiError>,
{
fn recovered_block(
&self,
block_id: BlockId,
) -> impl Future<
Output = Result<
Option<Arc<RecoveredBlock<<Self::Provider as BlockReader>::Block>>>,
Self::Error,
>,
> + Send {
let hl_node_compliant = self.hl_node_compliant;
async move {
// Copy of LoadBlock::recovered_block, but with --hl-node-compliant support
if block_id.is_pending() {
return Ok(None);
}
let block_hash = match self
.provider()
.block_hash_for_id(block_id)
.map_err(Self::Error::from_eth_err)?
{
Some(block_hash) => block_hash,
None => return Ok(None),
};
let recovered_block = self
.cache()
.get_recovered_block(block_hash)
.await
.map_err(Self::Error::from_eth_err)?;
if let Some(recovered_block) = recovered_block {
let recovered_block = if hl_node_compliant {
filter_if_hl_node_compliant(&recovered_block)
} else {
(*recovered_block).clone()
};
return Ok(Some(std::sync::Arc::new(recovered_block)));
}
Ok(None)
}
}
}
fn filter_if_hl_node_compliant(
recovered_block: &RecoveredBlock<HlBlock>,
) -> RecoveredBlock<HlBlock> {
let sealed_block = recovered_block.sealed_block();
let transactions = sealed_block.body().transactions();
let to_skip = transactions
.iter()
.position(|tx| !tx.is_system_transaction())
.unwrap_or(transactions.len());
let mut new_block: HlBlock = sealed_block.clone_block();
new_block.body.transactions.drain(..to_skip);
let new_sealed_block = SealedBlock::new_unchecked(new_block, sealed_block.hash());
let new_senders = recovered_block.senders()[to_skip..].to_vec();
RecoveredBlock::new_sealed(new_sealed_block, new_senders)
}
impl<N> LoadPendingBlock for HlEthApi<N>
impl<N, Rpc> LoadPendingBlock for HlEthApi<N, Rpc>
where
Self: SpawnBlocking
+ EthApiTypes<
NetworkTypes: RpcTypes<
Header = alloy_rpc_types_eth::Header<ProviderHeader<Self::Provider>>,
>,
Error: FromEvmError<Self::Evm>,
RpcConvert: RpcConvert<Network = Self::NetworkTypes>,
>,
N: RpcNodeCore<
Provider: BlockReaderIdExt
+ ChainSpecProvider<ChainSpec: EthChainSpec + EthereumHardforks>
+ StateProviderFactory,
Pool: TransactionPool<Transaction: PoolTransaction<Consensus = ProviderTx<N::Provider>>>,
Evm: ConfigureEvm<
Primitives = <Self as RpcNodeCore>::Primitives,
NextBlockEnvCtx: From<NextBlockEnvAttributes>,
>,
Primitives: NodePrimitives<
BlockHeader = ProviderHeader<Self::Provider>,
SignedTx = ProviderTx<Self::Provider>,
Receipt = ProviderReceipt<Self::Provider>,
Block = ProviderBlock<Self::Provider>,
>,
>,
N: RpcNodeCore,
EthApiError: FromEvmError<N::Evm>,
Rpc: RpcConvert<Primitives = N::Primitives, Error = EthApiError>,
{
#[inline]
fn pending_block(
&self,
) -> &tokio::sync::Mutex<
Option<PendingBlock<ProviderBlock<Self::Provider>, ProviderReceipt<Self::Provider>>>,
> {
fn pending_block(&self) -> &tokio::sync::Mutex<Option<PendingBlock<N::Primitives>>> {
self.inner.eth_api.pending_block()
}
fn next_env_attributes(
&self,
parent: &SealedHeader<ProviderHeader<Self::Provider>>,
) -> Result<<Self::Evm as reth_evm::ConfigureEvm>::NextBlockEnvCtx, Self::Error> {
Ok(NextBlockEnvAttributes {
timestamp: parent.timestamp().saturating_add(12),
suggested_fee_recipient: parent.beneficiary(),
prev_randao: B256::random(),
gas_limit: parent.gas_limit(),
parent_beacon_block_root: parent.parent_beacon_block_root(),
withdrawals: None,
}
.into())
#[inline]
fn pending_env_builder(&self) -> &dyn PendingEnvBuilder<Self::Evm> {
self.inner.eth_api.pending_env_builder()
}
#[inline]
fn pending_block_kind(&self) -> PendingBlockKind {
self.inner.eth_api.pending_block_kind()
}
}
impl<N> LoadReceipt for HlEthApi<N>
impl<N, Rpc> LoadReceipt for HlEthApi<N, Rpc>
where
Self: Send + Sync,
N: FullNodeComponents<Types: NodeTypes<ChainSpec = HlChainSpec>>,
Self::Provider:
TransactionsProvider<Transaction = TransactionSigned> + ReceiptProvider<Receipt = Receipt>,
N: RpcNodeCore,
EthApiError: FromEvmError<N::Evm>,
Rpc: RpcConvert<Primitives = N::Primitives, Error = EthApiError>,
{
async fn build_transaction_receipt(
&self,
tx: TransactionSigned,
meta: TransactionMeta,
receipt: Receipt,
) -> Result<RpcReceipt<Self::NetworkTypes>, Self::Error> {
let hash = meta.block_hash;
// get all receipts for the block
let all_receipts = self
.cache()
.get_receipts(hash)
.await
.map_err(Self::Error::from_eth_err)?
.ok_or(EthApiError::HeaderNotFound(hash.into()))?;
let blob_params = self.provider().chain_spec().blob_params_at_timestamp(meta.timestamp);
build_receipt(&tx, meta, &receipt, &all_receipts, blob_params, |receipt_with_bloom| {
match receipt.tx_type {
TxType::Legacy => ReceiptEnvelope::Legacy(receipt_with_bloom),
TxType::Eip2930 => ReceiptEnvelope::Eip2930(receipt_with_bloom),
TxType::Eip1559 => ReceiptEnvelope::Eip1559(receipt_with_bloom),
TxType::Eip4844 => ReceiptEnvelope::Eip4844(receipt_with_bloom),
TxType::Eip7702 => ReceiptEnvelope::Eip7702(receipt_with_bloom),
}
})
}
}

View File

@ -1,51 +1,32 @@
use super::{HlEthApi, HlNodeCore};
use crate::evm::transaction::HlTxEnv;
use alloy_rpc_types::TransactionRequest;
use super::HlEthApi;
use reth::rpc::server_types::eth::EthApiError;
use reth_evm::{block::BlockExecutorFactory, ConfigureEvm, EvmFactory, TxEnvFor};
use reth_primitives::NodePrimitives;
use reth_provider::{ProviderError, ProviderHeader, ProviderTx};
use reth_evm::TxEnvFor;
use reth_rpc_eth_api::{
helpers::{estimate::EstimateCall, Call, EthCall, LoadBlock, LoadState, SpawnBlocking},
FromEvmError, FullEthApiTypes, RpcConvert, RpcTypes,
helpers::{estimate::EstimateCall, Call, EthCall},
FromEvmError, RpcConvert, RpcNodeCore,
};
use revm::context::TxEnv;
impl<N> EthCall for HlEthApi<N>
impl<N, Rpc> EthCall for HlEthApi<N, Rpc>
where
Self: EstimateCall + LoadBlock + FullEthApiTypes,
N: HlNodeCore,
N: RpcNodeCore,
EthApiError: FromEvmError<N::Evm>,
Rpc: RpcConvert<Primitives = N::Primitives, Error = EthApiError, TxEnv = TxEnvFor<N::Evm>>,
{
}
impl<N> EstimateCall for HlEthApi<N>
impl<N, Rpc> EstimateCall for HlEthApi<N, Rpc>
where
Self: Call,
Self::Error: From<EthApiError>,
N: HlNodeCore,
N: RpcNodeCore,
EthApiError: FromEvmError<N::Evm>,
Rpc: RpcConvert<Primitives = N::Primitives, Error = EthApiError, TxEnv = TxEnvFor<N::Evm>>,
{
}
impl<N> Call for HlEthApi<N>
impl<N, Rpc> Call for HlEthApi<N, Rpc>
where
Self: LoadState<
Evm: ConfigureEvm<
Primitives: NodePrimitives<
BlockHeader = ProviderHeader<Self::Provider>,
SignedTx = ProviderTx<Self::Provider>,
>,
BlockExecutorFactory: BlockExecutorFactory<
EvmFactory: EvmFactory<Tx = HlTxEnv<TxEnv>>,
>,
>,
RpcConvert: RpcConvert<TxEnv = TxEnvFor<Self::Evm>, Network = Self::NetworkTypes>,
NetworkTypes: RpcTypes<TransactionRequest: From<TransactionRequest>>,
Error: FromEvmError<Self::Evm>
+ From<<Self::RpcConvert as RpcConvert>::Error>
+ From<ProviderError>,
> + SpawnBlocking,
Self::Error: From<EthApiError>,
N: HlNodeCore,
N: RpcNodeCore,
EthApiError: FromEvmError<N::Evm>,
Rpc: RpcConvert<Primitives = N::Primitives, Error = EthApiError, TxEnv = TxEnvFor<N::Evm>>,
{
#[inline]
fn call_gas_limit(&self) -> u64 {

View File

@ -6,20 +6,15 @@ use crate::{
use alloy_consensus::BlockHeader;
use alloy_eips::eip4895::Withdrawal;
use alloy_primitives::B256;
use alloy_rpc_types_engine::{PayloadAttributes, PayloadError};
use alloy_rpc_types_engine::PayloadError;
use reth::{
api::{FullNodeComponents, NodeTypes},
builder::{rpc::EngineValidatorBuilder, AddOnsContext},
consensus::ConsensusError,
};
use reth_engine_primitives::{EngineValidator, ExecutionPayload, PayloadValidator};
use reth_payload_primitives::{
EngineApiMessageVersion, EngineObjectValidationError, NewPayloadError, PayloadOrAttributes,
PayloadTypes,
builder::{rpc::PayloadValidatorBuilder, AddOnsContext},
};
use reth_engine_primitives::{ExecutionPayload, PayloadValidator};
use reth_payload_primitives::NewPayloadError;
use reth_primitives::{RecoveredBlock, SealedBlock};
use reth_primitives_traits::Block as _;
use reth_trie_common::HashedPostState;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
@ -27,27 +22,27 @@ use super::payload::HlPayloadTypes;
#[derive(Debug, Default, Clone)]
#[non_exhaustive]
pub struct HlEngineValidatorBuilder;
pub struct HlPayloadValidatorBuilder;
impl<Node, Types> EngineValidatorBuilder<Node> for HlEngineValidatorBuilder
impl<Node, Types> PayloadValidatorBuilder<Node> for HlPayloadValidatorBuilder
where
Types: NodeTypes<ChainSpec = HlChainSpec, Payload = HlPayloadTypes, Primitives = HlPrimitives>,
Node: FullNodeComponents<Types = Types>,
{
type Validator = HlEngineValidator;
type Validator = HlPayloadValidator;
async fn build(self, ctx: &AddOnsContext<'_, Node>) -> eyre::Result<Self::Validator> {
Ok(HlEngineValidator::new(Arc::new(ctx.config.chain.clone().as_ref().clone())))
Ok(HlPayloadValidator::new(Arc::new(ctx.config.chain.clone().as_ref().clone())))
}
}
/// Validator for Optimism engine API.
#[derive(Debug, Clone)]
pub struct HlEngineValidator {
pub struct HlPayloadValidator {
inner: HlExecutionPayloadValidator<HlChainSpec>,
}
impl HlEngineValidator {
impl HlPayloadValidator {
/// Instantiates a new validator.
pub fn new(chain_spec: Arc<HlChainSpec>) -> Self {
Self { inner: HlExecutionPayloadValidator { inner: chain_spec } }
@ -87,47 +82,17 @@ impl ExecutionPayload for HlExecutionData {
}
}
impl PayloadValidator for HlEngineValidator {
impl PayloadValidator<HlPayloadTypes> for HlPayloadValidator {
type Block = HlBlock;
type ExecutionData = HlExecutionData;
fn ensure_well_formed_payload(
&self,
payload: Self::ExecutionData,
payload: HlExecutionData,
) -> Result<RecoveredBlock<Self::Block>, NewPayloadError> {
let sealed_block =
self.inner.ensure_well_formed_payload(payload).map_err(NewPayloadError::other)?;
sealed_block.try_recover().map_err(|e| NewPayloadError::Other(e.into()))
}
fn validate_block_post_execution_with_hashed_state(
&self,
_state_updates: &HashedPostState,
_block: &RecoveredBlock<Self::Block>,
) -> Result<(), ConsensusError> {
Ok(())
}
}
impl<Types> EngineValidator<Types> for HlEngineValidator
where
Types: PayloadTypes<PayloadAttributes = PayloadAttributes, ExecutionData = HlExecutionData>,
{
fn validate_version_specific_fields(
&self,
_version: EngineApiMessageVersion,
_payload_or_attrs: PayloadOrAttributes<'_, Self::ExecutionData, PayloadAttributes>,
) -> Result<(), EngineObjectValidationError> {
Ok(())
}
fn ensure_well_formed_attributes(
&self,
_version: EngineApiMessageVersion,
_attributes: &PayloadAttributes,
) -> Result<(), EngineObjectValidationError> {
Ok(())
}
}
/// Execution payload validator.

View File

@ -1,104 +1,95 @@
use alloy_network::Ethereum;
use alloy_primitives::U256;
use reth::{
api::{FullNodeTypes, HeaderTy, NodeTypes, PrimitivesTy},
builder::{
rpc::{EthApiBuilder, EthApiCtx},
FullNodeComponents,
},
chainspec::EthChainSpec,
primitives::EthereumHardforks,
providers::ChainSpecProvider,
rpc::{
eth::{core::EthApiInner, DevSigner, FullEthApiServer},
server_types::eth::{EthApiError, EthStateCache, FeeHistoryCache, GasPriceOracle},
server_types::eth::{
receipt::EthReceiptConverter,
EthApiError, EthStateCache, FeeHistoryCache, GasPriceOracle,
},
},
tasks::{
pool::{BlockingTaskGuard, BlockingTaskPool},
TaskSpawner,
},
transaction_pool::TransactionPool,
};
use reth_evm::ConfigureEvm;
use reth_network::NetworkInfo;
use reth_primitives::NodePrimitives;
use reth_provider::{
BlockNumReader, BlockReader, BlockReaderIdExt, ProviderBlock, ProviderHeader, ProviderReceipt,
ProviderTx, StageCheckpointReader, StateProviderFactory,
};
use reth_primitives::{NodePrimitives, Receipt};
use reth_provider::{ChainSpecProvider, ProviderHeader, ProviderTx};
use reth_rpc::RpcTypes;
use reth_rpc_eth_api::{
helpers::{
AddDevSigners, EthApiSpec, EthFees, EthSigner, EthState, LoadBlock, LoadFee, LoadState,
SpawnBlocking, Trace,
pending_block::BuildPendingEnv, spec::SignersForApi, AddDevSigners, EthApiSpec, EthFees,
EthState, LoadFee, LoadState, SpawnBlocking, Trace,
},
EthApiTypes, FromEvmError, RpcConverter, RpcNodeCore, RpcNodeCoreExt,
EthApiTypes, FromEvmError, RpcConvert, RpcConverter, RpcNodeCore, RpcNodeCoreExt,
SignableTxRequest,
};
use std::{fmt, sync::Arc};
use std::{fmt, marker::PhantomData, sync::Arc};
use crate::chainspec::HlChainSpec;
mod block;
mod call;
pub mod engine_api;
mod transaction;
/// A helper trait with requirements for [`RpcNodeCore`] to be used in [`HlEthApi`].
pub trait HlNodeCore: RpcNodeCore<Provider: BlockReader> {}
impl<T> HlNodeCore for T where T: RpcNodeCore<Provider: BlockReader> {}
/// Adapter for [`EthApiInner`], which holds all the data required to serve core `eth_` API.
pub type EthApiNodeBackend<N> = EthApiInner<
<N as RpcNodeCore>::Provider,
<N as RpcNodeCore>::Pool,
<N as RpcNodeCore>::Network,
<N as RpcNodeCore>::Evm,
>;
/// Container type `HlEthApi`
#[allow(missing_debug_implementations)]
pub(crate) struct HlEthApiInner<N: HlNodeCore> {
pub(crate) struct HlEthApiInner<N: RpcNodeCore, Rpc: RpcConvert> {
/// Gateway to node's core components.
pub(crate) eth_api: EthApiNodeBackend<N>,
pub(crate) eth_api: EthApiInner<N, Rpc>,
}
type HlRpcConvert<N, NetworkT> =
RpcConverter<NetworkT, <N as FullNodeComponents>::Evm, EthReceiptConverter<HlChainSpec>>;
#[derive(Clone)]
pub struct HlEthApi<N: HlNodeCore> {
pub struct HlEthApi<N: RpcNodeCore, Rpc: RpcConvert> {
/// Gateway to node's core components.
pub(crate) inner: Arc<HlEthApiInner<N>>,
/// Converter for RPC types.
tx_resp_builder: RpcConverter<Ethereum, N::Evm, EthApiError, ()>,
/// Whether the node is in HL node compliant mode.
pub(crate) hl_node_compliant: bool,
pub(crate) inner: Arc<HlEthApiInner<N, Rpc>>,
}
impl<N: HlNodeCore> fmt::Debug for HlEthApi<N> {
impl<N, Rpc> fmt::Debug for HlEthApi<N, Rpc>
where
N: RpcNodeCore,
Rpc: RpcConvert<Primitives = N::Primitives, Error = EthApiError>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("HlEthApi").finish_non_exhaustive()
}
}
impl<N> EthApiTypes for HlEthApi<N>
impl<N, Rpc> EthApiTypes for HlEthApi<N, Rpc>
where
Self: Send + Sync,
N: HlNodeCore,
N::Evm: std::fmt::Debug,
N: RpcNodeCore,
Rpc: RpcConvert<Primitives = N::Primitives, Error = EthApiError>,
{
type Error = EthApiError;
type NetworkTypes = Ethereum;
type RpcConvert = RpcConverter<Ethereum, N::Evm, EthApiError, ()>;
type NetworkTypes = Rpc::Network;
type RpcConvert = Rpc;
fn tx_resp_builder(&self) -> &Self::RpcConvert {
&self.tx_resp_builder
self.inner.eth_api.tx_resp_builder()
}
}
impl<N> RpcNodeCore for HlEthApi<N>
impl<N, Rpc> RpcNodeCore for HlEthApi<N, Rpc>
where
N: HlNodeCore,
N: RpcNodeCore,
Rpc: RpcConvert<Primitives = N::Primitives>,
{
type Primitives = N::Primitives;
type Provider = N::Provider;
type Pool = N::Pool;
type Evm = <N as RpcNodeCore>::Evm;
type Network = <N as RpcNodeCore>::Network;
type PayloadBuilder = ();
type Evm = N::Evm;
type Network = N::Network;
#[inline]
fn pool(&self) -> &Self::Pool {
@ -115,37 +106,30 @@ where
self.inner.eth_api.network()
}
#[inline]
fn payload_builder(&self) -> &Self::PayloadBuilder {
&()
}
#[inline]
fn provider(&self) -> &Self::Provider {
self.inner.eth_api.provider()
}
}
impl<N> RpcNodeCoreExt for HlEthApi<N>
impl<N, Rpc> RpcNodeCoreExt for HlEthApi<N, Rpc>
where
N: HlNodeCore,
N: RpcNodeCore,
Rpc: RpcConvert<Primitives = N::Primitives, Error = EthApiError>,
{
#[inline]
fn cache(&self) -> &EthStateCache<ProviderBlock<N::Provider>, ProviderReceipt<N::Provider>> {
fn cache(&self) -> &EthStateCache<N::Primitives> {
self.inner.eth_api.cache()
}
}
impl<N> EthApiSpec for HlEthApi<N>
impl<N, Rpc> EthApiSpec for HlEthApi<N, Rpc>
where
N: HlNodeCore<
Provider: ChainSpecProvider<ChainSpec: EthereumHardforks>
+ BlockNumReader
+ StageCheckpointReader,
Network: NetworkInfo,
>,
N: RpcNodeCore,
Rpc: RpcConvert<Primitives = N::Primitives, Error = EthApiError>,
{
type Transaction = ProviderTx<Self::Provider>;
type Rpc = Rpc::Network;
#[inline]
fn starting_block(&self) -> U256 {
@ -153,16 +137,15 @@ where
}
#[inline]
fn signers(&self) -> &parking_lot::RwLock<Vec<Box<dyn EthSigner<ProviderTx<Self::Provider>>>>> {
fn signers(&self) -> &SignersForApi<Self> {
self.inner.eth_api.signers()
}
}
impl<N> SpawnBlocking for HlEthApi<N>
impl<N, Rpc> SpawnBlocking for HlEthApi<N, Rpc>
where
Self: Send + Sync + Clone + 'static,
N: HlNodeCore,
N::Evm: std::fmt::Debug,
N: RpcNodeCore,
Rpc: RpcConvert<Primitives = N::Primitives, Error = EthApiError>,
{
#[inline]
fn io_task_spawner(&self) -> impl TaskSpawner {
@ -180,14 +163,11 @@ where
}
}
impl<N> LoadFee for HlEthApi<N>
impl<N, Rpc> LoadFee for HlEthApi<N, Rpc>
where
Self: LoadBlock<Provider = N::Provider>,
N: HlNodeCore<
Provider: BlockReaderIdExt
+ ChainSpecProvider<ChainSpec: EthChainSpec + EthereumHardforks>
+ StateProviderFactory,
>,
N: RpcNodeCore,
EthApiError: FromEvmError<N::Evm>,
Rpc: RpcConvert<Primitives = N::Primitives, Error = EthApiError>,
{
#[inline]
fn gas_oracle(&self) -> &GasPriceOracle<Self::Provider> {
@ -195,25 +175,22 @@ where
}
#[inline]
fn fee_history_cache(&self) -> &FeeHistoryCache {
fn fee_history_cache(&self) -> &FeeHistoryCache<ProviderHeader<N::Provider>> {
self.inner.eth_api.fee_history_cache()
}
}
impl<N> LoadState for HlEthApi<N>
impl<N, Rpc> LoadState for HlEthApi<N, Rpc>
where
N: HlNodeCore<
Provider: StateProviderFactory + ChainSpecProvider<ChainSpec: EthereumHardforks>,
Pool: TransactionPool,
>,
N::Evm: std::fmt::Debug,
N: RpcNodeCore,
Rpc: RpcConvert<Primitives = N::Primitives, Error = EthApiError>,
{
}
impl<N> EthState for HlEthApi<N>
impl<N, Rpc> EthState for HlEthApi<N, Rpc>
where
Self: LoadState + SpawnBlocking,
N: HlNodeCore,
N: RpcNodeCore,
Rpc: RpcConvert<Primitives = N::Primitives, Error = EthApiError>,
{
#[inline]
fn max_proof_window(&self) -> u64 {
@ -221,36 +198,28 @@ where
}
}
impl<N> EthFees for HlEthApi<N>
impl<N, Rpc> EthFees for HlEthApi<N, Rpc>
where
Self: LoadFee<
Provider: ChainSpecProvider<
ChainSpec: EthChainSpec<Header = ProviderHeader<Self::Provider>>,
>,
N: RpcNodeCore,
EthApiError: FromEvmError<N::Evm>,
Rpc: RpcConvert<Primitives = N::Primitives, Error = EthApiError>,
{
}
impl<N, Rpc> Trace for HlEthApi<N, Rpc>
where
N: RpcNodeCore,
EthApiError: FromEvmError<N::Evm>,
Rpc: RpcConvert<Primitives = N::Primitives, Error = EthApiError>,
{
}
impl<N, Rpc> AddDevSigners for HlEthApi<N, Rpc>
where
N: RpcNodeCore,
Rpc: RpcConvert<
Network: RpcTypes<TransactionRequest: SignableTxRequest<ProviderTx<N::Provider>>>,
>,
N: HlNodeCore,
{
}
impl<N> Trace for HlEthApi<N>
where
Self: RpcNodeCore<Provider: BlockReader>
+ LoadState<
Evm: ConfigureEvm<
Primitives: NodePrimitives<
BlockHeader = ProviderHeader<Self::Provider>,
SignedTx = ProviderTx<Self::Provider>,
>,
>,
Error: FromEvmError<Self::Evm>,
>,
N: HlNodeCore,
{
}
impl<N> AddDevSigners for HlEthApi<N>
where
N: HlNodeCore,
{
fn with_dev_accounts(&self) {
*self.inner.eth_api.signers().write() = DevSigner::random_signers(20)
@ -258,40 +227,50 @@ where
}
/// Builds [`HlEthApi`] for HL.
#[derive(Debug, Default)]
#[derive(Debug)]
#[non_exhaustive]
pub struct HlEthApiBuilder {
/// Whether the node is in HL node compliant mode.
pub(crate) hl_node_compliant: bool,
pub struct HlEthApiBuilder<NetworkT = Ethereum> {
/// Marker for network types.
pub(crate) _nt: PhantomData<NetworkT>,
}
impl<N> EthApiBuilder<N> for HlEthApiBuilder
where
N: FullNodeComponents,
HlEthApi<N>: FullEthApiServer<Provider = N::Provider, Pool = N::Pool>,
{
type EthApi = HlEthApi<N>;
async fn build_eth_api(self, ctx: EthApiCtx<'_, N>) -> eyre::Result<Self::EthApi> {
let eth_api = reth::rpc::eth::EthApiBuilder::new(
ctx.components.provider().clone(),
ctx.components.pool().clone(),
ctx.components.network().clone(),
ctx.components.evm_config().clone(),
)
.eth_cache(ctx.cache)
.task_spawner(ctx.components.task_executor().clone())
.gas_cap(ctx.config.rpc_gas_cap.into())
.max_simulate_blocks(ctx.config.rpc_max_simulate_blocks)
.eth_proof_window(ctx.config.eth_proof_window)
.fee_history_cache_config(ctx.config.fee_history_cache)
.proof_permits(ctx.config.proof_permits)
.build_inner();
Ok(HlEthApi {
inner: Arc::new(HlEthApiInner { eth_api }),
tx_resp_builder: Default::default(),
hl_node_compliant: self.hl_node_compliant,
})
impl<NetworkT> Default for HlEthApiBuilder<NetworkT> {
fn default() -> Self {
Self { _nt: PhantomData }
}
}
impl<N, NetworkT> EthApiBuilder<N> for HlEthApiBuilder<NetworkT>
where
N: FullNodeComponents<
Types: NodeTypes<ChainSpec: EthereumHardforks>,
Evm: ConfigureEvm<
NextBlockEnvCtx: BuildPendingEnv<HeaderTy<N::Types>>,
Primitives: NodePrimitives,
>,
> + RpcNodeCore<Primitives = PrimitivesTy<N::Types>>
+ FullNodeTypes<
Types: NodeTypes<
Primitives: NodePrimitives<Receipt = Receipt>,
ChainSpec = HlChainSpec,
>,
>,
NetworkT: RpcTypes,
HlRpcConvert<N, NetworkT>: RpcConvert<Network = NetworkT, Primitives = PrimitivesTy<N::Types>>,
HlEthApi<N, HlRpcConvert<N, NetworkT>>: FullEthApiServer<
Provider = <N as FullNodeTypes>::Provider,
Pool = <N as FullNodeComponents>::Pool,
> + AddDevSigners,
<<N as RpcNodeCore>::Evm as ConfigureEvm>::NextBlockEnvCtx: BuildPendingEnv<HeaderTy<N::Types>>,
{
type EthApi = HlEthApi<N, HlRpcConvert<N, NetworkT>>;
async fn build_eth_api(self, ctx: EthApiCtx<'_, N>) -> eyre::Result<Self::EthApi> {
let provider = FullNodeComponents::provider(ctx.components);
let rpc_converter =
RpcConverter::new(EthReceiptConverter::<HlChainSpec>::new(provider.chain_spec()));
let eth_api = ctx.eth_api_builder().with_rpc_converter(rpc_converter).build_inner();
Ok(HlEthApi { inner: Arc::new(HlEthApiInner { eth_api }) })
}
}

View File

@ -1,51 +1,28 @@
use super::HlNodeCore;
use crate::node::rpc::HlEthApi;
use alloy_primitives::{Bytes, B256};
use reth::{
rpc::server_types::eth::utils::recover_raw_transaction,
transaction_pool::{PoolTransaction, TransactionOrigin, TransactionPool},
};
use reth_provider::{BlockReader, BlockReaderIdExt, ProviderTx, TransactionsProvider};
use reth::rpc::server_types::eth::EthApiError;
use reth_rpc_eth_api::{
helpers::{EthSigner, EthTransactions, LoadTransaction, SpawnBlocking},
FromEthApiError, FullEthApiTypes, RpcNodeCore, RpcNodeCoreExt,
helpers::{spec::SignersForRpc, EthTransactions, LoadTransaction},
RpcConvert, RpcNodeCore,
};
impl<N> LoadTransaction for HlEthApi<N>
impl<N, Rpc> LoadTransaction for HlEthApi<N, Rpc>
where
Self: SpawnBlocking + FullEthApiTypes + RpcNodeCoreExt,
N: HlNodeCore<Provider: TransactionsProvider, Pool: TransactionPool>,
Self::Pool: TransactionPool,
N: RpcNodeCore,
Rpc: RpcConvert<Primitives = N::Primitives, Error = EthApiError>,
{
}
impl<N> EthTransactions for HlEthApi<N>
impl<N, Rpc> EthTransactions for HlEthApi<N, Rpc>
where
Self: LoadTransaction<Provider: BlockReaderIdExt>,
N: HlNodeCore<Provider: BlockReader<Transaction = ProviderTx<Self::Provider>>>,
N: RpcNodeCore,
Rpc: RpcConvert<Primitives = N::Primitives, Error = EthApiError>,
{
fn signers(&self) -> &parking_lot::RwLock<Vec<Box<dyn EthSigner<ProviderTx<Self::Provider>>>>> {
fn signers(&self) -> &SignersForRpc<Self::Provider, Self::NetworkTypes> {
self.inner.eth_api.signers()
}
/// Decodes and recovers the transaction and submits it to the pool.
///
/// Returns the hash of the transaction.
async fn send_raw_transaction(&self, tx: Bytes) -> Result<B256, Self::Error> {
let recovered = recover_raw_transaction(&tx)?;
// broadcast raw transaction to subscribers if there is any.
self.inner.eth_api.broadcast_raw_transaction(tx);
let pool_transaction = <Self::Pool as TransactionPool>::Transaction::from_pooled(recovered);
// submit the transaction to the pool with a `Local` origin
let hash = self
.pool()
.add_transaction(TransactionOrigin::Local, pool_transaction)
.await
.map_err(Self::Error::from_eth_err)?;
Ok(hash)
async fn send_raw_transaction(&self, _tx: Bytes) -> Result<B256, Self::Error> {
unreachable!()
}
}