Skip to content

Commit

Permalink
apply morph changes
Browse files Browse the repository at this point in the history
  • Loading branch information
chengwenxi committed Sep 6, 2024
1 parent 3085f04 commit 2e54162
Show file tree
Hide file tree
Showing 45 changed files with 1,259 additions and 115 deletions.
22 changes: 16 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,17 @@ jobs:
strategy:
fail-fast: false
matrix:
rust: ["stable", "beta", "nightly"]
flags: ["--no-default-features", "", "--all-features"]
rust: [ "stable", "beta", "nightly" ]
flags: [
"--no-default-features",
"",
"--features=\"morph\"",
"--features=\"morph, morph-poseidon-codehash\"",
"--features=\"all, morph\"",
"--features=\"all, morph, morph-poseidon-codehash\"",
"--features=\"optimism\"",
"--features=\"all, optimism\""
]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
Expand All @@ -38,7 +47,7 @@ jobs:
strategy:
fail-fast: false
matrix:
features: ["", "optimism,kzg-rs"]
features: [ "", "optimism,kzg-rs" ]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
Expand All @@ -53,7 +62,7 @@ jobs:
strategy:
fail-fast: false
matrix:
features: ["", "serde", "std"]
features: [ "", "serde", "std" ]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
Expand All @@ -66,9 +75,10 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- run: cargo clippy --workspace --all-targets --all-features
- run: cargo clippy --workspace --all-targets --features all,morph
env:
RUSTFLAGS: -Dwarnings
- run: cargo clippy --workspace --all-targets --features all,optimism

docs:
name: docs
Expand All @@ -79,7 +89,7 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
with:
components: rust-docs
- run: cargo doc --workspace --all-features --no-deps --document-private-items
- run: cargo doc --workspace --features all,morph --no-deps --document-private-items
env:
RUSTDOCFLAGS: "--cfg docsrs -D warnings"

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ethereum-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ jobs:
timeout-minutes: 30
strategy:
matrix:
profile: [ethtests, release]
target: [i686-unknown-linux-gnu, x86_64-unknown-linux-gnu]
profile: [ ethtests, release ]
target: [ i686-unknown-linux-gnu, x86_64-unknown-linux-gnu ]
steps:
- name: Checkout sources
uses: actions/checkout@v4
Expand Down
30 changes: 26 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ debug = true
[profile.ethtests]
inherits = "test"
opt-level = 3

[patch.crates-io]
ff = { git = "https://github.com/scroll-tech/ff", branch = "feat/sp1" }
4 changes: 4 additions & 0 deletions bins/revm-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,7 @@ name = "transfer"

[[bin]]
name = "burntpix"

[features]
morph = ["revm/morph"]
morph-poseidon-codehash = ["morph", "revm/morph-poseidon-codehash"]
4 changes: 4 additions & 0 deletions bins/revme/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,7 @@ thiserror = "1.0"
triehash = "0.8"
walkdir = "2.5"
k256 = { version = "0.13.3", features = ["ecdsa"] }

[features]
morph = ["revm/morph"]
morph-poseidon-codehash = ["morph", "revm/morph-poseidon-codehash"]
12 changes: 10 additions & 2 deletions bins/revme/src/cmd/statetest/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,19 @@ pub fn execute_test_suite(
// Create database and insert cache
let mut cache_state = revm::CacheState::new(false);
for (address, info) in unit.pre {
let code_hash = keccak256(&info.code);
#[cfg(feature = "morph")]
let code_size = info.code.len();
let keccak_code_hash = keccak256(&info.code);
#[cfg(feature = "morph-poseidon-codehash")]
let poseidon_code_hash = revm::primitives::poseidon(&info.code);
let bytecode = to_analysed(Bytecode::new_raw(info.code));
let acc_info = revm::primitives::AccountInfo {
balance: info.balance,
code_hash,
#[cfg(feature = "morph")]
code_size,
code_hash: keccak_code_hash,
#[cfg(feature = "morph-poseidon-codehash")]
poseidon_code_hash,
code: Some(bytecode),
nonce: info.nonce,
};
Expand Down
26 changes: 26 additions & 0 deletions crates/interpreter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ all = "warn"
[dependencies]
revm-primitives = { path = "../primitives", version = "9.0.0", default-features = false }

cfg-if = "1.0"
paste = { version = "1.0", optional = true }
phf = { version = "0.11", default-features = false, optional = true, features = [
"macros",
Expand Down Expand Up @@ -60,6 +61,20 @@ negate-optimism-default-handler = [
"revm-primitives/negate-optimism-default-handler",
]

morph = ["revm-primitives/morph"]
# Morph default handler enabled Morph handler register by default in EvmBuilder.
morph-default-handler = [
"morph",
"revm-primitives/morph-default-handler",
]
negate-morph-default-handler = [
"revm-primitives/negate-morph-default-handler",
]
morph-poseidon-codehash = [
"morph",
"revm-primitives/morph-poseidon-codehash",
]

dev = [
"memory_limit",
"optional_balance_check",
Expand All @@ -78,3 +93,14 @@ optional_no_base_fee = ["revm-primitives/optional_no_base_fee"]
optional_beneficiary_reward = ["revm-primitives/optional_beneficiary_reward"]

kzg-rs = ["revm-primitives/kzg-rs"]

all = [
"std",
"serde",
"arbitrary",
"asm-keccak",
"portable",
"parse",
"dev",
"kzg-rs",
]
3 changes: 1 addition & 2 deletions crates/interpreter/src/function_stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,8 @@ impl FunctionStack {

/// Pops a frame from the stack and sets current_code_idx to the popped frame's idx.
pub fn pop(&mut self) -> Option<FunctionReturnFrame> {
self.return_stack.pop().map(|frame| {
self.return_stack.pop().inspect(|frame| {
self.current_code_idx = frame.idx;
frame
})
}

Expand Down
4 changes: 4 additions & 0 deletions crates/interpreter/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ pub trait Host {
/// Get code hash of `address` and if the account is cold.
fn code_hash(&mut self, address: Address) -> Option<Eip7702CodeLoad<B256>>;

#[cfg(feature = "morph")]
/// Get code size of `address` and if the account is cold.
fn code_size(&mut self, address: Address) -> Option<(usize, bool)>;

/// Get storage value of `address` at `index` and if the account is cold.
fn sload(&mut self, address: Address, index: U256) -> Option<StateLoad<U256>>;

Expand Down
6 changes: 6 additions & 0 deletions crates/interpreter/src/host/dummy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ impl Host for DummyHost {
Some(Default::default())
}

#[inline]
#[cfg(feature = "morph")]
fn code_size(&mut self, _address: Address) -> Option<(usize, bool)> {
Some((0, false))
}

#[inline]
fn code_hash(&mut self, _address: Address) -> Option<Eip7702CodeLoad<B256>> {
Some(Eip7702CodeLoad::new_not_delegated(KECCAK_EMPTY, false))
Expand Down
69 changes: 67 additions & 2 deletions crates/interpreter/src/instructions/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub fn selfbalance<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter,
push!(interpreter, balance.data);
}

#[cfg(not(feature = "morph"))]
pub fn extcodesize<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, host: &mut H) {
pop_address!(interpreter, address);
let Some(code) = host.code(address) else {
Expand All @@ -58,6 +59,18 @@ pub fn extcodesize<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter,
push!(interpreter, U256::from(code.len()));
}

#[cfg(feature = "morph")]
pub fn extcodesize<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, host: &mut H) {
pop_address!(interpreter, address);
let Some((code_size, is_cold)) = host.code_size(address) else {
interpreter.instruction_result = InstructionResult::FatalExternalError;
return;
};
gas!(interpreter, warm_cold_cost(is_cold));

push!(interpreter, U256::from(code_size));
}

/// EIP-1052: EXTCODEHASH opcode
pub fn extcodehash<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, host: &mut H) {
check!(interpreter, CONSTANTINOPLE);
Expand Down Expand Up @@ -105,6 +118,7 @@ pub fn extcodecopy<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter,
.set_data(memory_offset, code_offset, len, &code);
}

#[cfg(not(feature = "morph"))]
pub fn blockhash<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, host: &mut H) {
gas!(interpreter, gas::BLOCKHASH);
pop_top!(interpreter, number);
Expand All @@ -117,6 +131,37 @@ pub fn blockhash<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, ho
*number = U256::from_be_bytes(hash.0);
}

#[cfg(feature = "morph")]
pub fn blockhash<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, host: &mut H) {
use revm_primitives::BLOCK_HASH_HISTORY;

gas!(interpreter, gas::BLOCKHASH);
pop_top!(interpreter, number);

let block_number = host.env().block.number;

match block_number.checked_sub(*number) {
Some(diff) if !diff.is_zero() => {
let diff = as_u64_saturated!(diff);
let block_number = as_u64_or_fail!(interpreter, number);

if SPEC::enabled(PRE_BERNOULLI) && diff <= BLOCK_HASH_HISTORY {
let mut hasher = crate::primitives::Keccak256::new();
hasher.update(host.env().cfg.chain_id.to_be_bytes());
hasher.update(block_number.to_be_bytes());
*number = U256::from_be_bytes(*hasher.finalize());
return;
}
}
_ => {
// If blockhash is requested for the current block, the hash should be 0, so we fall
// through.
}
}

*number = U256::ZERO;
}

pub fn sload<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, host: &mut H) {
pop_top!(interpreter, index);
let Some(value) = host.sload(interpreter.contract.target_address, *index) else {
Expand Down Expand Up @@ -153,7 +198,14 @@ pub fn sstore<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, host:
/// EIP-1153: Transient storage opcodes
/// Store value to transient storage
pub fn tstore<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, host: &mut H) {
check!(interpreter, CANCUN);
cfg_if::cfg_if! {
if #[cfg(feature = "morph")] {
check!(interpreter, CURIE);
} else {
check!(interpreter, CANCUN);
}
}

require_non_staticcall!(interpreter);
gas!(interpreter, gas::WARM_STORAGE_READ_COST);

Expand All @@ -165,7 +217,14 @@ pub fn tstore<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, host:
/// EIP-1153: Transient storage opcodes
/// Load value from transient storage
pub fn tload<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, host: &mut H) {
check!(interpreter, CANCUN);
cfg_if::cfg_if! {
if #[cfg(feature = "morph")] {
check!(interpreter, CURIE);
} else {
check!(interpreter, CANCUN);
}
}

gas!(interpreter, gas::WARM_STORAGE_READ_COST);

pop_top!(interpreter, index);
Expand Down Expand Up @@ -210,6 +269,12 @@ pub fn selfdestruct<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter,
require_non_staticcall!(interpreter);
pop_address!(interpreter, target);

#[cfg(feature = "morph")]
if SPEC::enabled(PRE_BERNOULLI) {
interpreter.instruction_result = InstructionResult::NotActivated;
return;
}

let Some(res) = host.selfdestruct(interpreter.contract.target_address, target) else {
interpreter.instruction_result = InstructionResult::FatalExternalError;
return;
Expand Down
Loading

0 comments on commit 2e54162

Please sign in to comment.