Skip to content

Commit

Permalink
Merge pull request #27 from taikoxyz/v1.0.0-rc.2-taiko-ontake
Browse files Browse the repository at this point in the history
prepare for ontake upgrade
  • Loading branch information
smtmfft authored Aug 16, 2024
2 parents 6cc82cf + 018d2a6 commit 910b6f1
Show file tree
Hide file tree
Showing 12 changed files with 267 additions and 74 deletions.
180 changes: 119 additions & 61 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -504,8 +504,6 @@ similar-asserts = "1.5.0"
test-fuzz = "5"

# raiko
raiko-core = { git = "https://github.com/taikoxyz/raiko.git", branch = "reth-wip" }
raiko-lib = { git = "https://github.com/taikoxyz/raiko.git", branch = "reth-wip" }
anyhow = "1.0"

[patch.crates-io]
Expand Down
1 change: 1 addition & 0 deletions crates/chainspec/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,4 @@ arbitrary = [
"alloy-chains/arbitrary"
]
network = ["reth-network-peers"]
taiko = ["reth-ethereum-forks/taiko"]
14 changes: 11 additions & 3 deletions crates/chainspec/src/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ pub static TAIKO_A7: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
ForkCondition::TTD { fork_block: None, total_difficulty: U256::from(0) },
),
(Hardfork::Shanghai, ForkCondition::Timestamp(0)),
#[cfg(feature = "taiko")]
(Hardfork::Hekla, ForkCondition::Block(0)),
]),
deposit_contract: None,
..Default::default()
Expand Down Expand Up @@ -150,6 +152,10 @@ pub static TAIKO_DEV: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
ForkCondition::TTD { fork_block: None, total_difficulty: U256::from(0) },
),
(Hardfork::Shanghai, ForkCondition::Timestamp(0)),
#[cfg(feature = "taiko")]
(Hardfork::Hekla, ForkCondition::Block(0)),
#[cfg(feature = "taiko")]
(Hardfork::Ontake, ForkCondition::Block(20)), //todo
]),
deposit_contract: None,
..Default::default()
Expand All @@ -174,14 +180,16 @@ pub static TAIKO_MAINNET: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
(Hardfork::Byzantium, ForkCondition::Block(0)),
(Hardfork::Constantinople, ForkCondition::Block(0)),
(Hardfork::Petersburg, ForkCondition::Block(0)),
(Hardfork::Istanbul, ForkCondition::Block(1561651)),
(Hardfork::Berlin, ForkCondition::Block(4460644)),
(Hardfork::London, ForkCondition::Block(5062605)),
(Hardfork::Istanbul, ForkCondition::Block(0)),
(Hardfork::Berlin, ForkCondition::Block(0)),
(Hardfork::London, ForkCondition::Block(0)),
(
Hardfork::Paris,
ForkCondition::TTD { fork_block: None, total_difficulty: U256::from(0) },
),
(Hardfork::Shanghai, ForkCondition::Timestamp(0)),
#[cfg(feature = "taiko")]
(Hardfork::Hekla, ForkCondition::Block(0)),
]),
deposit_contract: None,
..Default::default()
Expand Down
1 change: 1 addition & 0 deletions crates/ethereum-forks/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ proptest-derive.workspace = true

[features]
default = ["std", "serde"]
taiko = []
std = ["thiserror-no-std/std"]
serde = ["dep:serde"]
arbitrary = ["dep:arbitrary", "dep:proptest", "dep:proptest-derive"]
Expand Down
6 changes: 6 additions & 0 deletions crates/ethereum-forks/src/hardfork.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ pub enum Hardfork {
Regolith,
/// Shanghai: <https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/shanghai.md>.
Shanghai,
/// Hekla: the 1st taiko mainnet version: <>
#[cfg(feature = "taiko")]
Hekla,
/// Ontake: the 2nd taiko mainnet fork: <>
#[cfg(feature = "taiko")]
Ontake,
/// Canyon:
/// <https://github.com/ethereum-optimism/specs/blob/main/specs/protocol/superchain-upgrades.md#canyon>.
#[cfg(feature = "optimism")]
Expand Down
31 changes: 27 additions & 4 deletions crates/ethereum/evm/src/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

use crate::{
dao_fork::{DAO_HARDFORK_BENEFICIARY, DAO_HARDKFORK_ACCOUNTS},
taiko::{check_anchor_tx, TaikoData}, EthEvmConfig,
taiko::{check_anchor_tx, check_anchor_tx_ontake, TaikoData},
EthEvmConfig,
};
use reth_chainspec::{ChainSpec, MAINNET};
pub use reth_consensus::Consensus;
Expand All @@ -16,7 +17,8 @@ use reth_evm::{
};
use reth_execution_types::ExecutionOutcome;
use reth_primitives::{
BlockNumber, BlockWithSenders, Hardfork, Header, Receipt, Request, Withdrawals, U256,
revm::config::revm_spec, BlockNumber, BlockWithSenders, Hardfork, Head, Header, Receipt,
Request, Withdrawals, U256,
};
use reth_prune_types::PruneModes;
use reth_revm::{
Expand All @@ -31,7 +33,7 @@ use reth_revm::{
};
use revm_primitives::{
db::{Database, DatabaseCommit}, Address, BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ResultAndState,
EVMError, HashSet,
EVMError, HashSet, SpecId,
};
use std::sync::Arc;
use anyhow::Result;
Expand Down Expand Up @@ -176,8 +178,28 @@ where

// verify the anchor tx
if is_anchor {
check_anchor_tx(transaction, sender, &block.block, taiko_data.clone().unwrap())
let spec_id = revm_spec(
&self.chain_spec,
Head { number: block.number, ..Default::default() },
);
if spec_id.is_enabled_in(SpecId::ONTAKE) {
check_anchor_tx_ontake(
transaction,
sender,
&block.block,
taiko_data.clone().unwrap(),
)
.map_err(|e| BlockExecutionError::CanonicalRevert { inner: e.to_string() })?;
} else if spec_id.is_enabled_in(SpecId::HEKLA) {
check_anchor_tx(transaction, sender, &block.block, taiko_data.clone().unwrap())
.map_err(|e| BlockExecutionError::CanonicalRevert {
inner: e.to_string(),
})?;
} else {
return Err(BlockExecutionError::CanonicalRevert {
inner: "unknown spec id for anchor".to_string(),
});
}
}

// If the signature was not valid, the sender address will have been set to zero
Expand Down Expand Up @@ -211,6 +233,7 @@ where
evm.tx_mut().taiko.is_anchor = is_anchor;
// set the treasury address
evm.tx_mut().taiko.treasury = taiko_data.clone().unwrap().l2_contract;
evm.tx_mut().taiko.basefee_ratio = taiko_data.clone().unwrap().basefee_ratio;

// Execute transaction.
let res = evm.transact().map_err(move |err| {
Expand Down
92 changes: 91 additions & 1 deletion crates/ethereum/evm/src/taiko.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ pub struct TaikoData {
pub parent_header: Header,
/// L2 contract
pub l2_contract: Address,
/// base fee sharing ratio
pub basefee_ratio: u8,
/// base fee adjustment quotient
pub basefee_adj_quotient: u8,
/// gas issuance per second
pub gas_issue_per_sec: u32,
}

/// Anchor tx gas limit
Expand Down Expand Up @@ -80,8 +86,23 @@ sol! {
)
external
{}

function anchorV2(
uint64 _anchorBlockId,
bytes32 _anchorStateRoot,
uint32 _parentGasUsed,
uint32 _gasIssuancePerSecond,
uint8 _basefeeAdjustmentQuotient
)
external
nonReentrant
{}
}

// todo, use compiled abi once test passes
// sol!(TaikoL2, "./res/TaikoL2.json");
// use TaikoL2::{anchor, anchorV2};

/// Decode anchor tx data
pub fn decode_anchor(bytes: &[u8]) -> Result<anchorCall> {
anchorCall::abi_decode(bytes, true).map_err(|e| anyhow!(e))
Expand Down Expand Up @@ -146,4 +167,73 @@ pub fn check_anchor_tx(tx: &TransactionSigned, from: &Address, block: &Block, ta
);

Ok(())
}
}

pub fn decode_anchor_ontake(bytes: &[u8]) -> Result<anchorV2Call> {
anchorV2Call::abi_decode(bytes, true).map_err(|e| anyhow!(e))
}

/// Verifies the anchor tx correctness in ontake fork
pub fn check_anchor_tx_ontake(
tx: &TransactionSigned,
from: &Address,
block: &Block,
taiko_data: TaikoData,
) -> Result<()> {
let anchor: &reth_primitives::TxEip1559 =
tx.as_eip1559().context(anyhow!("anchor tx is not an EIP1559 tx"))?;

// Check the signature
check_anchor_signature(tx).context(anyhow!("failed to check anchor signature"))?;

// Extract the `to` address
let TxKind::Call(to) = anchor.to else { panic!("anchor tx not a smart contract call") };
// Check that it's from the golden touch address
ensure!(*from == *GOLDEN_TOUCH_ACCOUNT, "anchor transaction from mismatch");
// Check that the L2 contract is being called
ensure!(to == taiko_data.l2_contract, "anchor transaction to mismatch");
// Tx can't have any ETH attached
ensure!(anchor.value == U256::from(0), "anchor transaction value mismatch");
// Tx needs to have the expected gas limit
ensure!(anchor.gas_limit == ANCHOR_GAS_LIMIT, "anchor transaction gas price mismatch");
// Check needs to have the base fee set to the block base fee
ensure!(
anchor.max_fee_per_gas == block.header.base_fee_per_gas.unwrap().into(),
"anchor transaction gas mismatch"
);

/*
uint64 _anchorBlockId,
bytes32 _anchorStateRoot,
uint32 _parentGasUsed,
uint32 _gasIssuancePerSecond,
uint8 _basefeeAdjustmentQuotient
*/

// Okay now let's decode the anchor tx to verify the inputs
let anchor_call = decode_anchor_ontake(&anchor.input)?;
ensure!(
anchor_call._anchorStateRoot == taiko_data.l1_header.state_root,
"L1 state root mismatch"
);
ensure!(anchor_call._anchorBlockId == taiko_data.l1_header.number, "L1 block number mismatch");
ensure!(
anchor_call._anchorStateRoot == taiko_data.l1_header.state_root,
"L1 state root mismatch"
);
// The parent gas used input needs to match the gas used value of the parent block
ensure!(
anchor_call._parentGasUsed == taiko_data.parent_header.gas_used as u32,
"parentGasUsed mismatch"
);
ensure!(
anchor_call._gasIssuancePerSecond == taiko_data.gas_issue_per_sec,
"gas issuance per second mismatch"
);
ensure!(
anchor_call._basefeeAdjustmentQuotient == taiko_data.basefee_adj_quotient,
"basefee adjustment quotient mismatch"
);

Ok(())
}
1 change: 1 addition & 0 deletions crates/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ optimism = [
taiko = [
"revm-primitives/taiko",
"revm/taiko",
"reth-ethereum-forks/taiko",
]
alloy-compat = [
"reth-primitives-traits/alloy-compat",
Expand Down
9 changes: 9 additions & 0 deletions crates/primitives/src/revm/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ pub fn revm_spec(chain_spec: &ChainSpec, block: Head) -> revm_primitives::SpecId
}
}

#[cfg(feature = "taiko")]
if chain_spec.is_taiko() {
if chain_spec.fork(Hardfork::Ontake).active_at_head(&block) {
return revm_primitives::ONTAKE;
} else if chain_spec.fork(Hardfork::Hekla).active_at_head(&block) {
return revm_primitives::HEKLA;
}
}

if chain_spec.fork(Hardfork::Prague).active_at_head(&block) {
revm_primitives::PRAGUE
} else if chain_spec.fork(Hardfork::Cancun).active_at_head(&block) {
Expand Down
2 changes: 1 addition & 1 deletion crates/primitives/src/revm/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ fn fill_tx_env_with_system_contract_call(
enveloped_tx: Some(Bytes::default()),
},
#[cfg(feature = "taiko")]
taiko: revm_primitives::TaikoFields { treasury: Address::default(), is_anchor: false },
taiko: revm_primitives::TaikoFields { treasury: Address::default(), is_anchor: false, basefee_ratio: 0u8 },
};

// ensure the block gas limit is >= the tx
Expand Down
2 changes: 0 additions & 2 deletions testing/ef-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,4 @@ thiserror.workspace = true
rayon.workspace = true

# raiko
raiko-core.workspace = true
raiko-lib.workspace = true
anyhow.workspace = true

0 comments on commit 910b6f1

Please sign in to comment.