feat: relax chainspec bounds on NodeBuilder and rpc types (#11160)

This commit is contained in:
Arsenii Kulikov
2024-09-24 20:47:04 +03:00
committed by GitHub
parent d3114b4eec
commit ae3d279cc3
38 changed files with 222 additions and 157 deletions

View File

@ -17,7 +17,7 @@
use alloy_primitives::{BlockHash, BlockNumber, Bloom, B256, U256};
use reth_beacon_consensus::BeaconEngineMessage;
use reth_chainspec::{ChainSpec, EthereumHardforks};
use reth_chainspec::{EthChainSpec, EthereumHardforks};
use reth_consensus::{Consensus, ConsensusError, PostExecutionInput};
use reth_engine_primitives::EngineTypes;
use reth_execution_errors::{
@ -34,6 +34,7 @@ use reth_transaction_pool::TransactionPool;
use reth_trie::HashedPostState;
use std::{
collections::HashMap,
fmt::Debug,
sync::Arc,
time::{SystemTime, UNIX_EPOCH},
};
@ -52,19 +53,19 @@ pub use task::MiningTask;
/// A consensus implementation intended for local development and testing purposes.
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct AutoSealConsensus {
pub struct AutoSealConsensus<ChainSpec> {
/// Configuration
chain_spec: Arc<ChainSpec>,
}
impl AutoSealConsensus {
impl<ChainSpec> AutoSealConsensus<ChainSpec> {
/// Create a new instance of [`AutoSealConsensus`]
pub const fn new(chain_spec: Arc<ChainSpec>) -> Self {
Self { chain_spec }
}
}
impl Consensus for AutoSealConsensus {
impl<ChainSpec: Send + Sync + Debug> Consensus for AutoSealConsensus<ChainSpec> {
fn validate_header(&self, _header: &SealedHeader) -> Result<(), ConsensusError> {
Ok(())
}
@ -100,9 +101,9 @@ impl Consensus for AutoSealConsensus {
/// Builder type for configuring the setup
#[derive(Debug)]
pub struct AutoSealBuilder<Client, Pool, Engine: EngineTypes, EvmConfig> {
pub struct AutoSealBuilder<Client, Pool, Engine: EngineTypes, EvmConfig, ChainSpec> {
client: Client,
consensus: AutoSealConsensus,
consensus: AutoSealConsensus<ChainSpec>,
pool: Pool,
mode: MiningMode,
storage: Storage,
@ -112,11 +113,13 @@ pub struct AutoSealBuilder<Client, Pool, Engine: EngineTypes, EvmConfig> {
// === impl AutoSealBuilder ===
impl<Client, Pool, Engine, EvmConfig> AutoSealBuilder<Client, Pool, Engine, EvmConfig>
impl<Client, Pool, Engine, EvmConfig, ChainSpec>
AutoSealBuilder<Client, Pool, Engine, EvmConfig, ChainSpec>
where
Client: BlockReaderIdExt,
Pool: TransactionPool,
Engine: EngineTypes,
ChainSpec: EthChainSpec,
{
/// Creates a new builder instance to configure all parts.
pub fn new(
@ -127,11 +130,9 @@ where
mode: MiningMode,
evm_config: EvmConfig,
) -> Self {
let latest_header = client
.latest_header()
.ok()
.flatten()
.unwrap_or_else(|| chain_spec.sealed_genesis_header());
let latest_header = client.latest_header().ok().flatten().unwrap_or_else(|| {
SealedHeader::new(chain_spec.genesis_header().clone(), chain_spec.genesis_hash())
});
Self {
storage: Storage::new(latest_header),
@ -154,7 +155,11 @@ where
#[track_caller]
pub fn build(
self,
) -> (AutoSealConsensus, AutoSealClient, MiningTask<Client, Pool, EvmConfig, Engine>) {
) -> (
AutoSealConsensus<ChainSpec>,
AutoSealClient,
MiningTask<Client, Pool, EvmConfig, Engine, ChainSpec>,
) {
let Self { client, consensus, pool, mode, storage, to_engine, evm_config } = self;
let auto_client = AutoSealClient::new(storage.clone());
let task = MiningTask::new(
@ -259,7 +264,7 @@ impl StorageInner {
/// Fills in pre-execution header fields based on the current best block and given
/// transactions.
pub(crate) fn build_header_template(
pub(crate) fn build_header_template<ChainSpec>(
&self,
timestamp: u64,
transactions: &[TransactionSigned],
@ -267,7 +272,10 @@ impl StorageInner {
withdrawals: Option<&Withdrawals>,
requests: Option<&Requests>,
chain_spec: &ChainSpec,
) -> Header {
) -> Header
where
ChainSpec: EthChainSpec + EthereumHardforks,
{
// check previous block for base fee
let base_fee_per_gas = self.headers.get(&self.best_block).and_then(|parent| {
parent.next_block_base_fee(chain_spec.base_fee_params_at_timestamp(timestamp))
@ -292,7 +300,7 @@ impl StorageInner {
withdrawals_root: withdrawals.map(|w| proofs::calculate_withdrawals_root(w)),
difficulty: U256::from(2),
number: self.best_block + 1,
gas_limit: chain_spec.max_gas_limit.into(),
gas_limit: chain_spec.max_gas_limit().into(),
timestamp,
base_fee_per_gas,
blob_gas_used: blob_gas_used.map(Into::into),
@ -333,7 +341,7 @@ impl StorageInner {
///
/// This returns the header of the executed block, as well as the poststate from execution.
#[allow(clippy::too_many_arguments)]
pub(crate) fn build_and_execute<Provider, Executor>(
pub(crate) fn build_and_execute<Provider, Executor, ChainSpec>(
&mut self,
transactions: Vec<TransactionSigned>,
ommers: Vec<Header>,
@ -344,6 +352,7 @@ impl StorageInner {
where
Executor: BlockExecutorProvider,
Provider: StateProviderFactory,
ChainSpec: EthChainSpec + EthereumHardforks,
{
let timestamp = SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_secs();
@ -435,7 +444,7 @@ impl StorageInner {
#[cfg(test)]
mod tests {
use reth_chainspec::{ChainHardforks, EthereumHardfork, ForkCondition};
use reth_chainspec::{ChainHardforks, ChainSpec, EthereumHardfork, ForkCondition};
use reth_primitives::Transaction;
use super::*;

View File

@ -1,7 +1,7 @@
use crate::{mode::MiningMode, Storage};
use futures_util::{future::BoxFuture, FutureExt};
use reth_beacon_consensus::{BeaconEngineMessage, ForkchoiceStatus};
use reth_chainspec::ChainSpec;
use reth_chainspec::{EthChainSpec, EthereumHardforks};
use reth_engine_primitives::EngineTypes;
use reth_evm::execute::BlockExecutorProvider;
use reth_primitives::IntoRecoveredTransaction;
@ -21,7 +21,7 @@ use tokio::sync::{mpsc::UnboundedSender, oneshot};
use tracing::{debug, error, warn};
/// A Future that listens for new ready transactions and puts new blocks into storage
pub struct MiningTask<Client, Pool: TransactionPool, Executor, Engine: EngineTypes> {
pub struct MiningTask<Client, Pool: TransactionPool, Executor, Engine: EngineTypes, ChainSpec> {
/// The configured chain spec
chain_spec: Arc<ChainSpec>,
/// The client used to interact with the state
@ -46,8 +46,8 @@ pub struct MiningTask<Client, Pool: TransactionPool, Executor, Engine: EngineTyp
// === impl MiningTask ===
impl<Executor, Client, Pool: TransactionPool, Engine: EngineTypes>
MiningTask<Client, Pool, Executor, Engine>
impl<Executor, Client, Pool: TransactionPool, Engine: EngineTypes, ChainSpec>
MiningTask<Client, Pool, Executor, Engine, ChainSpec>
{
/// Creates a new instance of the task
#[allow(clippy::too_many_arguments)]
@ -80,12 +80,14 @@ impl<Executor, Client, Pool: TransactionPool, Engine: EngineTypes>
}
}
impl<Executor, Client, Pool, Engine> Future for MiningTask<Client, Pool, Executor, Engine>
impl<Executor, Client, Pool, Engine, ChainSpec> Future
for MiningTask<Client, Pool, Executor, Engine, ChainSpec>
where
Client: StateProviderFactory + CanonChainTracker + Clone + Unpin + 'static,
Pool: TransactionPool + Unpin + 'static,
Engine: EngineTypes,
Executor: BlockExecutorProvider,
ChainSpec: EthChainSpec + EthereumHardforks,
{
type Output = ();
@ -216,8 +218,8 @@ where
}
}
impl<Client, Pool: TransactionPool, EvmConfig: std::fmt::Debug, Engine: EngineTypes> std::fmt::Debug
for MiningTask<Client, Pool, EvmConfig, Engine>
impl<Client, Pool: TransactionPool, EvmConfig: std::fmt::Debug, Engine: EngineTypes, ChainSpec>
std::fmt::Debug for MiningTask<Client, Pool, EvmConfig, Engine, ChainSpec>
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MiningTask").finish_non_exhaustive()

View File

@ -1,5 +1,5 @@
use alloy_primitives::{BlockNumber, U256};
use reth_chainspec::{ChainSpec, EthereumHardfork};
use reth_chainspec::{EthereumHardfork, Hardforks};
use reth_primitives::constants::ETH_TO_WEI;
/// Calculates the base block reward.
@ -22,7 +22,7 @@ use reth_primitives::constants::ETH_TO_WEI;
///
/// [yp]: https://ethereum.github.io/yellowpaper/paper.pdf
pub fn base_block_reward(
chain_spec: &ChainSpec,
chain_spec: impl Hardforks,
block_number: BlockNumber,
block_difficulty: U256,
total_difficulty: U256,
@ -37,7 +37,7 @@ pub fn base_block_reward(
/// Calculates the base block reward __before__ the merge (Paris hardfork).
///
/// Caution: The caller must ensure that the block number is before the merge.
pub fn base_block_reward_pre_merge(chain_spec: &ChainSpec, block_number: BlockNumber) -> u128 {
pub fn base_block_reward_pre_merge(chain_spec: impl Hardforks, block_number: BlockNumber) -> u128 {
if chain_spec.fork(EthereumHardfork::Constantinople).active_at_block(block_number) {
ETH_TO_WEI * 2
} else if chain_spec.fork(EthereumHardfork::Byzantium).active_at_block(block_number) {
@ -66,7 +66,7 @@ pub fn base_block_reward_pre_merge(chain_spec: &ChainSpec, block_number: BlockNu
/// let total_difficulty = U256::from(2_235_668_675_900usize);
/// let number_of_ommers = 1;
///
/// let reward = base_block_reward(&MAINNET, block_number, block_difficulty, total_difficulty)
/// let reward = base_block_reward(&*MAINNET, block_number, block_difficulty, total_difficulty)
/// .map(|reward| block_reward(reward, 1));
///
/// // The base block reward is 5 ETH, and the ommer inclusion reward is 1/32th of 5 ETH.
@ -130,7 +130,7 @@ mod tests {
];
for ((block_number, td), expected_reward) in cases {
assert_eq!(base_block_reward(&MAINNET, block_number, U256::ZERO, td), expected_reward);
assert_eq!(base_block_reward(&*MAINNET, block_number, U256::ZERO, td), expected_reward);
}
}