Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move cfg_env and block_env configuration from PayloadBuilderAttributes into PayloadBuilder #10510

Merged
merged 20 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 0 additions & 72 deletions crates/ethereum/engine-primitives/src/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,65 +234,6 @@ impl PayloadBuilderAttributes for EthPayloadBuilderAttributes {
fn withdrawals(&self) -> &Withdrawals {
&self.withdrawals
}

fn cfg_and_block_env(
&self,
chain_spec: &ChainSpec,
parent: &Header,
) -> (CfgEnvWithHandlerCfg, BlockEnv) {
// configure evm env based on parent block
let cfg = CfgEnv::default().with_chain_id(chain_spec.chain().id());

// ensure we're not missing any timestamp based hardforks
let spec_id = revm_spec_by_timestamp_after_merge(chain_spec, self.timestamp());

// if the parent block did not have excess blob gas (i.e. it was pre-cancun), but it is
// cancun now, we need to set the excess blob gas to the default value
let blob_excess_gas_and_price = parent
.next_block_excess_blob_gas()
.or_else(|| {
if spec_id == SpecId::CANCUN {
// default excess blob gas is zero
Some(0)
} else {
None
}
})
.map(BlobExcessGasAndPrice::new);

let mut basefee =
parent.next_block_base_fee(chain_spec.base_fee_params_at_timestamp(self.timestamp()));

let mut gas_limit = U256::from(parent.gas_limit);

// If we are on the London fork boundary, we need to multiply the parent's gas limit by the
// elasticity multiplier to get the new gas limit.
if chain_spec.fork(EthereumHardfork::London).transitions_at_block(parent.number + 1) {
let elasticity_multiplier =
chain_spec.base_fee_params_at_timestamp(self.timestamp()).elasticity_multiplier;

// multiply the gas limit by the elasticity multiplier
gas_limit *= U256::from(elasticity_multiplier);

// set the base fee to the initial base fee from the EIP-1559 spec
basefee = Some(EIP1559_INITIAL_BASE_FEE)
}

let block_env = BlockEnv {
number: U256::from(parent.number + 1),
coinbase: self.suggested_fee_recipient(),
timestamp: U256::from(self.timestamp()),
difficulty: U256::ZERO,
prevrandao: Some(self.prev_randao()),
gas_limit,
// calculate basefee based on parent block's gas usage
basefee: basefee.map(U256::from).unwrap_or_default(),
// calculate excess gas based on parent block's blob gas usage
blob_excess_gas_and_price,
};

(CfgEnvWithHandlerCfg::new_with_spec_id(cfg, spec_id), block_env)
}
}

/// Generates the payload id for the configured payload from the [`PayloadAttributes`].
Expand Down Expand Up @@ -398,18 +339,5 @@ mod tests {
let chainspec = ChainSpec::from(genesis);
let payload_builder_attributes =
EthPayloadBuilderAttributes::new(chainspec.genesis_hash(), attributes);

// use cfg_and_block_env
let cfg_and_block_env =
payload_builder_attributes.cfg_and_block_env(&chainspec, &chainspec.genesis_header());

// ensure the base fee is non zero
assert_eq!(cfg_and_block_env.1.basefee, U256::from(EIP1559_INITIAL_BASE_FEE));

// ensure the gas limit is double the previous block's gas limit
assert_eq!(
cfg_and_block_env.1.gas_limit,
U256::from(chainspec.genesis_header().gas_limit * 2)
);
}
}
40 changes: 24 additions & 16 deletions crates/ethereum/payload/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use reth_basic_payload_builder::{
commit_withdrawals, is_better_payload, BuildArguments, BuildOutcome, PayloadBuilder,
PayloadConfig, WithdrawalsOutcome,
};
use reth_chainspec::ChainSpec;
use reth_errors::RethError;
use reth_evm::{
system_calls::{
Expand All @@ -31,6 +32,7 @@ use reth_primitives::{
},
eip4844::calculate_excess_blob_gas,
proofs::{self, calculate_requests_root},
revm_primitives::{BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, SpecId},
Block, EthereumHardforks, Header, IntoRecoveredTransaction, Receipt, EMPTY_OMMER_ROOT_HASH,
U256,
};
Expand Down Expand Up @@ -87,14 +89,7 @@ where
config: PayloadConfig<Self::Attributes>,
) -> Result<EthBuiltPayload, PayloadBuilderError> {
let extra_data = config.extra_data();
let PayloadConfig {
initialized_block_env,
parent_block,
attributes,
chain_spec,
initialized_cfg,
..
} = config;
let PayloadConfig { parent_block, attributes, chain_spec, .. } = config;

debug!(target: "payload_builder", parent_hash = ?parent_block.hash(), parent_number = parent_block.number, "building empty payload");

Expand Down Expand Up @@ -244,6 +239,26 @@ where

Ok(EthBuiltPayload::new(attributes.payload_id(), sealed_block, U256::ZERO))
}

fn cfg_and_block_env(
&self,
chain_spec: &ChainSpec,
parent: &Header,
) -> (CfgEnvWithHandlerCfg, BlockEnv) {
let mut cfg_env = CfgEnvWithHandlerCfg::new_with_spec_id(CfgEnv::default(), SpecId::LATEST);
onbjerg marked this conversation as resolved.
Show resolved Hide resolved
let mut block_env = BlockEnv::default();
onbjerg marked this conversation as resolved.
Show resolved Hide resolved
let total_difficulty = U256::ZERO;

self.evm_config.fill_cfg_and_block_env(
&mut cfg_env,
&mut block_env,
&chain_spec,
&parent,
total_difficulty,
);

(cfg_env, block_env)
}
}

/// Constructs an Ethereum transaction payload using the best transactions from the pool.
Expand All @@ -268,14 +283,7 @@ where
let mut db =
State::builder().with_database_ref(cached_reads.as_db(state)).with_bundle_update().build();
let extra_data = config.extra_data();
let PayloadConfig {
initialized_block_env,
initialized_cfg,
parent_block,
attributes,
chain_spec,
..
} = config;
let PayloadConfig { parent_block, attributes, chain_spec, .. } = config;

debug!(target: "payload_builder", id=%attributes.id, parent_hash = ?parent_block.hash(), parent_number = parent_block.number, "building new payload");
let mut cumulative_gas_used = 0;
Expand Down
20 changes: 20 additions & 0 deletions crates/optimism/payload/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,26 @@ where
None,
))
}

fn cfg_and_block_env(
&self,
chain_spec: &ChainSpec,
parent: &Header,
) -> (CfgEnvWithHandlerCfg, BlockEnv) {
let mut cfg_env = CfgEnvWithHandlerCfg::new_with_spec_id(CfgEnv::default(), SpecId::LATEST);
garwahl marked this conversation as resolved.
Show resolved Hide resolved
let mut block_env = BlockEnv::default();
onbjerg marked this conversation as resolved.
Show resolved Hide resolved
let total_difficulty = U256::ZERO;

self.evm_config.fill_cfg_and_block_env(
&mut cfg_env,
&mut block_env,
&chain_spec,
&parent,
total_difficulty,
);

(cfg_env, block_env)
}
}

/// Constructs an Ethereum transaction payload from the transactions sent through the
Expand Down
53 changes: 0 additions & 53 deletions crates/optimism/payload/src/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,59 +106,6 @@ impl PayloadBuilderAttributes for OptimismPayloadBuilderAttributes {
fn withdrawals(&self) -> &Withdrawals {
&self.payload_attributes.withdrawals
}

fn cfg_and_block_env(
&self,
chain_spec: &ChainSpec,
parent: &Header,
) -> (CfgEnvWithHandlerCfg, BlockEnv) {
// configure evm env based on parent block
let cfg = CfgEnv::default().with_chain_id(chain_spec.chain().id());

// ensure we're not missing any timestamp based hardforks
let spec_id = revm_spec_by_timestamp_after_bedrock(chain_spec, self.timestamp());

// if the parent block did not have excess blob gas (i.e. it was pre-cancun), but it is
// cancun now, we need to set the excess blob gas to the default value
let blob_excess_gas_and_price = parent
.next_block_excess_blob_gas()
.or_else(|| {
if spec_id.is_enabled_in(SpecId::CANCUN) {
// default excess blob gas is zero
Some(0)
} else {
None
}
})
.map(BlobExcessGasAndPrice::new);

let block_env = BlockEnv {
number: U256::from(parent.number + 1),
coinbase: self.suggested_fee_recipient(),
timestamp: U256::from(self.timestamp()),
difficulty: U256::ZERO,
prevrandao: Some(self.prev_randao()),
gas_limit: U256::from(parent.gas_limit),
// calculate basefee based on parent block's gas usage
basefee: U256::from(
parent
.next_block_base_fee(chain_spec.base_fee_params_at_timestamp(self.timestamp()))
.unwrap_or_default(),
),
// calculate excess gas based on parent block's blob gas usage
blob_excess_gas_and_price,
};

let cfg_with_handler_cfg;
{
cfg_with_handler_cfg = CfgEnvWithHandlerCfg {
cfg_env: cfg,
handler_cfg: HandlerCfg { spec_id, is_optimism: true },
};
}

(cfg_with_handler_cfg, block_env)
}
}

/// Contains the built payload.
Expand Down
34 changes: 17 additions & 17 deletions crates/payload/basic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use reth_payload_builder::{
use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes};
use reth_primitives::{
constants::{EMPTY_WITHDRAWALS, RETH_CLIENT_VERSION, SLOT_DURATION},
proofs, BlockNumberOrTag, Bytes, SealedBlock, Withdrawals, B256, U256,
proofs, BlockNumberOrTag, Bytes, Header, SealedBlock, Withdrawals, B256, U256,
};
use reth_provider::{
BlockReaderIdExt, BlockSource, CanonStateNotification, ProviderError, StateProviderFactory,
Expand Down Expand Up @@ -673,10 +673,6 @@ impl Drop for Cancelled {
/// Static config for how to build a payload.
#[derive(Clone, Debug)]
pub struct PayloadConfig<Attributes> {
/// Pre-configured block environment.
pub initialized_block_env: BlockEnv,
/// Configuration for the environment.
pub initialized_cfg: CfgEnvWithHandlerCfg,
mattsse marked this conversation as resolved.
Show resolved Hide resolved
/// The parent block.
pub parent_block: Arc<SealedBlock>,
/// Block extra data.
Expand Down Expand Up @@ -705,18 +701,7 @@ where
attributes: Attributes,
chain_spec: Arc<ChainSpec>,
) -> Self {
// configure evm env based on parent block
let (initialized_cfg, initialized_block_env) =
attributes.cfg_and_block_env(&chain_spec, &parent_block);

Self {
initialized_block_env,
initialized_cfg,
parent_block,
extra_data,
attributes,
chain_spec,
}
Self { parent_block, extra_data, attributes, chain_spec }
}

/// Returns the payload id.
Expand Down Expand Up @@ -828,6 +813,21 @@ pub trait PayloadBuilder<Pool, Client>: Send + Sync + Clone {
client: &Client,
config: PayloadConfig<Self::Attributes>,
) -> Result<Self::BuiltPayload, PayloadBuilderError>;

/// Returns the configured [`CfgEnvWithHandlerCfg`] and [`BlockEnv`] for the targeted payload
/// (that has the `parent` as its parent).
///
/// The `chain_spec` is used to determine the correct chain id and hardfork for the payload
/// based on its timestamp.
///
/// Block related settings are derived from the `parent` block and the configured attributes.
///
/// NOTE: This is only intended for beacon consensus (after merge).
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have enough context to meaningfully update this comment so please suggest alternatives.

fn cfg_and_block_env(
&self,
chain_spec: &ChainSpec,
parent: &Header,
) -> (CfgEnvWithHandlerCfg, BlockEnv);
}

/// Tells the payload builder how to react to payload request if there's no payload available yet.
Expand Down
20 changes: 1 addition & 19 deletions crates/payload/primitives/src/traits.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use reth_chain_state::ExecutedBlock;
use reth_chainspec::ChainSpec;
use reth_primitives::{
revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg},
Address, Header, SealedBlock, Withdrawals, B256, U256,
};
use reth_primitives::{Address, SealedBlock, Withdrawals, B256, U256};
use reth_rpc_types::{
engine::{OptimismPayloadAttributes, PayloadAttributes as EthPayloadAttributes, PayloadId},
Withdrawal,
Expand Down Expand Up @@ -69,21 +66,6 @@ pub trait PayloadBuilderAttributes: Send + Sync + std::fmt::Debug {

/// Returns the withdrawals for the running payload job.
fn withdrawals(&self) -> &Withdrawals;

/// Returns the configured [`CfgEnvWithHandlerCfg`] and [`BlockEnv`] for the targeted payload
/// (that has the `parent` as its parent).
///
/// The `chain_spec` is used to determine the correct chain id and hardfork for the payload
/// based on its timestamp.
///
/// Block related settings are derived from the `parent` block and the configured attributes.
///
/// NOTE: This is only intended for beacon consensus (after merge).
fn cfg_and_block_env(
&self,
chain_spec: &ChainSpec,
parent: &Header,
) -> (CfgEnvWithHandlerCfg, BlockEnv);
}

/// The execution payload attribute type the CL node emits via the engine API.
Expand Down
Loading
Loading