Skip to content
This repository was archived by the owner on Nov 25, 2024. It is now read-only.

Commit 33dffda

Browse files
committed
feat: implement AUTHCALL instruction
1 parent 2fa48b8 commit 33dffda

File tree

5 files changed

+107
-7
lines changed

5 files changed

+107
-7
lines changed

bin/alphanet/Cargo.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,13 @@ clap = { workspace = true, features = ["derive"] }
2222
tikv-jemallocator = { version = "0.5", optional = true }
2323

2424
[features]
25-
default = ["jemalloc"]
25+
default = [
26+
"jemalloc",
27+
"alphanet-node/optimism",
28+
"reth/optimism",
29+
"reth-node-optimism/optimism",
30+
]
31+
2632
asm-keccak = []
2733

2834
jemalloc = ["dep:tikv-jemallocator"]

crates/instructions/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,13 @@ secp256k1 = { version = "0.28.2", default-features = false, features = [
2222
"rand-std"
2323
] }
2424

25+
[features]
26+
optimism = [
27+
"revm/optimism",
28+
"revm-interpreter/optimism",
29+
"revm-precompile/optimism",
30+
"revm-primitives/optimism",
31+
]
32+
2533
[lints]
2634
workspace = true

crates/instructions/src/eip3074.rs

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
use crate::{context::InstructionsContext, BoxedInstructionWithOpCode};
22
use revm::{Database, Evm};
3-
use revm_interpreter::{pop, resize_memory, InstructionResult, Interpreter};
3+
use revm_interpreter::{
4+
gas,
5+
instructions::host::{calc_call_gas, get_memory_input_and_out_ranges},
6+
pop, pop_address, resize_memory, CallContext, CallInputs, CallScheme, InstructionResult,
7+
Interpreter, InterpreterAction, Transfer,
8+
};
49
use revm_precompile::secp256k1::ecrecover;
5-
use revm_primitives::{alloy_primitives::B512, keccak256, Address, B256};
10+
use revm_primitives::{
11+
alloy_primitives::B512, keccak256, spec_to_generic, Address, SpecId, B256, U256,
12+
};
613

714
const AUTH_OPCODE: u8 = 0xF6;
815
const AUTHCALL_OPCODE: u8 = 0xF7;
@@ -119,10 +126,73 @@ fn auth_instruction<EXT, DB: Database>(
119126

120127
fn authcall_instruction<EXT, DB: Database>(
121128
interp: &mut Interpreter,
122-
_evm: &mut Evm<'_, EXT, DB>,
123-
_ctx: &InstructionsContext,
129+
evm: &mut Evm<'_, EXT, DB>,
130+
ctx: &InstructionsContext,
124131
) {
125-
interp.gas.record_cost(133);
132+
let authorized = match ctx.get(AUTHORIZED_VAR_NAME) {
133+
Some(address) => Address::from_slice(&address),
134+
None => {
135+
interp.instruction_result = InstructionResult::Stop;
136+
return;
137+
}
138+
};
139+
140+
pop!(interp, local_gas_limit);
141+
pop_address!(interp, to);
142+
// max gas limit is not possible in real ethereum situation.
143+
let local_gas_limit = u64::try_from(local_gas_limit).unwrap_or(u64::MAX);
144+
145+
pop!(interp, value);
146+
if interp.is_static && value != U256::ZERO {
147+
interp.instruction_result = InstructionResult::CallNotAllowedInsideStatic;
148+
return;
149+
}
150+
151+
let Some((input, return_memory_offset)) = get_memory_input_and_out_ranges(interp) else {
152+
return;
153+
};
154+
155+
let Some(mut gas_limit) = spec_to_generic!(
156+
evm.spec_id(),
157+
calc_call_gas::<Evm<'_, EXT, DB>, SPEC>(
158+
interp,
159+
evm,
160+
to,
161+
value != U256::ZERO,
162+
local_gas_limit,
163+
true,
164+
true
165+
)
166+
) else {
167+
return;
168+
};
169+
170+
gas!(interp, gas_limit);
171+
172+
// add call stipend if there is value to be transferred.
173+
if value != U256::ZERO {
174+
gas_limit = gas_limit.saturating_add(gas::CALL_STIPEND);
175+
}
176+
177+
// Call host to interact with target contract
178+
interp.next_action = InterpreterAction::Call {
179+
inputs: Box::new(CallInputs {
180+
contract: to,
181+
transfer: Transfer { source: interp.contract.address, target: to, value },
182+
input,
183+
gas_limit,
184+
context: CallContext {
185+
address: to,
186+
caller: authorized,
187+
code_address: to,
188+
apparent_value: value,
189+
scheme: CallScheme::Call,
190+
},
191+
is_static: interp.is_static,
192+
return_memory_offset,
193+
}),
194+
};
195+
interp.instruction_result = InstructionResult::CallOrCreate;
126196
}
127197

128198
#[cfg(test)]
@@ -133,7 +203,7 @@ mod tests {
133203
InMemoryDB,
134204
};
135205
use revm_interpreter::{Contract, SharedMemory, Stack};
136-
use revm_primitives::{Account, Bytecode, Bytes, U256};
206+
use revm_primitives::{Account, Bytecode, Bytes};
137207
use secp256k1::{rand, Context, Message, PublicKey, Secp256k1, SecretKey, Signing};
138208
use std::convert::Infallible;
139209

crates/node/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,15 @@ reth-node-optimism.workspace = true
1818
revm-interpreter.workspace = true
1919
revm-precompile.workspace = true
2020

21+
[features]
22+
optimism = [
23+
"alphanet-precompile/optimism",
24+
"alphanet-instructions/optimism",
25+
"reth/optimism",
26+
"reth-node-optimism/optimism",
27+
"revm-interpreter/optimism",
28+
"revm-precompile/optimism",
29+
]
30+
2131
[lints]
2232
workspace = true

crates/precompile/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,11 @@ revm-primitives.workspace = true
1818
[dev-dependencies]
1919
rstest.workspace = true
2020

21+
[features]
22+
optimism = [
23+
"revm-precompile/optimism",
24+
"revm-primitives/optimism",
25+
]
26+
2127
[lints]
2228
workspace = true

0 commit comments

Comments
 (0)