diff --git a/setup.cfg b/setup.cfg index b473b9caf..c03149535 100644 --- a/setup.cfg +++ b/setup.cfg @@ -24,15 +24,18 @@ install_requires = eth-keys==0.4.0 rlp==3.0.0 eth-utils==2.0.0 + platformdirs==3.11.0 + exceptiongroup==1.1.3 + eth-typing==3.5.1 [options.packages.find] where = src [options.extras_require] test = - pytest == 7.0.0 + pytest == 7.4.3 lint = - black == 23.10 + black == 23.10.1 mypy == 1.6.1 flake8 == 6.1.0 @@ -46,3 +49,6 @@ per-file-ignores = [mypy] exclude = ['build'] ignore_missing_imports = true +# src_data in CopyCircuit.copy() hits arg-type error. +# see https://github.com/python/mypy/issues/6001 +disable_error_code = ["arg-type"] diff --git a/src/zkevm_specs/evm_circuit/__init__.py b/src/zkevm_specs/evm_circuit/__init__.py index d445ee9a1..ee05962d0 100644 --- a/src/zkevm_specs/evm_circuit/__init__.py +++ b/src/zkevm_specs/evm_circuit/__init__.py @@ -7,4 +7,3 @@ from .table import * from .typing import * from .util import * -from .precompile import * diff --git a/src/zkevm_specs/evm_circuit/instruction.py b/src/zkevm_specs/evm_circuit/instruction.py index 8ffdfcf11..7d9cb954c 100644 --- a/src/zkevm_specs/evm_circuit/instruction.py +++ b/src/zkevm_specs/evm_circuit/instruction.py @@ -255,7 +255,7 @@ def constrain_step_state_transition(self, **kwargs: Transition): ) elif transition.kind == TransitionKind.ToWord: curr, next = cast(Word, curr), cast(Word, next) - # mypy gets confused here and thinkgs value must be FQ. + # mypy gets confused here and thinks value must be FQ. value = cast(Word, transition.value) # type: ignore assert next.lo.expr() == value.lo.expr() and next.hi.expr() == value.hi.expr(), ConstraintUnsatFailure( # type: ignore f"State {key} should transit to {transition.value}, but got {next}" diff --git a/src/zkevm_specs/evm_circuit/typing.py b/src/zkevm_specs/evm_circuit/typing.py index ebd0b66cb..56de28a02 100644 --- a/src/zkevm_specs/evm_circuit/typing.py +++ b/src/zkevm_specs/evm_circuit/typing.py @@ -23,6 +23,7 @@ U256, FQ, IntOrFQ, + IntOrFQOrWord, RLC, WordOrValue, Word, @@ -1010,9 +1011,9 @@ def copy( self, r: FQ, rw_dict: RWDictionary, - src_id: IntOrFQ, + src_id: IntOrFQOrWord, src_tag: CopyDataTypeTag, - dst_id: IntOrFQ, + dst_id: IntOrFQOrWord, dst_tag: CopyDataTypeTag, src_addr: IntOrFQ, src_addr_end: IntOrFQ, diff --git a/src/zkevm_specs/util/arithmetic.py b/src/zkevm_specs/util/arithmetic.py index c6aa2123e..1ea3ccfc6 100644 --- a/src/zkevm_specs/util/arithmetic.py +++ b/src/zkevm_specs/util/arithmetic.py @@ -195,6 +195,9 @@ def __repr__(self) -> str: return f"Value({hex(self.lo.expr().n)})" +IntOrFQOrWord = Union[int, FQ, Word] + + @runtime_checkable class Expression(Protocol): def expr(self) -> FQ: diff --git a/tests/evm/test_create.py b/tests/evm/test_create.py index a66cb0f1b..e9a039c53 100644 --- a/tests/evm/test_create.py +++ b/tests/evm/test_create.py @@ -26,8 +26,8 @@ GAS_COST_CREATE, GAS_COST_INITCODE_WORD, ) -from zkevm_specs.util import Word -from zkevm_specs.util.typing import U256 +from zkevm_specs.util import Word, U160, U256 + CreateContext = namedtuple( "CreateContext", @@ -47,7 +47,7 @@ ) -CALLER = Account(address=0xFE, balance=int(1e20), nonce=10) +CALLER = Account(address=U160(0xFE), balance=U256(int(1e20)), nonce=U256(10)) def gen_bytecode(is_return: bool, offset: int, has_init_code: bool) -> Bytecode: @@ -272,11 +272,11 @@ def test_create_create2( ( i, ( - init_codes.code[i - stack.offset], - init_codes.is_code[i - stack.offset], + int(init_codes.code[i - stack.offset]), + int(init_codes.is_code[i - stack.offset]), ) if i - stack.offset < len(init_codes.code) - else (0, 0), + else (int(0), int(0)), ) for i in range(stack.offset, stack.offset + stack.size) ] diff --git a/tests/evm/test_memory.py b/tests/evm/test_memory.py index bd11bf298..afd98ba68 100644 --- a/tests/evm/test_memory.py +++ b/tests/evm/test_memory.py @@ -6,11 +6,10 @@ Opcode, verify_steps, Tables, - Block, Bytecode, RWDictionary, ) -from zkevm_specs.util import Word +from zkevm_specs.util import Word, U64 from common import memory_expansion TESTING_DATA = ( @@ -58,7 +57,7 @@ def test_memory(opcode: Opcode, offset: int, value: int, memory: bytes): offset_word = Word(offset) value_word = Word(value) call_id = 1 - curr_memory_word_size = 0 + curr_memory_word_size = U64(0) length = offset is_mload = opcode == Opcode.MLOAD @@ -95,15 +94,15 @@ def test_memory(opcode: Opcode, offset: int, value: int, memory: bytes): rw_dictionary.memory_write(call_id, offset + idx, memory[idx]) tables = Tables( - block_table=set(Block().table_assignments()), + block_table=set(), tx_table=set(), withdrawal_table=set(), bytecode_table=set(bytecode.table_assignments()), - rw_table=rw_dictionary.rws, + rw_table=set(rw_dictionary.rws), ) address = offset + 1 + (is_not_mstore8 * 31) - next_mem_size, memory_gas_cost = memory_expansion(curr_memory_word_size, address) + next_mem_size, memory_gas_cost = memory_expansion(curr_memory_word_size, U64(address)) gas = Opcode.MLOAD.constant_gas_cost() + memory_gas_cost rw_counter = 35 - (is_mstore8 * 31) diff --git a/tests/evm/test_not.py b/tests/evm/test_not.py index a950f1d73..3e4f210bb 100644 --- a/tests/evm/test_not.py +++ b/tests/evm/test_not.py @@ -5,7 +5,6 @@ StepState, verify_steps, Tables, - Block, Bytecode, RWDictionary, ) @@ -26,17 +25,16 @@ @pytest.mark.parametrize("a", NOT_TESTING_DATA) def test_not(a: int): b = Word(a ^ ((1 << 256) - 1)) - a = Word(a) - bytecode = Bytecode().not_(a).stop() + bytecode = Bytecode().not_(Word(a)).stop() bytecode_hash = Word(bytecode.hash()) tables = Tables( - block_table=set(Block().table_assignments()), + block_table=set(), tx_table=set(), withdrawal_table=set(), bytecode_table=set(bytecode.table_assignments()), - rw_table=set(RWDictionary(9).stack_read(1, 1023, a).stack_write(1, 1023, b).rws), + rw_table=set(RWDictionary(9).stack_read(1, 1023, Word(a)).stack_write(1, 1023, b).rws), ) verify_steps( diff --git a/tests/evm/test_sar.py b/tests/evm/test_sar.py index db0a66409..1697c1f90 100644 --- a/tests/evm/test_sar.py +++ b/tests/evm/test_sar.py @@ -72,11 +72,7 @@ def test_sar(shift: int, a: int): b = get_int_neg(-(-get_int_abs(a) >> shift)) if int_is_neg(a) else a >> shift - shift = Word(shift) - a = Word(a) - b = Word(b) - - bytecode = Bytecode().sar(shift, a) + bytecode = Bytecode().sar(shift, Word(a)) bytecode_hash = Word(bytecode.hash()) tables = Tables( @@ -86,9 +82,9 @@ def test_sar(shift: int, a: int): bytecode_table=set(bytecode.table_assignments()), rw_table=set( RWDictionary(9) - .stack_read(1, 1022, shift) - .stack_read(1, 1023, a) - .stack_write(1, 1023, b) + .stack_read(1, 1022, Word(shift)) + .stack_read(1, 1023, Word(a)) + .stack_write(1, 1023, Word(b)) .rws ), ) diff --git a/tests/evm/test_sha3.py b/tests/evm/test_sha3.py index 2c12f14c4..05b56ae2a 100644 --- a/tests/evm/test_sha3.py +++ b/tests/evm/test_sha3.py @@ -43,7 +43,7 @@ def test_sha3(offset: U64, length: U64): memory_chunks.append(memory_snapshot[i : i + 32]) src_data = dict( [ - (i, memory_snapshot[i] if i < len(memory_snapshot) else 0) + (i, FQ(memory_snapshot[i]) if i < len(memory_snapshot) else FQ.zero()) for i in range(offset, offset + length) ] ) diff --git a/tests/evm/test_sstore.py b/tests/evm/test_sstore.py index ecc7ad55c..bb87d3177 100644 --- a/tests/evm/test_sstore.py +++ b/tests/evm/test_sstore.py @@ -128,6 +128,9 @@ def test_sstore( else: gas_refund = gas_refund + SSTORE_RESET_GAS - SLOAD_GAS + # workaround for mypy, it yells incompatible type + # bcs the type of callee_address is Optional[U160] + callee_addr = tx.callee_address or 0 tables = Tables( block_table=set(Block().table_assignments()), tx_table=set(tx.table_assignments()), @@ -140,11 +143,11 @@ def test_sstore( .call_context_read(1, CallContextFieldTag.IsStatic, 0) .call_context_read(1, CallContextFieldTag.RwCounterEndOfReversion, 0 if is_success else 14) .call_context_read(1, CallContextFieldTag.IsPersistent, is_success) - .call_context_read(1, CallContextFieldTag.CalleeAddress, Word(tx.callee_address)) + .call_context_read(1, CallContextFieldTag.CalleeAddress, Word(callee_addr)) .stack_read(1, 1022, Word(storage_key)) .stack_read(1, 1023, Word(value)) - .account_storage_write(tx.callee_address, Word(storage_key), Word(value), Word(value_prev), tx.id, Word(value_committed), rw_counter_of_reversion=None if is_success else 14) - .tx_access_list_account_storage_write(tx.id, tx.callee_address, Word(storage_key), True, True if warm else False, rw_counter_of_reversion=None if is_success else 13) + .account_storage_write(callee_addr, Word(storage_key), Word(value), Word(value_prev), tx.id, Word(value_committed), rw_counter_of_reversion=None if is_success else 14) + .tx_access_list_account_storage_write(tx.id, callee_addr, Word(storage_key), True, True if warm else False, rw_counter_of_reversion=None if is_success else 13) .tx_refund_write(tx.id, gas_refund, gas_refund_prev, rw_counter_of_reversion=None if is_success else 12) .rws # fmt: on