feat: support time-based forking (#985)

This commit is contained in:
Aurélien
2023-01-27 16:49:54 +01:00
committed by GitHub
parent 8cfe24081e
commit 9cdead5646
17 changed files with 453 additions and 312 deletions

View File

@@ -1,6 +1,6 @@
//! Reth block execution/validation configuration and constants
use reth_primitives::{BlockNumber, ChainSpec, Hardfork};
use reth_primitives::{ChainSpec, ForkDiscriminant, Hardfork};
/// Two ethereum worth of wei
pub const WEI_2ETH: u128 = 2000000000000000000u128;
@@ -10,19 +10,19 @@ pub const WEI_3ETH: u128 = 3000000000000000000u128;
pub const WEI_5ETH: u128 = 5000000000000000000u128;
/// return revm_spec from spec configuration.
pub fn revm_spec(chain_spec: &ChainSpec, for_block: BlockNumber) -> revm::SpecId {
match for_block {
b if chain_spec.fork_active(Hardfork::Shanghai, b) => revm::MERGE_EOF,
b if Some(b) >= chain_spec.paris_status().block_number() => revm::MERGE,
b if chain_spec.fork_active(Hardfork::London, b) => revm::LONDON,
b if chain_spec.fork_active(Hardfork::Berlin, b) => revm::BERLIN,
b if chain_spec.fork_active(Hardfork::Istanbul, b) => revm::ISTANBUL,
b if chain_spec.fork_active(Hardfork::Petersburg, b) => revm::PETERSBURG,
b if chain_spec.fork_active(Hardfork::Byzantium, b) => revm::BYZANTIUM,
b if chain_spec.fork_active(Hardfork::SpuriousDragon, b) => revm::SPURIOUS_DRAGON,
b if chain_spec.fork_active(Hardfork::Tangerine, b) => revm::TANGERINE,
b if chain_spec.fork_active(Hardfork::Homestead, b) => revm::HOMESTEAD,
b if chain_spec.fork_active(Hardfork::Frontier, b) => revm::FRONTIER,
pub fn revm_spec(chain_spec: &ChainSpec, discriminant: ForkDiscriminant) -> revm::SpecId {
match discriminant {
d if chain_spec.fork_active(Hardfork::Shanghai, d) => revm::MERGE_EOF,
d if chain_spec.fork_active(Hardfork::Paris, d) => revm::MERGE,
d if chain_spec.fork_active(Hardfork::London, d) => revm::LONDON,
d if chain_spec.fork_active(Hardfork::Berlin, d) => revm::BERLIN,
d if chain_spec.fork_active(Hardfork::Istanbul, d) => revm::ISTANBUL,
d if chain_spec.fork_active(Hardfork::Petersburg, d) => revm::PETERSBURG,
d if chain_spec.fork_active(Hardfork::Byzantium, d) => revm::BYZANTIUM,
d if chain_spec.fork_active(Hardfork::SpuriousDragon, d) => revm::SPURIOUS_DRAGON,
d if chain_spec.fork_active(Hardfork::Tangerine, d) => revm::TANGERINE,
d if chain_spec.fork_active(Hardfork::Homestead, d) => revm::HOMESTEAD,
d if chain_spec.fork_active(Hardfork::Frontier, d) => revm::FRONTIER,
_ => panic!("wrong configuration"),
}
}
@@ -30,62 +30,106 @@ pub fn revm_spec(chain_spec: &ChainSpec, for_block: BlockNumber) -> revm::SpecId
#[cfg(test)]
mod tests {
use crate::config::revm_spec;
use reth_primitives::{ChainSpecBuilder, MAINNET};
use reth_primitives::{ChainSpecBuilder, ForkDiscriminant, MAINNET, U256};
#[test]
fn test_to_revm_spec() {
let discriminant = ForkDiscriminant::new(1, U256::from(1), 1);
assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().paris_activated().build(), 1),
revm_spec(&ChainSpecBuilder::mainnet().shangai_activated().build(), discriminant),
revm::MERGE_EOF
);
assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().paris_activated().build(), discriminant),
revm::MERGE
);
assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().london_activated().build(), 1),
revm_spec(&ChainSpecBuilder::mainnet().london_activated().build(), discriminant),
revm::LONDON
);
assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().berlin_activated().build(), 1),
revm_spec(&ChainSpecBuilder::mainnet().berlin_activated().build(), discriminant),
revm::BERLIN
);
assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().istanbul_activated().build(), 1),
revm_spec(&ChainSpecBuilder::mainnet().istanbul_activated().build(), discriminant),
revm::ISTANBUL
);
assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().petersburg_activated().build(), 1),
revm_spec(&ChainSpecBuilder::mainnet().petersburg_activated().build(), discriminant),
revm::PETERSBURG
);
assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().byzantium_activated().build(), 1),
revm_spec(&ChainSpecBuilder::mainnet().byzantium_activated().build(), discriminant),
revm::BYZANTIUM
);
assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().spurious_dragon_activated().build(), 1),
revm_spec(
&ChainSpecBuilder::mainnet().spurious_dragon_activated().build(),
discriminant
),
revm::SPURIOUS_DRAGON
);
assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().tangerine_whistle_activated().build(), 1),
revm_spec(
&ChainSpecBuilder::mainnet().tangerine_whistle_activated().build(),
discriminant
),
revm::TANGERINE
);
assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().homestead_activated().build(), 1),
revm_spec(&ChainSpecBuilder::mainnet().homestead_activated().build(), discriminant),
revm::HOMESTEAD
);
assert_eq!(
revm_spec(&ChainSpecBuilder::mainnet().frontier_activated().build(), 1),
revm_spec(&ChainSpecBuilder::mainnet().frontier_activated().build(), discriminant),
revm::FRONTIER
);
}
#[test]
fn test_eth_spec() {
assert_eq!(revm_spec(&MAINNET, 15537394 + 10), revm::MERGE);
assert_eq!(revm_spec(&MAINNET, 15537394 - 10), revm::LONDON);
assert_eq!(revm_spec(&MAINNET, 12244000 + 10), revm::BERLIN);
assert_eq!(revm_spec(&MAINNET, 12244000 - 10), revm::ISTANBUL);
assert_eq!(revm_spec(&MAINNET, 7280000 + 10), revm::PETERSBURG);
assert_eq!(revm_spec(&MAINNET, 7280000 - 10), revm::BYZANTIUM);
assert_eq!(revm_spec(&MAINNET, 2675000 + 10), revm::SPURIOUS_DRAGON);
assert_eq!(revm_spec(&MAINNET, 2675000 - 10), revm::TANGERINE);
assert_eq!(revm_spec(&MAINNET, 1150000 + 10), revm::HOMESTEAD);
assert_eq!(revm_spec(&MAINNET, 1150000 - 10), revm::FRONTIER);
let post_merge_td = MAINNET.terminal_total_difficulty().unwrap();
let pre_merge_td = post_merge_td.saturating_sub(U256::from(10));
assert_eq!(
revm_spec(&MAINNET, ForkDiscriminant::new(15537394 + 10, post_merge_td, 1674477448)),
revm::MERGE
);
assert_eq!(
revm_spec(&MAINNET, ForkDiscriminant::new(15537394 - 10, pre_merge_td, 1674477448)),
revm::LONDON
);
assert_eq!(
revm_spec(&MAINNET, ForkDiscriminant::new(12244000 + 10, pre_merge_td, 1674477448)),
revm::BERLIN
);
assert_eq!(
revm_spec(&MAINNET, ForkDiscriminant::new(12244000 - 10, pre_merge_td, 1674477448)),
revm::ISTANBUL
);
assert_eq!(
revm_spec(&MAINNET, ForkDiscriminant::new(7280000 + 10, pre_merge_td, 1674477448)),
revm::PETERSBURG
);
assert_eq!(
revm_spec(&MAINNET, ForkDiscriminant::new(7280000 - 10, pre_merge_td, 1674477448)),
revm::BYZANTIUM
);
assert_eq!(
revm_spec(&MAINNET, ForkDiscriminant::new(2675000 + 10, pre_merge_td, 1674477448)),
revm::SPURIOUS_DRAGON
);
assert_eq!(
revm_spec(&MAINNET, ForkDiscriminant::new(2675000 - 10, pre_merge_td, 1674477448)),
revm::TANGERINE
);
assert_eq!(
revm_spec(&MAINNET, ForkDiscriminant::new(1150000 + 10, pre_merge_td, 1674477448)),
revm::HOMESTEAD
);
assert_eq!(
revm_spec(&MAINNET, ForkDiscriminant::new(1150000 - 10, pre_merge_td, 1674477448)),
revm::FRONTIER
);
}
}

View File

@@ -302,7 +302,7 @@ pub fn execute<DB: StateProvider>(
let mut evm = EVM::new();
evm.database(db);
let spec_id = revm_spec(chain_spec, header.number);
let spec_id = revm_spec(chain_spec, header.into());
evm.env.cfg.chain_id = U256::from(chain_spec.chain().id());
evm.env.cfg.spec_id = spec_id;
evm.env.cfg.perf_all_precompiles_have_balance = false;
@@ -451,10 +451,10 @@ pub fn block_reward_changeset<DB: StateProvider>(
// amount. We raise the blocks beneficiary account by Rblock; for each ommer, we raise the
// blocks beneficiary by an additional 1/32 of the block reward and the beneficiary of the
// ommer gets rewarded depending on the blocknumber. Formally we define the function Ω:
match header.number {
n if Some(n) >= chain_spec.paris_status().block_number() => None,
n if Some(n) >= chain_spec.fork_block(Hardfork::Petersburg) => Some(WEI_2ETH),
n if Some(n) >= chain_spec.fork_block(Hardfork::Byzantium) => Some(WEI_3ETH),
match header.into() {
d if chain_spec.fork_active(Hardfork::Paris, d) => None,
d if chain_spec.fork_active(Hardfork::Petersburg, d) => Some(WEI_2ETH),
d if chain_spec.fork_active(Hardfork::Byzantium, d) => Some(WEI_3ETH),
_ => Some(WEI_5ETH),
}
.map(|reward| -> Result<_, _> {
@@ -538,8 +538,8 @@ mod tests {
transaction::DbTx,
};
use reth_primitives::{
hex_literal::hex, keccak256, Account, Address, Bytes, ChainSpecBuilder, SealedBlock,
StorageKey, H160, H256, MAINNET, U256,
hex_literal::hex, keccak256, Account, Address, Bytes, ChainSpecBuilder, ForkKind,
SealedBlock, StorageKey, H160, H256, MAINNET, U256,
};
use reth_provider::{AccountProvider, BlockHashProvider, StateProvider};
use reth_rlp::Decodable;
@@ -776,7 +776,7 @@ mod tests {
let chain_spec = ChainSpecBuilder::from(&*MAINNET)
.homestead_activated()
.with_fork(Hardfork::Dao, 1)
.with_fork(Hardfork::Dao, ForkKind::Block(1))
.build();
let mut db = SubState::new(State::new(db));