This repository has been archived by the owner on Jul 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 272
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
135 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# CALLER opcode | ||
|
||
## Procedure | ||
|
||
The `CALLER` opcode gets the caller address (msg.caller) from the current call. | ||
|
||
## EVM behaviour | ||
|
||
The `CALLER` opcode loads an `address` (20 bytes of data) from call context, | ||
then pushes the `address` to the stack. | ||
|
||
## Circuit behaviour | ||
|
||
1. Construct call context table in rw table | ||
2. Do busmapping lookup for stack write operation | ||
3. Do busmapping lookup for call context caller read operation | ||
|
||
## Constraints | ||
|
||
1. opId = 0x33 | ||
2. State transition: | ||
- gc + 2 (1 stack write, 1 call context read) | ||
- stack_pointer - 1 | ||
- pc + 1 | ||
- gas + 2 | ||
3. Lookups: 2 | ||
- `address` is on top of stack | ||
- `address` is in the rw table {call context, call ID, caller} | ||
|
||
## Exceptions | ||
|
||
1. stack overflow: stack is full, stack pointer = 0 | ||
2. out of gas: remaining gas is not enough | ||
|
||
## Code | ||
|
||
Please refer to `src/zkevm_specs/evm/execution/caller.py`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,5 +6,6 @@ | |
from .jump import * | ||
from .jumpi import * | ||
from .block_coinbase import * | ||
from .caller import * | ||
|
||
# Error cases |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
from ..instruction import Instruction, Transition | ||
from ..table import CallContextFieldTag | ||
from ..opcode import Opcode | ||
|
||
|
||
def caller(instruction: Instruction): | ||
opcode = instruction.opcode_lookup(True) | ||
instruction.constrain_equal(opcode, Opcode.CALLER) | ||
address = instruction.stack_push() | ||
|
||
# check [rw_table, call_context] table for caller address | ||
instruction.constrain_equal( | ||
address, | ||
instruction.bytes_to_rlc( | ||
instruction.int_to_bytes( | ||
instruction.call_context_lookup(CallContextFieldTag.CallerAddress), | ||
20, | ||
) | ||
), | ||
) | ||
|
||
instruction.constrain_same_context_state_transition( | ||
opcode, | ||
rw_counter=Transition.delta(2), | ||
program_counter=Transition.delta(1), | ||
stack_pointer=Transition.delta(-1), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import pytest | ||
|
||
from zkevm_specs.evm import ( | ||
ExecutionState, | ||
StepState, | ||
Opcode, | ||
verify_steps, | ||
Tables, | ||
RWTableTag, | ||
RW, | ||
CallContextFieldTag, | ||
Bytecode, | ||
) | ||
from zkevm_specs.util import RLCStore, U160 | ||
|
||
|
||
TESTING_DATA = ((Opcode.CALLER, 0x030201),) | ||
|
||
|
||
@pytest.mark.parametrize("opcode, address", TESTING_DATA) | ||
def test_caller(opcode: Opcode, address: U160): | ||
rlc_store = RLCStore() | ||
|
||
caller_rlc = rlc_store.to_rlc(address.to_bytes(20, "little")) | ||
|
||
bytecode = Bytecode(f"{opcode.hex()}00") | ||
bytecode_hash = rlc_store.to_rlc(bytecode.hash, 32) | ||
tables = Tables( | ||
block_table=set(), | ||
tx_table=set(), | ||
bytecode_table=set(bytecode.table_assignments(rlc_store)), | ||
rw_table=set( | ||
[ | ||
(9, RW.Write, RWTableTag.Stack, 1, 1023, caller_rlc, 0, 0), | ||
(10, RW.Read, RWTableTag.CallContext, 1, CallContextFieldTag.CallerAddress, address, 0, 0), | ||
] | ||
), | ||
) | ||
|
||
verify_steps( | ||
rlc_store=rlc_store, | ||
tables=tables, | ||
steps=[ | ||
StepState( | ||
execution_state=ExecutionState.CALLER, | ||
rw_counter=9, | ||
call_id=1, | ||
is_root=True, | ||
is_create=False, | ||
opcode_source=bytecode_hash, | ||
program_counter=0, | ||
stack_pointer=1024, | ||
gas_left=2, | ||
), | ||
StepState( | ||
execution_state=ExecutionState.STOP, | ||
rw_counter=11, | ||
call_id=1, | ||
is_root=True, | ||
is_create=False, | ||
opcode_source=bytecode_hash, | ||
program_counter=1, | ||
stack_pointer=1023, | ||
gas_left=0, | ||
), | ||
], | ||
) |