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

feat: support time-based forking #985

Merged
merged 17 commits into from
Jan 27, 2023
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
6 changes: 3 additions & 3 deletions bin/reth/src/test_eth_chain/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use reth_db::{
Error as DbError,
};
use reth_primitives::{
keccak256, Account as RethAccount, Address, ChainSpec, JsonU256, SealedBlock, SealedHeader,
StorageEntry, H256, U256,
keccak256, Account as RethAccount, Address, ChainSpec, Hardfork, JsonU256, SealedBlock,
SealedHeader, StorageEntry, H256, U256,
};
use reth_rlp::Decodable;
use reth_stages::{stages::execution::ExecutionStage, ExecInput, Stage, StageId, Transaction};
Expand Down Expand Up @@ -125,7 +125,7 @@ pub async fn run_test(path: PathBuf) -> eyre::Result<TestOutcome> {

let chain_spec: ChainSpec = suite.network.into();
// if paris aka merge is not activated we dont have block rewards;
let has_block_reward = chain_spec.paris_status().block_number().is_some();
let has_block_reward = chain_spec.fork_block(Hardfork::MergeNetsplit).is_some();

// Create db and acquire transaction
let db = create_test_rw_db::<WriteMap>();
Expand Down
6 changes: 3 additions & 3 deletions crates/consensus/src/consensus.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Consensus for ethereum network
use crate::verification;
use reth_interfaces::consensus::{Consensus, Error, ForkchoiceState};
use reth_primitives::{BlockNumber, ChainSpec, SealedBlock, SealedHeader, H256};
use reth_primitives::{BlockNumber, ChainSpec, Hardfork, SealedBlock, SealedHeader, H256};
use tokio::sync::{watch, watch::error::SendError};

/// Ethereum beacon consensus
Expand Down Expand Up @@ -46,7 +46,7 @@ impl Consensus for BeaconConsensus {
verification::validate_header_standalone(header, &self.chain_spec)?;
verification::validate_header_regarding_parent(parent, header, &self.chain_spec)?;

if Some(header.number) < self.chain_spec.paris_status().block_number() {
if !self.chain_spec.fork_active(Hardfork::MergeNetsplit, header.number.into()) {
leruaa marked this conversation as resolved.
Show resolved Hide resolved
// TODO Consensus checks for old blocks:
// * difficulty, mix_hash & nonce aka PoW stuff
// low priority as syncing is done in reverse order
Expand All @@ -59,6 +59,6 @@ impl Consensus for BeaconConsensus {
}

fn has_block_reward(&self, block_num: BlockNumber) -> bool {
Some(block_num) < self.chain_spec.paris_status().block_number()
!self.chain_spec.fork_active(Hardfork::MergeNetsplit, block_num.into())
leruaa marked this conversation as resolved.
Show resolved Hide resolved
}
}
25 changes: 7 additions & 18 deletions crates/consensus/src/engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ impl<Client: HeaderProvider + BlockProvider + StateProvider> ConsensusEngine
};

if let Some(parent_td) = self.client.header_td(&block.parent_hash)? {
if Some(parent_td) <= self.chain_spec.paris_status().terminal_total_difficulty() {
if Some(parent_td) <= self.chain_spec.terminal_total_difficulty() {
return Ok(PayloadStatus::from_status(PayloadStatusEnum::Invalid {
validation_error: EngineApiError::PayloadPreMerge.to_string(),
}))
Expand Down Expand Up @@ -271,7 +271,6 @@ impl<Client: HeaderProvider + BlockProvider + StateProvider> ConsensusEngine

let merge_terminal_td = self
.chain_spec
.paris_status()
.terminal_total_difficulty()
.ok_or(EngineApiError::UnknownMergeTerminalTotalDifficulty)?;

Expand Down Expand Up @@ -516,8 +515,7 @@ mod tests {

let (result_tx, result_rx) = oneshot::channel();
let parent = transform_block(random_block(100, None, None, Some(0)), |mut b| {
b.header.difficulty =
chain_spec.paris_status().terminal_total_difficulty().unwrap();
b.header.difficulty = chain_spec.terminal_total_difficulty().unwrap();
b
});
let block = random_block(101, Some(parent.hash()), None, Some(0));
Expand Down Expand Up @@ -555,7 +553,7 @@ mod tests {
let parent = transform_block(random_block(100, None, None, Some(0)), |mut b| {
b.header.timestamp = parent_timestamp;
b.header.difficulty =
chain_spec.paris_status().terminal_total_difficulty().unwrap() + U256::from(1);
chain_spec.terminal_total_difficulty().unwrap() + U256::from(1);
b
});
let block =
Expand Down Expand Up @@ -633,10 +631,7 @@ mod tests {
tokio::spawn(engine);

let transition_config = TransitionConfiguration {
terminal_total_difficulty: chain_spec
.paris_status()
.terminal_total_difficulty()
.unwrap() +
terminal_total_difficulty: chain_spec.terminal_total_difficulty().unwrap() +
U256::from(1),
..Default::default()
};
Expand All @@ -651,7 +646,7 @@ mod tests {
assert_matches!(
result_rx.await,
Ok(Err(EngineApiError::TerminalTD { execution, consensus }))
if execution == chain_spec.paris_status().terminal_total_difficulty().unwrap()
if execution == chain_spec.terminal_total_difficulty().unwrap()
&& consensus == U256::from(transition_config.terminal_total_difficulty)
);
}
Expand All @@ -675,10 +670,7 @@ mod tests {
let execution_terminal_block = random_block(terminal_block_number, None, None, None);

let transition_config = TransitionConfiguration {
terminal_total_difficulty: chain_spec
.paris_status()
.terminal_total_difficulty()
.unwrap(),
terminal_total_difficulty: chain_spec.terminal_total_difficulty().unwrap(),
terminal_block_hash: consensus_terminal_block.hash(),
terminal_block_number: terminal_block_number.into(),
};
Expand Down Expand Up @@ -737,10 +729,7 @@ mod tests {
let terminal_block = random_block(terminal_block_number, None, None, None);

let transition_config = TransitionConfiguration {
terminal_total_difficulty: chain_spec
.paris_status()
.terminal_total_difficulty()
.unwrap(),
terminal_total_difficulty: chain_spec.terminal_total_difficulty().unwrap(),
terminal_block_hash: terminal_block.hash(),
terminal_block_number: terminal_block_number.into(),
};
Expand Down
15 changes: 8 additions & 7 deletions crates/consensus/src/verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,15 @@ pub fn validate_header_standalone(
}

// Check if base fee is set.
if chain_spec.fork_active(Hardfork::London, header.number) && header.base_fee_per_gas.is_none()
if chain_spec.fork_active(Hardfork::London, header.number.into()) &&
header.base_fee_per_gas.is_none()
{
return Err(Error::BaseFeeMissing)
}

// EIP-3675: Upgrade consensus to Proof-of-Stake:
// https://eips.ethereum.org/EIPS/eip-3675#replacing-difficulty-with-0
if Some(header.number) >= chain_spec.paris_status().block_number() {
if chain_spec.fork_active(Hardfork::MergeNetsplit, header.number.into()) {
leruaa marked this conversation as resolved.
Show resolved Hide resolved
if header.difficulty != U256::ZERO {
return Err(Error::TheMergeDifficultyIsNotZero)
}
Expand Down Expand Up @@ -78,7 +79,7 @@ pub fn validate_transaction_regarding_header(
let chain_id = match transaction {
Transaction::Legacy(TxLegacy { chain_id, .. }) => {
// EIP-155: Simple replay attack protection: https://eips.ethereum.org/EIPS/eip-155
if chain_spec.fork_active(Hardfork::SpuriousDragon, at_block_number) &&
if chain_spec.fork_active(Hardfork::SpuriousDragon, at_block_number.into()) &&
chain_id.is_some()
{
return Err(Error::TransactionOldLegacyChainId)
Expand All @@ -87,7 +88,7 @@ pub fn validate_transaction_regarding_header(
}
Transaction::Eip2930(TxEip2930 { chain_id, .. }) => {
// EIP-2930: Optional access lists: https://eips.ethereum.org/EIPS/eip-2930 (New transaction type)
if !chain_spec.fork_active(Hardfork::Berlin, at_block_number) {
if !chain_spec.fork_active(Hardfork::Berlin, at_block_number.into()) {
return Err(Error::TransactionEip2930Disabled)
}
Some(*chain_id)
Expand All @@ -99,7 +100,7 @@ pub fn validate_transaction_regarding_header(
..
}) => {
// EIP-1559: Fee market change for ETH 1.0 chain https://eips.ethereum.org/EIPS/eip-1559
if !chain_spec.fork_active(Hardfork::Berlin, at_block_number) {
if !chain_spec.fork_active(Hardfork::Berlin, at_block_number.into()) {
return Err(Error::TransactionEip1559Disabled)
}

Expand Down Expand Up @@ -259,7 +260,7 @@ pub fn validate_header_regarding_parent(
}

// difficulty check is done by consensus.
if chain_spec.paris_status().block_number() > Some(child.number) {
if !chain_spec.fork_active(Hardfork::MergeNetsplit, child.number.into()) {
leruaa marked this conversation as resolved.
Show resolved Hide resolved
// TODO how this needs to be checked? As ice age did increment it by some formula
}

Expand Down Expand Up @@ -287,7 +288,7 @@ pub fn validate_header_regarding_parent(
}

// EIP-1559 check base fee
if chain_spec.fork_active(Hardfork::London, child.number) {
if chain_spec.fork_active(Hardfork::London, child.number.into()) {
let base_fee = child.base_fee_per_gas.ok_or(Error::BaseFeeMissing)?;

let expected_base_fee = if chain_spec.fork_block(Hardfork::London) == Some(child.number) {
Expand Down
Loading