Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support taiko protocol(rebase to the 3.5.0 revm) #1

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/interpreter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ serde = ["dep:serde", "revm-primitives/serde"]
arbitrary = ["std", "revm-primitives/arbitrary"]

optimism = ["revm-primitives/optimism"]
taiko = ["revm-primitives/taiko"]

dev = [
"memory_limit",
Expand Down
1 change: 1 addition & 0 deletions crates/precompile/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ std = [
]

optimism = ["revm-primitives/optimism"]
taiko = ["revm-primitives/taiko"]


# This library may not work on all no_std platforms as they depend on C libraries.
Expand Down
1 change: 1 addition & 0 deletions crates/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ serde = [
arbitrary = ["std", "alloy-primitives/arbitrary", "bitflags/arbitrary"]

optimism = []
taiko = []

dev = [
"memory_limit",
Expand Down
14 changes: 14 additions & 0 deletions crates/primitives/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ use crate::{
};
use core::cmp::{min, Ordering};

#[cfg(feature = "taiko")]
use crate::taiko::env::TaikoFields;

#[derive(Clone, Debug, Default, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Env {
Expand Down Expand Up @@ -183,6 +186,10 @@ pub struct TxEnv {
#[cfg_attr(feature = "serde", serde(flatten))]
#[cfg(feature = "optimism")]
pub optimism: OptimismFields,

#[cfg_attr(feature = "serde", serde(flatten))]
#[cfg(feature = "taiko")]
pub taiko: TaikoFields,
}

impl TxEnv {
Expand Down Expand Up @@ -442,6 +449,8 @@ impl Default for TxEnv {
max_fee_per_blob_gas: None,
#[cfg(feature = "optimism")]
optimism: OptimismFields::default(),
#[cfg(feature = "taiko")]
taiko: TaikoFields::default(),
}
}
}
Expand Down Expand Up @@ -648,6 +657,11 @@ impl Env {
.ok_or(InvalidTransaction::OverflowPaymentInTransaction)?;
}

#[cfg(feature = "taiko")]
if self.tx.taiko.is_anchor {
return Ok(());
}

// Check if account has enough balance for gas_limit*gas_price and value transfer.
// Transfer will be done inside `*_inner` functions.
if balance_check > account.info.balance {
Expand Down
2 changes: 2 additions & 0 deletions crates/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ pub mod precompile;
pub mod result;
pub mod specification;
pub mod state;
#[cfg(feature = "taiko")]
pub mod taiko;
pub mod utilities;

pub use alloy_primitives::{
Expand Down
3 changes: 3 additions & 0 deletions crates/primitives/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,9 @@ pub enum InvalidTransaction {
/// post-regolith hardfork.
#[cfg(feature = "optimism")]
DepositSystemTxPostRegolith,
/// Anchor check failed
#[cfg(feature = "taiko")]
InvalidAnchorTransaction,
}

impl<DBError> From<InvalidHeader> for EVMError<DBError> {
Expand Down
8 changes: 8 additions & 0 deletions crates/primitives/src/taiko/env.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use crate::Address;

#[derive(Clone, Debug, Default, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct TaikoFields {
pub treasury: Address,
pub is_anchor: bool,
}
1 change: 1 addition & 0 deletions crates/primitives/src/taiko/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod env;
1 change: 1 addition & 0 deletions crates/revm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ serde = ["dep:serde", "dep:serde_json", "revm-interpreter/serde"]
arbitrary = ["revm-interpreter/arbitrary"]

optimism = ["revm-interpreter/optimism", "revm-precompile/optimism"]
taiko = ["revm-interpreter/taiko", "revm-precompile/taiko"]

ethersdb = ["std", "tokio", "futures", "ethers-providers", "ethers-core"]

Expand Down
25 changes: 23 additions & 2 deletions crates/revm/src/evm_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> Transact<DB::Error>
let tx_value = env.tx.value;
let tx_data = env.tx.data.clone();
let tx_gas_limit = env.tx.gas_limit;
#[cfg(feature = "taiko")]
let is_anchor = env.tx.taiko.is_anchor;

#[cfg(feature = "optimism")]
let tx_l1_cost = {
Expand Down Expand Up @@ -278,8 +280,15 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> Transact<DB::Error>
gas_cost = gas_cost.saturating_add(data_fee);
}

caller_account.info.balance = caller_account.info.balance.saturating_sub(gas_cost);
#[cfg(feature = "taiko")]
if !is_anchor {
caller_account.info.balance = caller_account.info.balance.saturating_sub(gas_cost);
}

#[cfg(not(feature = "taiko"))]
{
caller_account.info.balance = caller_account.info.balance.saturating_sub(gas_cost);
}
// touch account so we know it is changed.
caller_account.mark_touch();

Expand Down Expand Up @@ -402,6 +411,18 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,
precompiles: Precompiles,
) -> Self {
let journaled_state = JournaledState::new(precompiles.len(), GSPEC::SPEC_ID);

#[cfg(feature = "optimism")]
let handler: Handler<DB> = if env.cfg.optimism {
Handler::optimism::<GSPEC>()
} else {
Handler::mainnet::<GSPEC>()
};
#[cfg(feature = "taiko")]
let handler = Handler::taiko::<GSPEC>();
#[cfg(not(any(feature = "optimism", feature = "taiko")))]
let handler = Handler::mainnet::<GSPEC>();

Self {
data: EVMData {
env,
Expand All @@ -413,7 +434,7 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,
l1_block_info: None,
},
inspector,
handler: Handler::mainnet::<GSPEC>(),
handler,
_phantomdata: PhantomData {},
}
}
Expand Down
12 changes: 12 additions & 0 deletions crates/revm/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ impl<DB: Database> Handler<DB> {
}
}

/// Handler for the taiko
#[cfg(feature = "taiko")]
pub fn taiko<SPEC: Spec>() -> Self {
use crate::taiko::handler;
Self {
call_return: mainnet::handle_call_return::<SPEC>,
calculate_gas_refund: mainnet::calculate_gas_refund::<SPEC>,
reimburse_caller: handler::handle_reimburse_caller::<SPEC, DB>,
reward_beneficiary: handler::reward_beneficiary::<SPEC, DB>,
}
}

/// Handler for the optimism
#[cfg(feature = "optimism")]
pub fn optimism<SPEC: Spec>() -> Self {
Expand Down
3 changes: 3 additions & 0 deletions crates/revm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ mod journaled_state;
#[cfg(feature = "optimism")]
pub mod optimism;

#[cfg(feature = "taiko")]
pub mod taiko;

#[cfg(all(feature = "with-serde", not(feature = "serde")))]
compile_error!("`with-serde` feature has been renamed to `serde`.");

Expand Down
83 changes: 83 additions & 0 deletions crates/revm/src/taiko/handler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//! Mainnet related handlers.
use revm_interpreter::primitives::EVMError;

use crate::{
interpreter::{return_ok, return_revert, Gas, InstructionResult},
primitives::{db::Database, Env, Spec, SpecId::LONDON, U256},
EVMData,
};

#[inline]
pub fn handle_reimburse_caller<SPEC: Spec, DB: Database>(
data: &mut EVMData<'_, DB>,
gas: &Gas,
gas_refund: u64,
) -> Result<(), EVMError<DB::Error>> {
let _ = data;
if data.env.tx.taiko.is_anchor {
return Ok(());
}
let caller = data.env.tx.caller;
let effective_gas_price = data.env.effective_gas_price();

// return balance of not spend gas.
let (caller_account, _) = data
.journaled_state
.load_account(caller, data.db)
.map_err(EVMError::Database)?;

caller_account.info.balance = caller_account
.info
.balance
.saturating_add(effective_gas_price * U256::from(gas.remaining() + gas_refund));

Ok(())
}

/// Reward beneficiary with gas fee.
#[inline]
pub fn reward_beneficiary<SPEC: Spec, DB: Database>(
data: &mut EVMData<'_, DB>,
gas: &Gas,
gas_refund: u64,
) -> Result<(), EVMError<DB::Error>> {
if data.env.tx.taiko.is_anchor {
return Ok(());
}
let beneficiary = data.env.block.coinbase;
let effective_gas_price = data.env.effective_gas_price();

// transfer fee to coinbase/beneficiary.
// EIP-1559 discard basefee for coinbase transfer. Basefee amount of gas is discarded.
let coinbase_gas_price = if SPEC::enabled(LONDON) {
effective_gas_price.saturating_sub(data.env.block.basefee)
} else {
effective_gas_price
};

let (coinbase_account, _) = data
.journaled_state
.load_account(beneficiary, data.db)
.map_err(EVMError::Database)?;

coinbase_account.mark_touch();
coinbase_account.info.balance = coinbase_account
.info
.balance
.saturating_add(coinbase_gas_price * U256::from(gas.spend() - gas_refund));

let treasury = data.env.tx.taiko.treasury;
let basefee = data.env.block.basefee;

let (treasury_account, _) = data
.journaled_state
.load_account(treasury, data.db)
.map_err(EVMError::Database)?;

treasury_account.mark_touch();
treasury_account.info.balance = treasury_account
.info
.balance
.saturating_add(basefee * U256::from(gas.spend() - gas_refund));
Ok(())
}
1 change: 1 addition & 0 deletions crates/revm/src/taiko/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod handler;