Add support for optimism granite hardfork (#10107)

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
Brian Bland
2024-08-09 03:51:27 -07:00
committed by GitHub
parent 7634995cee
commit 5716c20198
7 changed files with 85 additions and 23 deletions

View File

@ -758,6 +758,8 @@ impl From<Genesis> for ChainSpec {
(OptimismHardfork::Ecotone.boxed(), genesis_info.ecotone_time),
#[cfg(feature = "optimism")]
(OptimismHardfork::Fjord.boxed(), genesis_info.fjord_time),
#[cfg(feature = "optimism")]
(OptimismHardfork::Granite.boxed(), genesis_info.granite_time),
];
let time_hardforks = time_hardfork_opts
@ -1012,6 +1014,14 @@ impl ChainSpecBuilder {
self
}
/// Enable Granite at genesis
#[cfg(feature = "optimism")]
pub fn granite_activated(mut self) -> Self {
self = self.fjord_activated();
self.hardforks.insert(OptimismHardfork::Granite, ForkCondition::Timestamp(0));
self
}
/// Build the resulting [`ChainSpec`].
///
/// # Panics
@ -1719,7 +1729,15 @@ Post-merge hard forks (timestamp based):
),
(
Head { number: 0, timestamp: 1716998400, ..Default::default() },
ForkId { hash: ForkHash([0x54, 0x0a, 0x8c, 0x5d]), next: 0 },
ForkId { hash: ForkHash([0x54, 0x0a, 0x8c, 0x5d]), next: 1723478400 },
),
(
Head { number: 0, timestamp: 1723478399, ..Default::default() },
ForkId { hash: ForkHash([0x54, 0x0a, 0x8c, 0x5d]), next: 1723478400 },
),
(
Head { number: 0, timestamp: 1723478400, ..Default::default() },
ForkId { hash: ForkHash([0x75, 0xde, 0xa4, 0x1e]), next: 0 },
),
],
);
@ -1776,7 +1794,15 @@ Post-merge hard forks (timestamp based):
),
(
Head { number: 0, timestamp: 1716998400, ..Default::default() },
ForkId { hash: ForkHash([0x4e, 0x45, 0x7a, 0x49]), next: 0 },
ForkId { hash: ForkHash([0x4e, 0x45, 0x7a, 0x49]), next: 1723478400 },
),
(
Head { number: 0, timestamp: 1723478399, ..Default::default() },
ForkId { hash: ForkHash([0x4e, 0x45, 0x7a, 0x49]), next: 1723478400 },
),
(
Head { number: 0, timestamp: 1723478400, ..Default::default() },
ForkId { hash: ForkHash([0x5e, 0xdf, 0xa3, 0xb6]), next: 0 },
),
],
);
@ -2645,6 +2671,7 @@ Post-merge hard forks (timestamp based):
"canyonTime": 30,
"ecotoneTime": 40,
"fjordTime": 50,
"graniteTime": 51,
"optimism": {
"eip1559Elasticity": 60,
"eip1559Denominator": 70
@ -2664,6 +2691,8 @@ Post-merge hard forks (timestamp based):
assert_eq!(actual_ecotone_timestamp, Some(serde_json::Value::from(40)).as_ref());
let actual_fjord_timestamp = genesis.config.extra_fields.get("fjordTime");
assert_eq!(actual_fjord_timestamp, Some(serde_json::Value::from(50)).as_ref());
let actual_granite_timestamp = genesis.config.extra_fields.get("graniteTime");
assert_eq!(actual_granite_timestamp, Some(serde_json::Value::from(51)).as_ref());
let optimism_object = genesis.config.extra_fields.get("optimism").unwrap();
assert_eq!(
@ -2686,12 +2715,14 @@ Post-merge hard forks (timestamp based):
assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Canyon, 0));
assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Ecotone, 0));
assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Fjord, 0));
assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Granite, 0));
assert!(chain_spec.is_fork_active_at_block(OptimismHardfork::Bedrock, 10));
assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Regolith, 20));
assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Canyon, 30));
assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Ecotone, 40));
assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Fjord, 50));
assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Granite, 51));
}
#[cfg(feature = "optimism")]
@ -2705,6 +2736,7 @@ Post-merge hard forks (timestamp based):
"canyonTime": 30,
"ecotoneTime": 40,
"fjordTime": 50,
"graniteTime": 51,
"optimism": {
"eip1559Elasticity": 60,
"eip1559Denominator": 70,
@ -2725,6 +2757,8 @@ Post-merge hard forks (timestamp based):
assert_eq!(actual_ecotone_timestamp, Some(serde_json::Value::from(40)).as_ref());
let actual_fjord_timestamp = genesis.config.extra_fields.get("fjordTime");
assert_eq!(actual_fjord_timestamp, Some(serde_json::Value::from(50)).as_ref());
let actual_granite_timestamp = genesis.config.extra_fields.get("graniteTime");
assert_eq!(actual_granite_timestamp, Some(serde_json::Value::from(51)).as_ref());
let optimism_object = genesis.config.extra_fields.get("optimism").unwrap();
assert_eq!(
@ -2754,12 +2788,14 @@ Post-merge hard forks (timestamp based):
assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Canyon, 0));
assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Ecotone, 0));
assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Fjord, 0));
assert!(!chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Granite, 0));
assert!(chain_spec.is_fork_active_at_block(OptimismHardfork::Bedrock, 10));
assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Regolith, 20));
assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Canyon, 30));
assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Ecotone, 40));
assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Fjord, 50));
assert!(chain_spec.is_fork_active_at_timestamp(OptimismHardfork::Granite, 51));
}
#[cfg(feature = "optimism")]

View File

@ -101,13 +101,14 @@ mod tests {
#[test]
fn check_op_hardfork_from_str() {
let hardfork_str = ["beDrOck", "rEgOlITH", "cAnYoN", "eCoToNe", "FJorD"];
let hardfork_str = ["beDrOck", "rEgOlITH", "cAnYoN", "eCoToNe", "FJorD", "GRaNiTe"];
let expected_hardforks = [
OptimismHardfork::Bedrock,
OptimismHardfork::Regolith,
OptimismHardfork::Canyon,
OptimismHardfork::Ecotone,
OptimismHardfork::Fjord,
OptimismHardfork::Granite,
];
let hardforks: Vec<OptimismHardfork> =

View File

@ -27,6 +27,8 @@ hardfork!(
Ecotone,
/// Fjord: <https://github.com/ethereum-optimism/specs/blob/main/specs/protocol/superchain-upgrades.md#fjord>
Fjord,
/// Granite: <https://github.com/ethereum-optimism/specs/blob/main/specs/protocol/superchain-upgrades.md#granite>
Granite,
}
);
@ -84,6 +86,7 @@ impl OptimismHardfork {
Self::Canyon => Some(2106456),
Self::Ecotone => Some(6383256),
Self::Fjord => Some(10615056),
_ => None,
},
)
}
@ -150,6 +153,7 @@ impl OptimismHardfork {
Self::Canyon => Some(1699981200),
Self::Ecotone => Some(1708534800),
Self::Fjord => Some(1716998400),
Self::Granite => Some(1723478400),
},
)
}
@ -183,6 +187,7 @@ impl OptimismHardfork {
Self::Canyon => Some(1704992401),
Self::Ecotone => Some(1710374401),
Self::Fjord => Some(1720627201),
_ => None,
},
)
}
@ -244,6 +249,7 @@ impl OptimismHardfork {
(EthereumHardfork::Cancun.boxed(), ForkCondition::Timestamp(1708534800)),
(Self::Ecotone.boxed(), ForkCondition::Timestamp(1708534800)),
(Self::Fjord.boxed(), ForkCondition::Timestamp(1716998400)),
(Self::Granite.boxed(), ForkCondition::Timestamp(1723478400)),
])
}
@ -274,6 +280,7 @@ impl OptimismHardfork {
(EthereumHardfork::Cancun.boxed(), ForkCondition::Timestamp(1708534800)),
(Self::Ecotone.boxed(), ForkCondition::Timestamp(1708534800)),
(Self::Fjord.boxed(), ForkCondition::Timestamp(1716998400)),
(Self::Granite.boxed(), ForkCondition::Timestamp(1723478400)),
])
}

View File

@ -9,7 +9,9 @@ pub fn revm_spec_by_timestamp_after_bedrock(
chain_spec: &ChainSpec,
timestamp: u64,
) -> revm_primitives::SpecId {
if chain_spec.fork(OptimismHardfork::Fjord).active_at_timestamp(timestamp) {
if chain_spec.fork(OptimismHardfork::Granite).active_at_timestamp(timestamp) {
revm_primitives::GRANITE
} else if chain_spec.fork(OptimismHardfork::Fjord).active_at_timestamp(timestamp) {
revm_primitives::FJORD
} else if chain_spec.fork(OptimismHardfork::Ecotone).active_at_timestamp(timestamp) {
revm_primitives::ECOTONE
@ -24,7 +26,9 @@ pub fn revm_spec_by_timestamp_after_bedrock(
/// return `revm_spec` from spec configuration.
pub fn revm_spec(chain_spec: &ChainSpec, block: &Head) -> revm_primitives::SpecId {
if chain_spec.fork(OptimismHardfork::Fjord).active_at_head(block) {
if chain_spec.fork(OptimismHardfork::Granite).active_at_head(block) {
revm_primitives::GRANITE
} else if chain_spec.fork(OptimismHardfork::Fjord).active_at_head(block) {
revm_primitives::FJORD
} else if chain_spec.fork(OptimismHardfork::Ecotone).active_at_head(block) {
revm_primitives::ECOTONE
@ -80,6 +84,10 @@ mod tests {
let cs = ChainSpecBuilder::mainnet().chain(reth_chainspec::Chain::from_id(10));
f(cs).build()
}
assert_eq!(
revm_spec_by_timestamp_after_bedrock(&op_cs(|cs| cs.granite_activated()), 0),
revm_primitives::GRANITE
);
assert_eq!(
revm_spec_by_timestamp_after_bedrock(&op_cs(|cs| cs.fjord_activated()), 0),
revm_primitives::FJORD
@ -109,6 +117,10 @@ mod tests {
let cs = ChainSpecBuilder::mainnet().chain(reth_chainspec::Chain::from_id(10));
f(cs).build()
}
assert_eq!(
revm_spec(&op_cs(|cs| cs.granite_activated()), &Head::default()),
revm_primitives::GRANITE
);
assert_eq!(
revm_spec(&op_cs(|cs| cs.fjord_activated()), &Head::default()),
revm_primitives::FJORD

View File

@ -78,7 +78,10 @@ pub struct RollupConfig {
pub block_time: u64,
pub max_sequencer_drift: u64,
pub seq_window_size: u64,
pub channel_timeout: u64,
#[serde(rename = "channel_timeout")]
pub channel_timeout_bedrock: u64,
pub channel_timeout_granite: u64,
/// todo use u128 to represent *big.Int?
#[serde(default, skip_serializing_if = "Option::is_none")]
pub l1_chain_id: Option<u128>,
@ -96,6 +99,8 @@ pub struct RollupConfig {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub fjord_time: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub granite_time: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub interop_time: Option<u64>,
pub batch_inbox_address: Address,
pub deposit_contract_address: Address,
@ -333,7 +338,7 @@ mod tests {
#[test]
fn test_rollup_config() {
let rollup_config_json = r#"{"genesis":{"l1":{"blockHash":"0x438335a20d98863a4c0c97999eb2481921ccd28553eac6f913af7c12aec04108"},"l2":{"blockHash":"0xdbf6a80fef073de06add9b0d14026d6e5a86c85f6d102c36d3d8e9cf89c2afd3"},"l2_time":1686068903,"system_config":{"batcherAddr":"0x6887246668a3b87f54deb3b94ba47a6f63f32985","overhead":"0x00000000000000000000000000000000000000000000000000000000000000bc","scalar":"0x00000000000000000000000000000000000000000000000000000000000a6fe0","gasLimit":30000000}},"block_time":2,"max_sequencer_drift":600,"seq_window_size":3600,"channel_timeout":300,"l1_chain_id":1,"l2_chain_id":10,"regolith_time":0,"canyon_time":1704992401,"delta_time":1708560000,"ecotone_time":1710374401,"batch_inbox_address":"0xff00000000000000000000000000000000000010","deposit_contract_address":"0xbeb5fc579115071764c7423a4f12edde41f106ed","l1_system_config_address":"0x229047fed2591dbec1ef1118d64f7af3db9eb290","protocol_versions_address":"0x8062abc286f5e7d9428a0ccb9abd71e50d93b935","da_challenge_address":"0x0000000000000000000000000000000000000000","da_challenge_window":0,"da_resolve_window":0,"use_plasma":false}"#;
let rollup_config_json = r#"{"genesis":{"l1":{"blockHash":"0x438335a20d98863a4c0c97999eb2481921ccd28553eac6f913af7c12aec04108"},"l2":{"blockHash":"0xdbf6a80fef073de06add9b0d14026d6e5a86c85f6d102c36d3d8e9cf89c2afd3"},"l2_time":1686068903,"system_config":{"batcherAddr":"0x6887246668a3b87f54deb3b94ba47a6f63f32985","overhead":"0x00000000000000000000000000000000000000000000000000000000000000bc","scalar":"0x00000000000000000000000000000000000000000000000000000000000a6fe0","gasLimit":30000000}},"block_time":2,"max_sequencer_drift":600,"seq_window_size":3600,"channel_timeout":300,"channel_timeout_granite":50,"l1_chain_id":1,"l2_chain_id":10,"regolith_time":0,"canyon_time":1704992401,"delta_time":1708560000,"ecotone_time":1710374401,"batch_inbox_address":"0xff00000000000000000000000000000000000010","deposit_contract_address":"0xbeb5fc579115071764c7423a4f12edde41f106ed","l1_system_config_address":"0x229047fed2591dbec1ef1118d64f7af3db9eb290","protocol_versions_address":"0x8062abc286f5e7d9428a0ccb9abd71e50d93b935","da_challenge_address":"0x0000000000000000000000000000000000000000","da_challenge_window":0,"da_resolve_window":0,"use_plasma":false}"#;
test_helper::<RollupConfig>(rollup_config_json);
}