Skip to content
Merged
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,132 changes: 409 additions & 723 deletions Cargo.lock

Large diffs are not rendered by default.

94 changes: 47 additions & 47 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,29 +83,29 @@ celo-revm = { version = "0.1.0", path = "crates/celo-revm", default-features = f
celo-otel = { version = "0.1.0", path = "crates/celo-otel", default-features = false }

# Binaries
kona-host = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.6", default-features = false }
kona-client = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.6", default-features = false }
kona-host = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.7", default-features = false }
kona-client = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.7", default-features = false }

# Protocol
kona-driver = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.6", default-features = false }
kona-derive = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.6", default-features = false }
kona-genesis = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.6", default-features = false }
kona-protocol = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.6", default-features = false }
kona-registry = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.6", default-features = false }
kona-driver = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.7", default-features = false }
kona-derive = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.7", default-features = false }
kona-genesis = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.7", default-features = false }
kona-protocol = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.7", default-features = false }
kona-registry = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.7", default-features = false }

# Providers
kona-providers-alloy = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.6", default-features = false }
kona-providers-alloy = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.7", default-features = false }

# Proof
kona-mpt = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.6", default-features = false }
kona-proof = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.6", default-features = false }
kona-executor = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.6", default-features = false }
kona-std-fpvm = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.6", default-features = false }
kona-preimage = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.6", default-features = false }
kona-std-fpvm-proc = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.6", default-features = false }
kona-mpt = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.7", default-features = false }
kona-proof = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.7", default-features = false }
kona-executor = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.7", default-features = false }
kona-std-fpvm = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.7", default-features = false }
kona-preimage = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.7", default-features = false }
kona-std-fpvm-proc = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.7", default-features = false }

# Utilities
kona-cli = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.6", default-features = false }
kona-cli = { git = "https://github.com/op-rs/kona", tag = "kona-client/v1.1.7", default-features = false }

# Alloy
alloy-rlp = { version = "0.3.12", default-features = false }
Expand All @@ -115,41 +115,41 @@ alloy-serde = { version = "1.0.38", default-features = false }
alloy-chains = { version = "0.2.7", default-features = false }
alloy-network = { version = "1.0.38", default-features = false }
alloy-provider = { version = "1.0.38", default-features = false }
alloy-hardforks = { version = "0.3.5", default-features = false }
alloy-sol-types = { version = "1.3.1", default-features = false }
alloy-hardforks = { version = "0.4.4", default-features = false }
alloy-sol-types = { version = "1.4.1", default-features = false }
alloy-consensus = { version = "1.0.38", default-features = false }
alloy-transport = { version = "1.0.38", default-features = false }
alloy-rpc-types = { version = "1.0.38", default-features = false }
alloy-rpc-client = { version = "1.0.38", default-features = false }
alloy-primitives = { version = "1.3.1", default-features = false }
alloy-primitives = { version = "1.4.1", default-features = false }
alloy-rpc-types-eth = { version = "1.0.38", default-features = false }
alloy-transport-http = { version = "1.0.38", default-features = false }
alloy-rpc-types-engine = { version = "1.0.38", default-features = false }
alloy-network-primitives = { version = "1.0.38", default-features = false }

# OP Alloy
alloy-op-hardforks = { version = "0.3.5", default-features = false }
op-alloy-consensus = { version = "0.20.0", default-features = false }
op-alloy-rpc-types = { version = "0.20.0", default-features = false }
op-alloy-rpc-types-engine = { version = "0.20.0", default-features = false }
alloy-op-hardforks = { version = "0.4.4", default-features = false }
op-alloy-consensus = { version = "0.22.0", default-features = false }
op-alloy-rpc-types = { version = "0.22.0", default-features = false }
op-alloy-rpc-types-engine = { version = "0.22.0", default-features = false }

# Execution
revm = { version = "29.0.1", default-features = false }
op-revm = { version = "10.1.0", default-features = false }
alloy-evm = { version = "0.21.0", default-features = false }
alloy-op-evm = { version = "0.21.0", default-features = false }
revm = { version = "31.0.1", default-features = false }
op-revm = { version = "12.0.1", default-features = false }
alloy-evm = { version = "0.23.1", default-features = false }
alloy-op-evm = { version = "0.23.1", default-features = false }

# Dependencies not in upstream kona-client
# These are kept separately to make it easier to compare and update the versions above
revm-context-interface = { version = "10.2.0", default-features = false }
revm-handler = { version = "10.0.0", default-features = false }
revm-context = { version = "9.0.2", default-features = false }
revm-context-interface = { version = "12.0.1", default-features = false }
revm-handler = { version = "12.0.1", default-features = false }
revm-context = { version = "11.0.1", default-features = false }
alloy-signer = { version = "1.0.38", default-features = false }

# Hokulea
hokulea-eigenda = { git = "https://github.com/Layr-Labs/hokulea", rev = "90404fb", default-features = false}
hokulea-proof = { git = "https://github.com/Layr-Labs/hokulea", rev = "90404fb", default-features = false}
hokulea-host-bin = { git = "https://github.com/Layr-Labs/hokulea", rev = "90404fb", default-features = false}
hokulea-eigenda = { git = "https://github.com/Layr-Labs/hokulea", tag = "hokulea-client/v1.0.2", default-features = false }
hokulea-proof = { git = "https://github.com/Layr-Labs/hokulea", tag = "hokulea-client/v1.0.2", default-features = false }
hokulea-host-bin = { git = "https://github.com/Layr-Labs/hokulea", tag = "hokulea-client/v1.0.2", default-features = false }

# General
url = "2.5.4"
Expand Down Expand Up @@ -206,18 +206,18 @@ opentelemetry-appender-tracing = "0.30.1"
uuid = { version = "1", features = ["v4"] }

[patch."https://github.com/op-rs/kona"]
kona-host = { git = "https://github.com/celo-org/kona", rev = "2c33430" }
kona-client = { git = "https://github.com/celo-org/kona", rev = "2c33430" }
kona-driver = { git = "https://github.com/celo-org/kona", rev = "2c33430" }
kona-derive = { git = "https://github.com/celo-org/kona", rev = "2c33430" }
kona-genesis = { git = "https://github.com/celo-org/kona", rev = "2c33430" }
kona-protocol = { git = "https://github.com/celo-org/kona", rev = "2c33430" }
kona-registry = { git = "https://github.com/celo-org/kona", rev = "2c33430" }
kona-providers-alloy = { git = "https://github.com/celo-org/kona", rev = "2c33430" }
kona-mpt = { git = "https://github.com/celo-org/kona", rev = "2c33430" }
kona-proof = { git = "https://github.com/celo-org/kona", rev = "2c33430" }
kona-executor = { git = "https://github.com/celo-org/kona", rev = "2c33430" }
kona-std-fpvm = { git = "https://github.com/celo-org/kona", rev = "2c33430" }
kona-preimage = { git = "https://github.com/celo-org/kona", rev = "2c33430" }
kona-std-fpvm-proc = { git = "https://github.com/celo-org/kona", rev = "2c33430" }
kona-cli = { git = "https://github.com/celo-org/kona", rev = "2c33430" }
kona-host = { git = "https://github.com/celo-org/kona", rev = "b0ea596" }
kona-client = { git = "https://github.com/celo-org/kona", rev = "b0ea596" }
kona-driver = { git = "https://github.com/celo-org/kona", rev = "b0ea596" }
kona-derive = { git = "https://github.com/celo-org/kona", rev = "b0ea596" }
kona-genesis = { git = "https://github.com/celo-org/kona", rev = "b0ea596" }
kona-protocol = { git = "https://github.com/celo-org/kona", rev = "b0ea596" }
kona-registry = { git = "https://github.com/celo-org/kona", rev = "b0ea596" }
kona-providers-alloy = { git = "https://github.com/celo-org/kona", rev = "b0ea596" }
kona-mpt = { git = "https://github.com/celo-org/kona", rev = "b0ea596" }
kona-proof = { git = "https://github.com/celo-org/kona", rev = "b0ea596" }
kona-executor = { git = "https://github.com/celo-org/kona", rev = "b0ea596" }
kona-std-fpvm = { git = "https://github.com/celo-org/kona", rev = "b0ea596" }
kona-preimage = { git = "https://github.com/celo-org/kona", rev = "b0ea596" }
kona-std-fpvm-proc = { git = "https://github.com/celo-org/kona", rev = "b0ea596" }
kona-cli = { git = "https://github.com/celo-org/kona", rev = "b0ea596" }
1 change: 1 addition & 0 deletions bin/host/src/single/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ impl HintHandler for CeloSingleChainHintHandler {
&SingleChainHostWithEigenDA {
kona_cfg: cfg.kona_cfg.clone(),
eigenda_proxy_address: cfg.eigenda_proxy_address.clone(),
recency_window: 0,
verbose: cfg.verbose,
},
&SingleChainProvidersWithEigenDA {
Expand Down
2 changes: 1 addition & 1 deletion crates/alloy-celo-evm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ op-alloy-consensus.workspace = true

revm.workspace = true
op-revm.workspace = true
celo-revm = { version = "0.1.0", path = "../celo-revm", default-features = false }
celo-revm = { version = "0.1.0", path = "../celo-revm", default-features = false, features = ["alloy-op-evm"] }
spin.workspace = true

[dev-dependencies]
Expand Down
3 changes: 2 additions & 1 deletion crates/alloy-celo-evm/src/block/receipt_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use core::fmt::Debug;
use op_alloy_consensus::OpDepositReceipt;

use crate::cip64_storage::{Cip64Storage, get_tx_identifier, none_tx_identifier};
use revm::context_interface::Block;

/// Receipt builder operating on celo-alloy types.
#[derive(Debug, Clone, Default)]
Expand Down Expand Up @@ -47,7 +48,7 @@ impl OpReceiptBuilder for CeloAlloyReceiptBuilder {
) -> Result<Self::Receipt, ReceiptBuilderCtx<'a, CeloTxEnvelope, E>> {
match ctx.tx.tx_type() {
CeloTxType::Cip64 => {
let base_fee = ctx.evm.block().basefee as u128;
let base_fee = ctx.evm.block().basefee() as u128;
// For CIP-64 transactions, calculate the base fee in ERC20
let base_fee_in_erc20 = if let CeloTxEnvelope::Cip64(cip64) = ctx.tx {
if cip64.tx().fee_currency.is_none() {
Expand Down
2 changes: 2 additions & 0 deletions crates/alloy-celo-evm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ where
type Error = EVMError<DB::Error, OpTransactionError>;
type HaltReason = OpHaltReason;
type Spec = OpSpecId;
type BlockEnv = BlockEnv;
type Precompiles = CeloPrecompiles;
type Inspector = I;

Expand Down Expand Up @@ -277,6 +278,7 @@ impl EvmFactory for CeloEvmFactory {
EVMError<DBError, OpTransactionError>;
type HaltReason = OpHaltReason;
type Spec = OpSpecId;
type BlockEnv = BlockEnv;
type Precompiles = CeloPrecompiles;

fn create_evm<DB: Database>(
Expand Down
10 changes: 6 additions & 4 deletions crates/celo-revm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ keywords.workspace = true
license.workspace = true
repository.workspace = true
readme.workspace = true
rust-version.workspace = true

[package.metadata.docs.rs]
all-features = true
Expand All @@ -26,7 +27,7 @@ all = "warn"
celo-alloy-consensus.workspace = true

# revm
revm = { workspace = true }
revm.workspace = true
op-revm = { workspace = true, features = ["serde"] }
revm-context-interface.workspace = true

Expand All @@ -38,6 +39,7 @@ alloy-evm.workspace = true
# OP Alloy
op-alloy-consensus.workspace = true
alloy-sol-types.workspace = true
alloy-op-evm = { workspace = true, optional = true }

# misc
auto_impl.workspace = true
Expand All @@ -55,12 +57,14 @@ alloy-eips.workspace = true
revm-handler.workspace = true

[features]
default = ["std", "c-kzg", "secp256k1", "portable", "blst"]
default = ["std", "c-kzg", "secp256k1", "portable", "blst", "alloy-op-evm"]
std = [
"serde?/std",
"revm/std",
"tracing/std",
"alloy-op-evm?/std",
]
alloy-op-evm = ["dep:alloy-op-evm"]
hashbrown = ["revm/hashbrown"]
serde = [
"dep:serde",
Expand All @@ -85,8 +89,6 @@ optional_no_base_fee = ["revm/optional_no_base_fee"]
# See comments in `revm-precompile`
secp256k1 = ["revm/secp256k1"]
c-kzg = ["revm/c-kzg"]
# `kzg-rs` is not audited but useful for `no_std` environment, use it with causing and default to `c-kzg` if possible.
kzg-rs = ["revm/kzg-rs"]
blst = ["revm/blst"]
bn = ["revm/bn"]
serde-bincode-compat = [
Expand Down
68 changes: 49 additions & 19 deletions crates/celo-revm/src/contracts/core_contracts.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
//! # System calls for interacting with Celo core contracts
//!
//! System calls are executed without calling `finalize()`, using a "keep by default" approach
//! where state changes (accounts, storage) remain in the EVM's journal. This avoids needing
//! `set_storage` (which is not in upstream revm) to manually merge state back after system calls.
//!
//! When the main transaction reverts, fee debit changes persist because the main
//! transaction is executed as a subcall with automatic checkpoint/revert handling (see
//! [`make_call_frame`](https://github.com/bluealloy/revm/blob/main/crates/handler/src/frame.rs)).
//!
//! # Key Behaviors
//! - **State changes**: Remain in the journal (accounts, storage, etc.)
//! - **Logs**: Extracted and cleared from journal during `ExecutionResult` creation
//! - **Transient storage**: Explicitly cleared after each system call (EIP-1153 requirement)
//! - **transaction_id**: Restored to keep warmed addresses from system call

use crate::{CeloContext, constants::get_addresses, evm::CeloEvm};
use alloy_primitives::{
Address, Bytes, U256, hex,
map::{DefaultHashBuilder, HashMap},
};
use alloy_sol_types::{SolCall, SolType, sol, sol_data};
use revm::{
Database, ExecuteEvm,
Database,
context_interface::ContextTr,
handler::{EvmTr, SystemCallEvm},
inspector::Inspector,
primitives::Log,
state::EvmState,
};
use revm_context_interface::{
ContextSetters,
Expand Down Expand Up @@ -69,19 +84,37 @@ pub fn get_revert_message(output: Bytes) -> String {
}
}

/// Call a core contract function and return the result.
/// Call a core contract in read-only mode (checkpoint/revert to discard state changes).
pub fn call_read_only<DB, INSP>(
evm: &mut CeloEvm<DB, INSP>,
address: Address,
calldata: Bytes,
gas_limit: Option<u64>,
) -> Result<(Bytes, Vec<Log>, u64), CoreContractError>
where
DB: Database,
INSP: Inspector<CeloContext<DB>>,
{
let checkpoint = evm.ctx().journal_mut().checkpoint();
let result = call(evm, address, calldata, gas_limit);
evm.ctx().journal_mut().checkpoint_revert(checkpoint);
result
}

/// Call a core contract function. State changes remain in the EVM's journal.
pub fn call<DB, INSP>(
evm: &mut CeloEvm<DB, INSP>,
address: Address,
calldata: Bytes,
gas_limit: Option<u64>,
) -> Result<(Bytes, EvmState, Vec<Log>, u64), CoreContractError>
) -> Result<(Bytes, Vec<Log>, u64), CoreContractError>
where
DB: Database,
INSP: Inspector<CeloContext<DB>>,
{
// Preserve the tx set in the evm before the call to restore it afterwards
// Preserve the tx and transaction_id to restore afterwards
let prev_tx = evm.ctx().tx().clone();
let prev_transaction_id = evm.ctx().journal_ref().transaction_id;

let call_result = if let Some(limit) = gas_limit {
evm.transact_system_call_with_gas_limit(address, calldata, limit)
Expand All @@ -91,27 +124,24 @@ where

// Restore the original transaction context
evm.ctx().set_tx(prev_tx);
// Clear transient storage (EIP-1153)
evm.ctx().journal_mut().transient_storage.clear();
// Restore transaction_id for correct warm/cold accounting
evm.ctx().journal_mut().transaction_id = prev_transaction_id;

let exec_result = match call_result {
Err(e) => return Err(CoreContractError::Evm(e.to_string())),
Ok(o) => o,
};

// Get logs from the execution result
let logs_from_call = match &exec_result {
ExecutionResult::Success { logs, .. } => logs.clone(),
_ => Vec::new(),
};

let state = evm.finalize();

// Check success
match exec_result {
ExecutionResult::Success {
output: Output::Call(bytes),
gas_used,
logs,
..
} => Ok((bytes, state, logs_from_call, gas_used)),
} => Ok((bytes, logs, gas_used)),
ExecutionResult::Halt { reason, .. } => Err(CoreContractError::ExecutionFailed(format!(
"halt: {reason:?}"
))),
Expand All @@ -131,15 +161,15 @@ where
INSP: Inspector<CeloContext<DB>>,
{
let fee_curr_dir = get_addresses(evm.ctx_ref().cfg().chain_id).fee_currency_directory;
let call_result = call(
let call_result = call_read_only(
evm,
fee_curr_dir,
getCurrenciesCall {}.abi_encode().into(),
None,
);

let output_bytes = match call_result {
Ok((bytes, _, _, _)) => bytes,
Ok((bytes, _, _)) => bytes,
Err(e) => {
debug!(target: "celo_core_contracts", "get_currencies: failed to call 0x{:x}: {}", fee_curr_dir, e);
return Vec::new();
Expand Down Expand Up @@ -176,15 +206,15 @@ where
HashMap::with_capacity_and_hasher(currencies.len(), DefaultHashBuilder::default());

for token in currencies {
let call_result = call(
let call_result = call_read_only(
evm,
get_addresses(evm.ctx_ref().cfg().chain_id).fee_currency_directory,
getExchangeRateCall { token: *token }.abi_encode().into(),
None,
);

let output_bytes = match call_result {
Ok((bytes, _, _, _)) => bytes,
Ok((bytes, _, _)) => bytes,
Err(e) => {
debug!(target: "celo_core_contracts", "get_exchange_rates: failed to call for token 0x{:x}: {}", token, e);
continue;
Expand Down Expand Up @@ -218,7 +248,7 @@ where
HashMap::with_capacity_and_hasher(currencies.len(), DefaultHashBuilder::default());

for token in currencies {
let (output_bytes, _, _, _) = call(
let (output_bytes, _, _) = call_read_only(
evm,
get_addresses(evm.ctx_ref().cfg().chain_id).fee_currency_directory,
getCurrencyConfigCall { token: *token }.abi_encode().into(),
Expand Down
Loading
Loading