Skip to content
Closed
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
2 changes: 1 addition & 1 deletion specs/opcode/41COINBASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ then push the `address` to the stack.

## Code

Please refer to `src/zkevm_specs/evm/execution/coinbase.py`.
Please refer to `src/zkevm_specs/evm/execution/block_coinbase.py`.
39 changes: 39 additions & 0 deletions specs/opcode/42TIMESTAMP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Timestamp op code

## Procedure

The `TIMESTAMP` opcode pushes the timestamp of the current block onto the stack.

## EVM behavior

The `TIMESTAMP` opcode loads a `timestamp` (8 bytes of data) from the block context and then
pushes it onto the stack.

## Circuit behavior

1. construct block context table
2. do busmapping lookup for stack write operation
3. other implicit check: bytes length

## Constraints

1. opId = 0x42
2. State transition:
- gc + 1 (1 stack write)
- stack_pointer - 1
- pc + 1
- gas + 2
3. Lookups: 2
- `timestamp` is on the top of stack
- `timestamp` is in the block context table
4. Others:
- `timestamp` fits into 8 bytes

## 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/block_timestamp.py`.
2 changes: 2 additions & 0 deletions src/zkevm_specs/evm/execution/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from .jumpi import *
from .push import *
from .block_coinbase import *
from .block_timestamp import *
from .caller import *
from .slt_sgt import *
from .callvalue import *
Expand All @@ -27,6 +28,7 @@
ExecutionState.CALLVALUE: callvalue,
ExecutionState.CALLDATASIZE: calldatasize,
ExecutionState.COINBASE: coinbase,
ExecutionState.TIMESTAMP: timestamp,
ExecutionState.JUMP: jump,
ExecutionState.JUMPI: jumpi,
ExecutionState.PUSH: push,
Expand Down
22 changes: 22 additions & 0 deletions src/zkevm_specs/evm/execution/block_timestamp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from ..instruction import Instruction, Transition
from ..table import BlockContextFieldTag
from ..opcode import Opcode


def timestamp(instruction: Instruction):
opcode = instruction.opcode_lookup(True)
instruction.constrain_equal(opcode, Opcode.TIMESTAMP)
timestamp = instruction.stack_push()
# in real circuit also check timestamp raw data is 64 bit length (8 bytes)
# check block table for timestamp
instruction.constrain_equal(
timestamp,
instruction.block_context_lookup(BlockContextFieldTag.Timestamp),
)

instruction.step_state_transition_in_same_context(
opcode,
rw_counter=Transition.delta(1),
program_counter=Transition.delta(1),
stack_pointer=Transition.delta(-1),
)
65 changes: 65 additions & 0 deletions tests/evm/test_timestamp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import pytest

from zkevm_specs.evm import (
ExecutionState,
StepState,
verify_steps,
Tables,
RWTableTag,
RW,
Block,
Bytecode,
)
from zkevm_specs.util import rand_range, rand_fp, RLC, U64

TESTING_DATA = (0, 1, 2 ** 64 - 1, rand_range(2 ** 64))


@pytest.mark.parametrize("timestamp", TESTING_DATA)
def test_timestamp(timestamp: U64):
randomness = rand_fp()

block = Block(timestamp=timestamp)

bytecode = Bytecode().timestamp()
bytecode_hash = RLC(bytecode.hash(), randomness)

tables = Tables(
block_table=set(block.table_assignments(randomness)),
tx_table=set(),
bytecode_table=set(bytecode.table_assignments(randomness)),
rw_table=set(
[
(9, RW.Write, RWTableTag.Stack, 1, 1023, RLC(timestamp, randomness, 8), 0, 0),
]
),
)

verify_steps(
randomness=randomness,
tables=tables,
steps=[
StepState(
execution_state=ExecutionState.TIMESTAMP,
rw_counter=9,
call_id=1,
is_root=True,
is_create=False,
code_source=bytecode_hash,
program_counter=0,
stack_pointer=1024,
gas_left=2,
),
StepState(
execution_state=ExecutionState.STOP,
rw_counter=10,
call_id=1,
is_root=True,
is_create=False,
code_source=bytecode_hash,
program_counter=1,
stack_pointer=1023,
gas_left=0,
),
],
)