diff --git a/crates/genesis/src/chain.rs b/crates/genesis/src/chain.rs index 33056d36..923a2328 100644 --- a/crates/genesis/src/chain.rs +++ b/crates/genesis/src/chain.rs @@ -53,6 +53,8 @@ pub struct HardForkConfiguration { pub granite_time: Option, /// Holocene hardfork activation time pub holocene_time: Option, + /// Isthmus hardfork activation time + pub isthmus_time: Option, } /// Defines core blockchain settings per block. @@ -215,6 +217,7 @@ impl ChainConfig { fjord_time: self.hardfork_configuration.fjord_time, granite_time: self.hardfork_configuration.granite_time, holocene_time: self.hardfork_configuration.holocene_time, + isthmus_time: self.hardfork_configuration.isthmus_time, batch_inbox_address: self.batch_inbox_addr, deposit_contract_address: self .addresses diff --git a/crates/genesis/src/rollup.rs b/crates/genesis/src/rollup.rs index 0b243fc6..8b4bcad1 100644 --- a/crates/genesis/src/rollup.rs +++ b/crates/genesis/src/rollup.rs @@ -234,7 +234,7 @@ impl RollupConfig { /// Returns true if Holocene is active at the given timestamp. pub fn is_holocene_active(&self, timestamp: u64) -> bool { - self.holocene_time.map_or(false, |t| timestamp >= t) + self.holocene_time.map_or(false, |t| timestamp >= t) || self.is_isthmus_active(timestamp) } /// Returns true if Isthmus is active at the given timestamp. diff --git a/crates/protocol/src/block_info.rs b/crates/protocol/src/block_info.rs index c0cb7ff8..f40aa889 100644 --- a/crates/protocol/src/block_info.rs +++ b/crates/protocol/src/block_info.rs @@ -28,7 +28,7 @@ const L1_INFO_TX_LEN_BEDROCK: usize = 4 + 32 * 8; const L1_INFO_TX_LEN_ECOTONE: usize = 4 + 32 * 5; /// The length of an L1 info transaction in Isthmus. -const L1_INFO_TX_LEN_ISTHMUS: usize = 4 + 32 * 5 + 4; +const L1_INFO_TX_LEN_ISTHMUS: usize = 4 + 32 * 5 + 8 + 4; /// The 4 byte selector of the /// "setL1BlockValues(uint64,uint64,uint256,bytes32,uint64,bytes32,uint256,uint256)" function @@ -284,7 +284,7 @@ impl L1BlockInfoTx { return Ok(Self::Isthmus(L1BlockInfoIsthmus { number: l1_header.number, time: l1_header.timestamp, - base_fee: l1_header.base_fee_per_gas.unwrap_or(0) as u64, + base_fee: l1_header.base_fee_per_gas.unwrap_or(0), block_hash: l1_header.hash_slow(), sequence_number, batcher_address: system_config.batcher_address, @@ -396,6 +396,9 @@ impl L1BlockInfoTx { L1_INFO_TX_SELECTOR_ECOTONE => L1BlockInfoEcotone::decode_calldata(r) .map(Self::Ecotone) .map_err(|e| DecodeError::ParseError(format!("Ecotone decode error: {}", e))), + L1_INFO_TX_SELECTOR_ISTHMUS => L1BlockInfoIsthmus::decode_calldata(r) + .map(Self::Isthmus) + .map_err(|e| DecodeError::ParseError(format!("Isthmus decode error: {}", e))), _ => Err(DecodeError::InvalidSelector), } } @@ -405,6 +408,7 @@ impl L1BlockInfoTx { match self { Self::Bedrock(ref tx) => tx.block_hash, Self::Ecotone(ref tx) => tx.block_hash, + Self::Isthmus(ref tx) => tx.block_hash, } } @@ -413,12 +417,16 @@ impl L1BlockInfoTx { match self { Self::Bedrock(bedrock_tx) => bedrock_tx.encode_calldata(), Self::Ecotone(ecotone_tx) => ecotone_tx.encode_calldata(), + Self::Isthmus(isthmus_tx) => isthmus_tx.encode_calldata(), } } /// Returns the L1 [BlockNumHash] for the info transaction. pub const fn id(&self) -> BlockNumHash { match self { + Self::Isthmus(L1BlockInfoIsthmus { number, block_hash, .. }) => { + BlockNumHash { number: *number, hash: *block_hash } + } Self::Ecotone(L1BlockInfoEcotone { number, block_hash, .. }) => { BlockNumHash { number: *number, hash: *block_hash } } @@ -433,6 +441,7 @@ impl L1BlockInfoTx { match self { Self::Bedrock(L1BlockInfoBedrock { l1_fee_overhead, .. }) => *l1_fee_overhead, Self::Ecotone(_) => U256::ZERO, + Self::Isthmus(_) => U256::ZERO, } } @@ -441,6 +450,7 @@ impl L1BlockInfoTx { match self { Self::Bedrock(L1BlockInfoBedrock { batcher_address, .. }) => *batcher_address, Self::Ecotone(L1BlockInfoEcotone { batcher_address, .. }) => *batcher_address, + Self::Isthmus(L1BlockInfoIsthmus { batcher_address, .. }) => *batcher_address, } } @@ -449,6 +459,7 @@ impl L1BlockInfoTx { match self { Self::Bedrock(L1BlockInfoBedrock { sequence_number, .. }) => *sequence_number, Self::Ecotone(L1BlockInfoEcotone { sequence_number, .. }) => *sequence_number, + Self::Isthmus(L1BlockInfoIsthmus { sequence_number, .. }) => *sequence_number, } } } @@ -664,7 +675,7 @@ mod test { const RAW_BEDROCK_INFO_TX: [u8; L1_INFO_TX_LEN_BEDROCK] = hex!("015d8eb9000000000000000000000000000000000000000000000000000000000117c4eb0000000000000000000000000000000000000000000000000000000065280377000000000000000000000000000000000000000000000000000000026d05d953392012032675be9f94aae5ab442de73c5f4fb1bf30fa7dd0d2442239899a40fc00000000000000000000000000000000000000000000000000000000000000040000000000000000000000006887246668a3b87f54deb3b94ba47a6f63f3298500000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000a6fe0"); const RAW_ECOTONE_INFO_TX: [u8; L1_INFO_TX_LEN_ECOTONE] = hex!("440a5e2000000558000c5fc5000000000000000500000000661c277300000000012bec20000000000000000000000000000000000000000000000000000000026e9f109900000000000000000000000000000000000000000000000000000000000000011c4c84c50740386c7dc081efddd644405f04cde73e30a2e381737acce9f5add30000000000000000000000006887246668a3b87f54deb3b94ba47a6f63f32985"); - const RAW_ISTHMUS_INFO_TX: [u8; L1_INFO_TX_LEN_ISTHMUS] = hex!("d1fbe15b00000558000c5fc5000000000000000500000000661c277300000000012bec20000000000000000000000000000000000000000000000000000000026e9f109900000000000000000000000000000000000000000000000000000000000000011c4c84c50740386c7dc081efddd644405f04cde73e30a2e381737acce9f5add30000000000000000000000006887246668a3b87f54deb3b94ba47a6f63f329850000abcd000000000000dcba"); + const RAW_ISTHMUS_INFO_TX: [u8; L1_INFO_TX_LEN_ISTHMUS] = hex!("098999be00000558000c5fc5000000000000000500000000661c277300000000012bec20000000000000000000000000000000000000000000000000000000026e9f109900000000000000000000000000000000000000000000000000000000000000011c4c84c50740386c7dc081efddd644405f04cde73e30a2e381737acce9f5add30000000000000000000000006887246668a3b87f54deb3b94ba47a6f63f329850000abcd000000000000dcba"); #[test] fn bedrock_l1_block_info_invalid_len() { diff --git a/crates/protocol/src/lib.rs b/crates/protocol/src/lib.rs index fc46d1e2..cb2ca90c 100644 --- a/crates/protocol/src/lib.rs +++ b/crates/protocol/src/lib.rs @@ -56,7 +56,8 @@ pub use deposits::{ mod block_info; pub use block_info::{ - BlockInfoError, DecodeError, L1BlockInfoBedrock, L1BlockInfoEcotone, L1BlockInfoTx, + BlockInfoError, DecodeError, L1BlockInfoBedrock, L1BlockInfoEcotone, L1BlockInfoIsthmus, + L1BlockInfoTx, }; mod fee; diff --git a/crates/protocol/src/utils.rs b/crates/protocol/src/utils.rs index a36e7bf0..77b0e215 100644 --- a/crates/protocol/src/utils.rs +++ b/crates/protocol/src/utils.rs @@ -8,8 +8,8 @@ use op_alloy_consensus::{OpBlock, OpTxEnvelope}; use op_alloy_genesis::{RollupConfig, SystemConfig}; use crate::{ - L1BlockInfoBedrock, L1BlockInfoEcotone, L1BlockInfoTx, OpBlockConversionError, SpanBatchError, - SpanDecodingError, + L1BlockInfoBedrock, L1BlockInfoEcotone, L1BlockInfoIsthmus, L1BlockInfoTx, + OpBlockConversionError, SpanBatchError, SpanDecodingError, }; /// Returns if the given `value` is a deposit transaction. @@ -54,6 +54,11 @@ pub fn to_system_config( base_fee_scalar, blob_base_fee_scalar, .. + }) + | L1BlockInfoTx::Isthmus(L1BlockInfoIsthmus { + base_fee_scalar, + blob_base_fee_scalar, + .. }) => { // Translate Ecotone values back into encoded scalar if needed. // We do not know if it was derived from a v0 or v1 scalar, diff --git a/crates/registry/src/configs/base_mainnet.rs b/crates/registry/src/configs/base_mainnet.rs index 6831e0a3..4a07f949 100644 --- a/crates/registry/src/configs/base_mainnet.rs +++ b/crates/registry/src/configs/base_mainnet.rs @@ -43,6 +43,7 @@ pub const BASE_MAINNET_CONFIG: RollupConfig = RollupConfig { fjord_time: Some(1720627201), granite_time: Some(1_726_070_401_u64), holocene_time: None, + isthmus_time: None, batch_inbox_address: address!("ff00000000000000000000000000000000008453"), deposit_contract_address: address!("49048044d57e1c92a77f79988d21fa8faf74e97e"), l1_system_config_address: address!("73a79fab69143498ed3712e519a88a918e1f4072"), diff --git a/crates/registry/src/configs/base_sepolia.rs b/crates/registry/src/configs/base_sepolia.rs index 9c44567c..b70f94c4 100644 --- a/crates/registry/src/configs/base_sepolia.rs +++ b/crates/registry/src/configs/base_sepolia.rs @@ -43,6 +43,7 @@ pub const BASE_SEPOLIA_CONFIG: RollupConfig = RollupConfig { fjord_time: Some(1716998400), granite_time: Some(1723478400), holocene_time: Some(1732633200), + isthmus_time: None, batch_inbox_address: address!("ff00000000000000000000000000000000084532"), deposit_contract_address: address!("49f53e41452c74589e85ca1677426ba426459e85"), l1_system_config_address: address!("f272670eb55e895584501d564afeb048bed26194"), diff --git a/crates/registry/src/configs/op_mainnet.rs b/crates/registry/src/configs/op_mainnet.rs index cb66d3d9..00228d6c 100644 --- a/crates/registry/src/configs/op_mainnet.rs +++ b/crates/registry/src/configs/op_mainnet.rs @@ -43,6 +43,7 @@ pub const OP_MAINNET_CONFIG: RollupConfig = RollupConfig { fjord_time: Some(1_720_627_201_u64), granite_time: Some(1_726_070_401_u64), holocene_time: None, + isthmus_time: None, batch_inbox_address: address!("ff00000000000000000000000000000000000010"), deposit_contract_address: address!("beb5fc579115071764c7423a4f12edde41f106ed"), l1_system_config_address: address!("229047fed2591dbec1ef1118d64f7af3db9eb290"), diff --git a/crates/registry/src/configs/op_sepolia.rs b/crates/registry/src/configs/op_sepolia.rs index 560ef53b..08044223 100644 --- a/crates/registry/src/configs/op_sepolia.rs +++ b/crates/registry/src/configs/op_sepolia.rs @@ -43,6 +43,7 @@ pub const OP_SEPOLIA_CONFIG: RollupConfig = RollupConfig { fjord_time: Some(1716998400), granite_time: Some(1723478400), holocene_time: Some(1732633200), + isthmus_time: None, batch_inbox_address: address!("ff00000000000000000000000000000011155420"), deposit_contract_address: address!("16fc5058f25648194471939df75cf27a2fdc48bc"), l1_system_config_address: address!("034edd2a225f7f429a63e0f1d2084b9e0a93b538"), diff --git a/crates/registry/src/superchain.rs b/crates/registry/src/superchain.rs index adf53e49..16d50b77 100644 --- a/crates/registry/src/superchain.rs +++ b/crates/registry/src/superchain.rs @@ -145,6 +145,7 @@ mod tests { fjord_time: Some(1720627201), granite_time: Some(1726070401), holocene_time: None, + isthmus_time: None, }, block_time: 2, seq_window_size: 3600,