feat(ethereum-forks): remove total difficulty for hardfork check (#13362)

Co-authored-by: Dan Cline <6798349+Rjected@users.noreply.github.com>
This commit is contained in:
Kunal Arora
2024-12-20 20:58:05 +05:30
committed by GitHub
parent dc6394b05b
commit 82af170687
44 changed files with 382 additions and 646 deletions

View File

@ -26,7 +26,7 @@ use reth_primitives::{BlockWithSenders, EthPrimitives, Receipt};
use reth_revm::db::State;
use revm_primitives::{
db::{Database, DatabaseCommit},
EnvWithHandlerCfg, ResultAndState, U256,
EnvWithHandlerCfg, ResultAndState,
};
/// Factory for [`EthExecutionStrategy`].
@ -123,13 +123,9 @@ where
/// # Caution
///
/// This does not initialize the tx environment.
fn evm_env_for_block(
&self,
header: &alloy_consensus::Header,
total_difficulty: U256,
) -> EnvWithHandlerCfg {
fn evm_env_for_block(&self, header: &alloy_consensus::Header) -> EnvWithHandlerCfg {
let EvmEnv { cfg_env_with_handler_cfg, block_env } =
self.evm_config.cfg_and_block_env(header, total_difficulty);
self.evm_config.cfg_and_block_env(header);
EnvWithHandlerCfg::new_with_cfg_env(cfg_env_with_handler_cfg, block_env, Default::default())
}
}
@ -151,17 +147,13 @@ where
self.tx_env_overrides = Some(tx_env_overrides);
}
fn apply_pre_execution_changes(
&mut self,
block: &BlockWithSenders,
total_difficulty: U256,
) -> Result<(), Self::Error> {
fn apply_pre_execution_changes(&mut self, block: &BlockWithSenders) -> Result<(), Self::Error> {
// Set state clear flag if the block is after the Spurious Dragon hardfork.
let state_clear_flag =
(*self.chain_spec).is_spurious_dragon_active_at_block(block.header.number);
self.state.set_state_clear_flag(state_clear_flag);
let env = self.evm_env_for_block(&block.header, total_difficulty);
let env = self.evm_env_for_block(&block.header);
let mut evm = self.evm_config.evm_with_env(&mut self.state, env);
self.system_caller.apply_pre_execution_changes(&block.block, &mut evm)?;
@ -172,9 +164,8 @@ where
fn execute_transactions(
&mut self,
block: &BlockWithSenders,
total_difficulty: U256,
) -> Result<ExecuteOutput<Receipt>, Self::Error> {
let env = self.evm_env_for_block(&block.header, total_difficulty);
let env = self.evm_env_for_block(&block.header);
let mut evm = self.evm_config.evm_with_env(&mut self.state, env);
let mut cumulative_gas_used = 0;
@ -234,10 +225,9 @@ where
fn apply_post_execution_changes(
&mut self,
block: &BlockWithSenders,
total_difficulty: U256,
receipts: &[Receipt],
) -> Result<Requests, Self::Error> {
let env = self.evm_env_for_block(&block.header, total_difficulty);
let env = self.evm_env_for_block(&block.header);
let mut evm = self.evm_config.evm_with_env(&mut self.state, env);
let requests = if self.chain_spec.is_prague_active_at_timestamp(block.timestamp) {
@ -258,8 +248,7 @@ where
};
drop(evm);
let mut balance_increments =
post_block_balance_increments(&self.chain_spec, &block.block, total_difficulty);
let mut balance_increments = post_block_balance_increments(&self.chain_spec, &block.block);
// Irregular state change at Ethereum DAO hardfork
if self.chain_spec.fork(EthereumHardfork::Dao).transitions_at_block(block.number) {
@ -337,7 +326,7 @@ mod tests {
eip7002::{WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, WITHDRAWAL_REQUEST_PREDEPLOY_CODE},
eip7685::EMPTY_REQUESTS_HASH,
};
use alloy_primitives::{b256, fixed_bytes, keccak256, Bytes, TxKind, B256};
use alloy_primitives::{b256, fixed_bytes, keccak256, Bytes, TxKind, B256, U256};
use reth_chainspec::{ChainSpecBuilder, ForkCondition};
use reth_evm::execute::{
BasicBlockExecutorProvider, BatchExecutor, BlockExecutorProvider, Executor,
@ -421,23 +410,13 @@ mod tests {
// attempt to execute a block without parent beacon block root, expect err
let err = executor
.execute_and_verify_one(
(
&BlockWithSenders::new_unchecked(
Block {
header: header.clone(),
body: BlockBody {
transactions: vec![],
ommers: vec![],
withdrawals: None,
},
},
vec![],
),
U256::ZERO,
)
.into(),
)
.execute_and_verify_one(&BlockWithSenders::new_unchecked(
Block {
header: header.clone(),
body: BlockBody { transactions: vec![], ommers: vec![], withdrawals: None },
},
vec![],
))
.expect_err(
"Executing cancun block without parent beacon block root field should fail",
);
@ -452,23 +431,13 @@ mod tests {
// Now execute a block with the fixed header, ensure that it does not fail
executor
.execute_and_verify_one(
(
&BlockWithSenders::new_unchecked(
Block {
header: header.clone(),
body: BlockBody {
transactions: vec![],
ommers: vec![],
withdrawals: None,
},
},
vec![],
),
U256::ZERO,
)
.into(),
)
.execute_and_verify_one(&BlockWithSenders::new_unchecked(
Block {
header: header.clone(),
body: BlockBody { transactions: vec![], ommers: vec![], withdrawals: None },
},
vec![],
))
.unwrap();
// check the actual storage of the contract - it should be:
@ -522,23 +491,13 @@ mod tests {
// attempt to execute an empty block with parent beacon block root, this should not fail
provider
.batch_executor(StateProviderDatabase::new(&db))
.execute_and_verify_one(
(
&BlockWithSenders::new_unchecked(
Block {
header,
body: BlockBody {
transactions: vec![],
ommers: vec![],
withdrawals: None,
},
},
vec![],
),
U256::ZERO,
)
.into(),
)
.execute_and_verify_one(&BlockWithSenders::new_unchecked(
Block {
header,
body: BlockBody { transactions: vec![], ommers: vec![], withdrawals: None },
},
vec![],
))
.expect(
"Executing a block with no transactions while cancun is active should not fail",
);
@ -576,23 +535,13 @@ mod tests {
// attempt to execute an empty block with parent beacon block root, this should not fail
executor
.execute_and_verify_one(
(
&BlockWithSenders::new_unchecked(
Block {
header,
body: BlockBody {
transactions: vec![],
ommers: vec![],
withdrawals: None,
},
},
vec![],
),
U256::ZERO,
)
.into(),
)
.execute_and_verify_one(&BlockWithSenders::new_unchecked(
Block {
header,
body: BlockBody { transactions: vec![], ommers: vec![], withdrawals: None },
},
vec![],
))
.expect(
"Executing a block with no transactions while cancun is active should not fail",
);
@ -622,16 +571,10 @@ mod tests {
// attempt to execute the genesis block with non-zero parent beacon block root, expect err
header.parent_beacon_block_root = Some(B256::with_last_byte(0x69));
let _err = executor
.execute_and_verify_one(
(
&BlockWithSenders::new_unchecked(
Block { header: header.clone(), body: Default::default() },
vec![],
),
U256::ZERO,
)
.into(),
)
.execute_and_verify_one(&BlockWithSenders::new_unchecked(
Block { header: header.clone(), body: Default::default() },
vec![],
))
.expect_err(
"Executing genesis cancun block with non-zero parent beacon block root field
should fail",
@ -643,16 +586,10 @@ mod tests {
// now try to process the genesis block again, this time ensuring that a system contract
// call does not occur
executor
.execute_and_verify_one(
(
&BlockWithSenders::new_unchecked(
Block { header, body: Default::default() },
vec![],
),
U256::ZERO,
)
.into(),
)
.execute_and_verify_one(&BlockWithSenders::new_unchecked(
Block { header, body: Default::default() },
vec![],
))
.unwrap();
// there is no system contract call so there should be NO STORAGE CHANGES
@ -697,16 +634,10 @@ mod tests {
// Now execute a block with the fixed header, ensure that it does not fail
executor
.execute_and_verify_one(
(
&BlockWithSenders::new_unchecked(
Block { header: header.clone(), body: Default::default() },
vec![],
),
U256::ZERO,
)
.into(),
)
.execute_and_verify_one(&BlockWithSenders::new_unchecked(
Block { header: header.clone(), body: Default::default() },
vec![],
))
.unwrap();
// check the actual storage of the contract - it should be:
@ -773,16 +704,10 @@ mod tests {
// attempt to execute an empty block, this should not fail
executor
.execute_and_verify_one(
(
&BlockWithSenders::new_unchecked(
Block { header, body: Default::default() },
vec![],
),
U256::ZERO,
)
.into(),
)
.execute_and_verify_one(&BlockWithSenders::new_unchecked(
Block { header, body: Default::default() },
vec![],
))
.expect(
"Executing a block with no transactions while Prague is active should not fail",
);
@ -816,16 +741,10 @@ mod tests {
// attempt to execute genesis block, this should not fail
executor
.execute_and_verify_one(
(
&BlockWithSenders::new_unchecked(
Block { header, body: Default::default() },
vec![],
),
U256::ZERO,
)
.into(),
)
.execute_and_verify_one(&BlockWithSenders::new_unchecked(
Block { header, body: Default::default() },
vec![],
))
.expect(
"Executing a block with no transactions while Prague is active should not fail",
);
@ -866,16 +785,10 @@ mod tests {
// attempt to execute the fork activation block, this should not fail
executor
.execute_and_verify_one(
(
&BlockWithSenders::new_unchecked(
Block { header, body: Default::default() },
vec![],
),
U256::ZERO,
)
.into(),
)
.execute_and_verify_one(&BlockWithSenders::new_unchecked(
Block { header, body: Default::default() },
vec![],
))
.expect(
"Executing a block with no transactions while Prague is active should not fail",
);
@ -922,16 +835,10 @@ mod tests {
// attempt to execute the fork activation block, this should not fail
executor
.execute_and_verify_one(
(
&BlockWithSenders::new_unchecked(
Block { header, body: Default::default() },
vec![],
),
U256::ZERO,
)
.into(),
)
.execute_and_verify_one(&BlockWithSenders::new_unchecked(
Block { header, body: Default::default() },
vec![],
))
.expect(
"Executing a block with no transactions while Prague is active should not fail",
);
@ -970,16 +877,10 @@ mod tests {
// attempt to execute the genesis block, this should not fail
executor
.execute_and_verify_one(
(
&BlockWithSenders::new_unchecked(
Block { header, body: Default::default() },
vec![],
),
U256::ZERO,
)
.into(),
)
.execute_and_verify_one(&BlockWithSenders::new_unchecked(
Block { header, body: Default::default() },
vec![],
))
.expect(
"Executing a block with no transactions while Prague is active should not fail",
);
@ -1005,16 +906,10 @@ mod tests {
let header_hash = header.hash_slow();
executor
.execute_and_verify_one(
(
&BlockWithSenders::new_unchecked(
Block { header, body: Default::default() },
vec![],
),
U256::ZERO,
)
.into(),
)
.execute_and_verify_one(&BlockWithSenders::new_unchecked(
Block { header, body: Default::default() },
vec![],
))
.expect(
"Executing a block with no transactions while Prague is active should not fail",
);
@ -1043,16 +938,10 @@ mod tests {
};
executor
.execute_and_verify_one(
(
&BlockWithSenders::new_unchecked(
Block { header, body: Default::default() },
vec![],
),
U256::ZERO,
)
.into(),
)
.execute_and_verify_one(&BlockWithSenders::new_unchecked(
Block { header, body: Default::default() },
vec![],
))
.expect(
"Executing a block with no transactions while Prague is active should not fail",
);
@ -1133,16 +1022,9 @@ mod tests {
let BlockExecutionOutput { receipts, requests, .. } = executor
.execute(
(
&Block {
header,
body: BlockBody { transactions: vec![tx], ..Default::default() },
}
&Block { header, body: BlockBody { transactions: vec![tx], ..Default::default() } }
.with_recovered_senders()
.unwrap(),
U256::ZERO,
)
.into(),
)
.unwrap();
@ -1216,13 +1098,9 @@ mod tests {
// Execute the block and capture the result
let exec_result = executor.execute(
(
&Block { header, body: BlockBody { transactions: vec![tx], ..Default::default() } }
.with_recovered_senders()
.unwrap(),
U256::ZERO,
)
.into(),
&Block { header, body: BlockBody { transactions: vec![tx], ..Default::default() } }
.with_recovered_senders()
.unwrap(),
);
// Check if the execution result is an error and assert the specific error type
@ -1282,7 +1160,7 @@ mod tests {
let tx_clone = tx.clone();
let _output = executor
.execute_with_state_hook((block, U256::ZERO).into(), move |state: &EvmState| {
.execute_with_state_hook(block, move |state: &EvmState| {
if let Some(account) = state.get(&withdrawal_recipient) {
let _ = tx_clone.send(account.info.balance);
}