Skip to content

Commit

Permalink
chore(consensus): Trait Abstracted Hardforks (#289)
Browse files Browse the repository at this point in the history
### Description

Trait abstracts hardforks to make them more ergonomic to extend, modify,
or introduce a new hardfork.
  • Loading branch information
refcell committed Nov 21, 2024
1 parent e66aeab commit ac79298
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 175 deletions.
142 changes: 60 additions & 82 deletions crates/consensus/src/hardforks/ecotone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,41 @@
//!
//! [Transaction]: alloy_consensus::Transaction

use alloc::{string::String, vec, vec::Vec};
use alloc::{string::String, vec::Vec};
use alloy_consensus::Sealable;
use alloy_eips::eip2718::Encodable2718;
use alloy_primitives::{address, hex, Address, Bytes, TxKind, B256, U256};

use crate::{OpTxEnvelope, TxDeposit, UpgradeDepositSource, GAS_PRICE_ORACLE};
use crate::{OpTxEnvelope, TxDeposit, UpgradeDepositSource};

/// L1 Block Deployer Address
pub const L1_BLOCK_DEPLOYER: Address = address!("4210000000000000000000000000000000000000");
/// The Ecotone network upgrade transactions.
#[derive(Debug, Default, Clone, Copy)]
pub struct Ecotone;

/// The Gas Price Oracle Deployer Address
pub const GAS_PRICE_ORACLE_DEPLOYER: Address = address!("4210000000000000000000000000000000000001");
impl Ecotone {
/// The Gas Price Oracle Address
/// This is computed by using go-ethereum's `crypto.CreateAddress` function,
/// with the Gas Price Oracle Deployer Address and nonce 0.
pub const GAS_PRICE_ORACLE: Address = address!("b528d11cc114e026f138fe568744c6d45ce6da7a");

/// The new L1 Block Address
/// This is computed by using go-ethereum's `crypto.CreateAddress` function,
/// with the L1 Block Deployer Address and nonce 0.
pub const NEW_L1_BLOCK: Address = address!("07dbe8500fc591d1852b76fee44d5a05e13097ff");

/// EIP-4788 From Address
pub const EIP4788_FROM: Address = address!("0B799C86a49DEeb90402691F1041aa3AF2d3C875");

impl super::Hardforks {
/// The Enable Ecotone Input Method 4Byte Signature
pub const ENABLE_ECOTONE_INPUT: [u8; 4] = hex!("22b908b3");

/// L1 Block Deployer Address
pub const L1_BLOCK_DEPLOYER: Address = address!("4210000000000000000000000000000000000000");

/// The Gas Price Oracle Deployer Address
pub const GAS_PRICE_ORACLE_DEPLOYER: Address =
address!("4210000000000000000000000000000000000001");

/// The new L1 Block Address
/// This is computed by using go-ethereum's `crypto.CreateAddress` function,
/// with the L1 Block Deployer Address and nonce 0.
pub const NEW_L1_BLOCK: Address = address!("07dbe8500fc591d1852b76fee44d5a05e13097ff");

/// EIP-4788 From Address
pub const EIP4788_FROM: Address = address!("0B799C86a49DEeb90402691F1041aa3AF2d3C875");

/// Returns the source hash for the deployment of the l1 block contract.
pub fn deploy_l1_block_source() -> B256 {
UpgradeDepositSource { intent: String::from("Ecotone: L1 Block Deployment") }.source_hash()
Expand Down Expand Up @@ -79,118 +89,86 @@ impl super::Hardforks {
include_bytes!("./bytecode/gpo_ecotone.hex").into()
}

/// Constructs the Ecotone network upgrade transactions.
pub fn ecotone_txs() -> Vec<Bytes> {
let mut txs = vec![];

// Deploy the L1 Block Contract
let mut buffer = Vec::new();
OpTxEnvelope::Deposit(
/// Returns the list of [TxDeposit]s for the Ecotone network upgrade.
pub fn deposits() -> impl Iterator<Item = TxDeposit> {
([
TxDeposit {
source_hash: Self::deploy_l1_block_source(),
from: L1_BLOCK_DEPLOYER,
from: Self::L1_BLOCK_DEPLOYER,
to: TxKind::Create,
mint: 0.into(),
value: U256::ZERO,
gas_limit: 375_000,
is_system_transaction: false,
input: Self::l1_block_deployment_bytecode(),
}
.seal_slow(),
)
.encode_2718(&mut buffer);
txs.push(Bytes::from(buffer));

// Deploy the Gas Price Oracle
buffer = Vec::new();
OpTxEnvelope::Deposit(
},
TxDeposit {
source_hash: Self::deploy_gas_price_oracle_source(),
from: GAS_PRICE_ORACLE_DEPLOYER,
from: Self::GAS_PRICE_ORACLE_DEPLOYER,
to: TxKind::Create,
mint: 0.into(),
value: U256::ZERO,
gas_limit: 1_000_000,
is_system_transaction: false,
input: Self::ecotone_gas_price_oracle_deployment_bytecode(),
}
.seal_slow(),
)
.encode_2718(&mut buffer);
txs.push(Bytes::from(buffer));

// Update the l1 block proxy
buffer = Vec::new();
OpTxEnvelope::Deposit(
},
TxDeposit {
source_hash: Self::update_l1_block_source(),
from: Address::default(),
to: TxKind::Call(L1_BLOCK_DEPLOYER),
to: TxKind::Call(Self::L1_BLOCK_DEPLOYER),
mint: 0.into(),
value: U256::ZERO,
gas_limit: 50_000,
is_system_transaction: false,
input: Self::upgrade_to_calldata(NEW_L1_BLOCK),
}
.seal_slow(),
)
.encode_2718(&mut buffer);
txs.push(Bytes::from(buffer));

// Update gas price oracle proxy
buffer = Vec::new();
OpTxEnvelope::Deposit(
input: super::upgrade_to_calldata(Self::NEW_L1_BLOCK),
},
TxDeposit {
source_hash: Self::update_gas_price_oracle_source(),
from: Address::default(),
to: TxKind::Call(GAS_PRICE_ORACLE_DEPLOYER),
to: TxKind::Call(Self::GAS_PRICE_ORACLE_DEPLOYER),
mint: 0.into(),
value: U256::ZERO,
gas_limit: 50_000,
is_system_transaction: false,
input: Self::upgrade_to_calldata(GAS_PRICE_ORACLE),
}
.seal_slow(),
)
.encode_2718(&mut buffer);
txs.push(Bytes::from(buffer));

// Enable ecotone
buffer = Vec::new();
OpTxEnvelope::Deposit(
input: super::upgrade_to_calldata(Self::GAS_PRICE_ORACLE),
},
TxDeposit {
source_hash: Self::enable_ecotone_source(),
from: L1_BLOCK_DEPLOYER,
to: TxKind::Call(GAS_PRICE_ORACLE),
from: Self::L1_BLOCK_DEPLOYER,
to: TxKind::Call(Self::GAS_PRICE_ORACLE),
mint: 0.into(),
value: U256::ZERO,
gas_limit: 80_000,
is_system_transaction: false,
input: Self::ENABLE_ECOTONE_INPUT.into(),
}
.seal_slow(),
)
.encode_2718(&mut buffer);
txs.push(Bytes::from(buffer));

// Deploy EIP-4788
buffer = Vec::new();
OpTxEnvelope::Deposit(
},
TxDeposit {
source_hash: Self::beacon_roots_source(),
from: EIP4788_FROM,
from: Self::EIP4788_FROM,
to: TxKind::Create,
mint: 0.into(),
value: U256::ZERO,
gas_limit: 250_000,
is_system_transaction: false,
input: Self::eip4788_creation_data(),
}
.seal_slow(),
)
.encode_2718(&mut buffer);
txs.push(Bytes::from(buffer));
},
])
.into_iter()
}

/// Returns the list of [OpTxEnvelope]s for the Ecotone network upgrade.
pub fn enveloped_txs() -> impl Iterator<Item = OpTxEnvelope> {
Self::deposits().map(|deposit| OpTxEnvelope::from(deposit.seal_slow()))
}
}

txs
impl super::Hardfork for Ecotone {
/// Constructs the Ecotone network upgrade transactions.
fn txs(&self) -> impl Iterator<Item = Bytes> + '_ {
Self::enveloped_txs().map(|tx| {
let mut encoded = Vec::new();
tx.encode_2718(&mut encoded);
Bytes::from(encoded)
})
}
}
94 changes: 48 additions & 46 deletions crates/consensus/src/hardforks/fjord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,33 @@
//!
//! [Transaction]: alloy_consensus::Transaction

use crate::{OpTxEnvelope, TxDeposit};
use alloc::{string::String, vec, vec::Vec};
use crate::{OpTxEnvelope, TxDeposit, UpgradeDepositSource};
use alloc::{string::String, vec::Vec};
use alloy_consensus::Sealable;
use alloy_eips::eip2718::Encodable2718;
use alloy_primitives::{address, hex, Address, Bytes, TxKind, B256, U256};

use crate::{UpgradeDepositSource, GAS_PRICE_ORACLE};
/// The Fjord network upgrade transactions.
#[derive(Debug, Default, Clone, Copy)]
pub struct Fjord;

/// The L1 Info Depositer Address.
pub const L1_INFO_DEPOSITER: Address = address!("deaddeaddeaddeaddeaddeaddeaddeaddead0001");
impl Fjord {
/// The Gas Price Oracle Address
/// This is computed by using go-ethereum's `crypto.CreateAddress` function,
/// with the Gas Price Oracle Deployer Address and nonce 0.
pub const GAS_PRICE_ORACLE: Address = address!("b528d11cc114e026f138fe568744c6d45ce6da7a");

/// Fjord Gas Price Oracle Deployer Address.
pub const GAS_PRICE_ORACLE_FJORD_DEPLOYER: Address =
address!("4210000000000000000000000000000000000002");
/// The L1 Info Depositer Address.
pub const L1_INFO_DEPOSITER: Address = address!("deaddeaddeaddeaddeaddeaddeaddeaddead0001");

/// Fjord Gas Price Oracle address.
pub const FJORD_GAS_PRICE_ORACLE: Address = address!("a919894851548179a0750865e7974da599c0fac7");
/// Fjord Gas Price Oracle Deployer Address.
pub const GAS_PRICE_ORACLE_FJORD_DEPLOYER: Address =
address!("4210000000000000000000000000000000000002");

/// Fjord Gas Price Oracle address.
pub const FJORD_GAS_PRICE_ORACLE: Address =
address!("a919894851548179a0750865e7974da599c0fac7");

impl super::Hardforks {
/// The Set Fjord Four Byte Method Signature.
pub const SET_FJORD_METHOD_SIGNATURE: [u8; 4] = hex!("8e98b106");

Expand All @@ -47,63 +55,57 @@ impl super::Hardforks {
include_bytes!("./bytecode/gpo_fjord.hex").into()
}

/// Constructs the Fjord network upgrade transactions.
pub fn fjord_txs() -> Vec<Bytes> {
let mut txs = vec![];

let mut buffer = Vec::new();
OpTxEnvelope::Deposit(
/// Returns the list of [TxDeposit]s for the Fjord network upgrade.
pub fn deposits() -> impl Iterator<Item = TxDeposit> {
([
TxDeposit {
source_hash: Self::deploy_fjord_gas_price_oracle_source(),
from: GAS_PRICE_ORACLE_FJORD_DEPLOYER,
from: Self::GAS_PRICE_ORACLE_FJORD_DEPLOYER,
to: TxKind::Create,
mint: 0.into(),
value: U256::ZERO,
gas_limit: 1_450_000,
is_system_transaction: false,
input: Self::gas_price_oracle_deployment_bytecode(),
}
.seal_slow(),
)
.encode_2718(&mut buffer);
txs.push(Bytes::from(buffer));

// Update the gas price oracle proxy.
buffer = Vec::new();
OpTxEnvelope::Deposit(
},
TxDeposit {
source_hash: Self::update_fjord_gas_price_oracle_source(),
from: Address::ZERO,
to: TxKind::Call(GAS_PRICE_ORACLE),
to: TxKind::Call(Self::GAS_PRICE_ORACLE),
mint: 0.into(),
value: U256::ZERO,
gas_limit: 50_000,
is_system_transaction: false,
input: Self::upgrade_to_calldata(FJORD_GAS_PRICE_ORACLE),
}
.seal_slow(),
)
.encode_2718(&mut buffer);
txs.push(Bytes::from(buffer));

// Enable Fjord
buffer = Vec::new();
OpTxEnvelope::Deposit(
input: super::upgrade_to_calldata(Self::FJORD_GAS_PRICE_ORACLE),
},
// Enable Fjord
TxDeposit {
source_hash: Self::enable_fjord_source(),
from: L1_INFO_DEPOSITER,
to: TxKind::Call(GAS_PRICE_ORACLE),
from: Self::L1_INFO_DEPOSITER,
to: TxKind::Call(Self::GAS_PRICE_ORACLE),
mint: 0.into(),
value: U256::ZERO,
gas_limit: 90_000,
is_system_transaction: false,
input: Self::SET_FJORD_METHOD_SIGNATURE.into(),
}
.seal_slow(),
)
.encode_2718(&mut buffer);
txs.push(Bytes::from(buffer));
},
])
.into_iter()
}

txs
/// Returns the list of [OpTxEnvelope]s for the Fjord network upgrade.
pub fn enveloped_txs() -> impl Iterator<Item = OpTxEnvelope> {
Self::deposits().map(|deposit| OpTxEnvelope::Deposit(deposit.seal_slow()))
}
}

impl super::Hardfork for Fjord {
/// Constructs the Fjord network upgrade transactions.
fn txs(&self) -> impl Iterator<Item = Bytes> + '_ {
Self::enveloped_txs().map(|tx| {
let mut encoded = Vec::new();
tx.encode_2718(&mut encoded);
Bytes::from(encoded)
})
}
}
Loading

0 comments on commit ac79298

Please sign in to comment.