diff --git a/.gitignore b/.gitignore index 6b30efc72..20f254555 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ __pycache__ build .idea *.DS_Store +.vscode diff --git a/README.md b/README.md index 442b591b0..d89b5fde7 100644 --- a/README.md +++ b/README.md @@ -14,15 +14,14 @@ We provide the [Beacon Chain](https://github.com/ethereum/eth2.0-specs) style Py Installing dependencies(Python 3.9 is required) -```python -pip3 install pytest -pip3 install . +``` +make install ``` Run the tests -```python -pytest +``` +make test ``` ## Implementations diff --git a/pyproject.toml b/pyproject.toml index ef1273fc4..a162a2714 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,6 +6,6 @@ requires = [ build-backend = "setuptools.build_meta" [tool.black] -line-length = 120 +line-length = 100 target-version = ['py39'] include = '\.pyi?$' diff --git a/setup.cfg b/setup.cfg index fde91e447..e77608300 100644 --- a/setup.cfg +++ b/setup.cfg @@ -17,7 +17,7 @@ classifiers = package_dir = = src packages = find: -python_requires = >=3.6 +python_requires = >=3.9 install_requires = pycryptodome==3.11.0 py-ecc==6.0.0 diff --git a/src/zkevm_specs/bytecode.py b/src/zkevm_specs/bytecode.py index 59c9ad20d..8b7ef60b4 100644 --- a/src/zkevm_specs/bytecode.py +++ b/src/zkevm_specs/bytecode.py @@ -29,7 +29,11 @@ def select( @is_circuit_code def check_bytecode_row( - row: Row, prev_row: Row, push_table: Set[Tuple[int, int]], keccak_table: Set[Tuple[int, int, int]], r: int + row: Row, + prev_row: Row, + push_table: Set[Tuple[int, int]], + keccak_table: Set[Tuple[int, int, int]], + r: int, ): row = Row(*[v if isinstance(v, RLC) else FQ(v) for v in row]) prev_row = Row(*[v if isinstance(v, RLC) else FQ(v) for v in prev_row]) @@ -62,7 +66,9 @@ def check_bytecode_row( # padding needs to be boolean assert_bool(row.padding) # push_data_left := is_code ? byte_push_size : push_data_left_prev - 1 - assert row.push_data_left == select(row.is_code, row.byte_push_size, prev_row.push_data_left - 1) + assert row.push_data_left == select( + row.is_code, row.byte_push_size, prev_row.push_data_left - 1 + ) # Padding if row.q_first == 0: diff --git a/src/zkevm_specs/evm/execution/begin_tx.py b/src/zkevm_specs/evm/execution/begin_tx.py index 2022b7a3a..58de3305c 100644 --- a/src/zkevm_specs/evm/execution/begin_tx.py +++ b/src/zkevm_specs/evm/execution/begin_tx.py @@ -12,7 +12,9 @@ def begin_tx(instruction: Instruction): rw_counter_end_of_reversion = instruction.call_context_lookup( CallContextFieldTag.RwCounterEndOfReversion, call_id=call_id ) - is_persistent = instruction.call_context_lookup(CallContextFieldTag.IsPersistent, call_id=call_id) + is_persistent = instruction.call_context_lookup( + CallContextFieldTag.IsPersistent, call_id=call_id + ) if instruction.is_first_step: instruction.constrain_equal(instruction.curr.rw_counter, 1) @@ -39,7 +41,11 @@ def begin_tx(instruction: Instruction): # TODO: Handle gas cost of tx level access list (EIP 2930) tx_call_data_gas_cost = instruction.tx_context_lookup(tx_id, TxContextFieldTag.CallDataGasCost) - gas_left = tx_gas - (GAS_COST_CREATION_TX if tx_is_create == 1 else GAS_COST_TX) - tx_call_data_gas_cost + gas_left = ( + tx_gas + - (GAS_COST_CREATION_TX if tx_is_create == 1 else GAS_COST_TX) + - tx_call_data_gas_cost + ) instruction.constrain_gas_left_not_underflow(gas_left) # Prepare access list of caller and callee @@ -84,7 +90,9 @@ def begin_tx(instruction: Instruction): (CallContextFieldTag.LastCalleeReturnDataOffset, 0), (CallContextFieldTag.LastCalleeReturnDataLength, 0), ]: - instruction.constrain_equal(instruction.call_context_lookup(tag, call_id=call_id), value) + instruction.constrain_equal( + instruction.call_context_lookup(tag, call_id=call_id), value + ) instruction.step_state_transition_to_new_context( rw_counter=Transition.delta(19), diff --git a/src/zkevm_specs/evm/execution/block_timestamp.py b/src/zkevm_specs/evm/execution/block_timestamp.py index a1115f80c..c503e2750 100644 --- a/src/zkevm_specs/evm/execution/block_timestamp.py +++ b/src/zkevm_specs/evm/execution/block_timestamp.py @@ -9,7 +9,8 @@ def timestamp(instruction: Instruction): timestamp = instruction.stack_push() # check block table for timestamp instruction.constrain_equal( - timestamp, instruction.int_to_rlc(instruction.block_context_lookup(BlockContextFieldTag.Timestamp), 8) + timestamp, + instruction.int_to_rlc(instruction.block_context_lookup(BlockContextFieldTag.Timestamp), 8), ) instruction.step_state_transition_in_same_context( diff --git a/src/zkevm_specs/evm/execution/end_tx.py b/src/zkevm_specs/evm/execution/end_tx.py index a8b71b459..e9d295b32 100644 --- a/src/zkevm_specs/evm/execution/end_tx.py +++ b/src/zkevm_specs/evm/execution/end_tx.py @@ -10,13 +10,17 @@ def end_tx(instruction: Instruction): # Handle gas refund (refund is capped to gas_used // MAX_REFUND_QUOTIENT_OF_GAS_USED in EIP 3529) tx_gas = instruction.tx_context_lookup(tx_id, TxContextFieldTag.Gas) gas_used = tx_gas - instruction.curr.gas_left - max_refund, _ = instruction.constant_divmod(gas_used, MAX_REFUND_QUOTIENT_OF_GAS_USED, N_BYTES_GAS) + max_refund, _ = instruction.constant_divmod( + gas_used, MAX_REFUND_QUOTIENT_OF_GAS_USED, N_BYTES_GAS + ) refund = instruction.tx_refund_read(tx_id) effective_refund = instruction.min(max_refund, refund, 8) # Add effective_refund * gas_price back to caller's balance tx_gas_price = instruction.tx_gas_price(tx_id) - value, carry = instruction.mul_word_by_u64(tx_gas_price, instruction.curr.gas_left + effective_refund) + value, carry = instruction.mul_word_by_u64( + tx_gas_price, instruction.curr.gas_left + effective_refund + ) instruction.constrain_zero(carry) tx_caller_address = instruction.tx_context_lookup(tx_id, TxContextFieldTag.CallerAddress) instruction.add_balance(tx_caller_address, [value]) @@ -33,7 +37,9 @@ def end_tx(instruction: Instruction): if instruction.next.execution_state == ExecutionState.BeginTx: # Check next tx_id is increased by 1 instruction.constrain_equal( - instruction.call_context_lookup(CallContextFieldTag.TxId, call_id=instruction.next.rw_counter), + instruction.call_context_lookup( + CallContextFieldTag.TxId, call_id=instruction.next.rw_counter + ), tx_id + 1, ) diff --git a/src/zkevm_specs/evm/execution/push.py b/src/zkevm_specs/evm/execution/push.py index 3f01f6265..cb5602684 100644 --- a/src/zkevm_specs/evm/execution/push.py +++ b/src/zkevm_specs/evm/execution/push.py @@ -14,7 +14,9 @@ def push(instruction: Instruction): for idx in range(32): index = instruction.curr.program_counter + num_pushed - idx if idx == 0 or selectors[idx - 1]: - instruction.constrain_equal(value_le_bytes[idx], instruction.opcode_lookup_at(index, False)) + instruction.constrain_equal( + value_le_bytes[idx], instruction.opcode_lookup_at(index, False) + ) else: instruction.constrain_zero(value_le_bytes[idx]) diff --git a/src/zkevm_specs/evm/instruction.py b/src/zkevm_specs/evm/instruction.py index 851321a0a..b49a5008a 100644 --- a/src/zkevm_specs/evm/instruction.py +++ b/src/zkevm_specs/evm/instruction.py @@ -94,10 +94,14 @@ def constrain_zero(self, value: FQ): assert value == 0, ConstraintUnsatFailure(f"Expected value to be 0, but got {value}") def constrain_equal(self, lhs: FQ, rhs: FQ): - assert lhs == rhs, ConstraintUnsatFailure(f"Expected values to be equal, but got {lhs} and {rhs}") + assert lhs == rhs, ConstraintUnsatFailure( + f"Expected values to be equal, but got {lhs} and {rhs}" + ) def constrain_bool(self, num: FQ): - assert num.n in [0, 1], ConstraintUnsatFailure(f"Expected value to be a bool, but got {num}") + assert num.n in [0, 1], ConstraintUnsatFailure( + f"Expected value to be a bool, but got {num}" + ) def constrain_gas_left_not_underflow(self, gas_left: FQ): self.bytes_range_lookup(gas_left, N_BYTES_GAS) @@ -125,7 +129,9 @@ def constrain_step_state_transition(self, **kwargs: Transition): for key, transition in kwargs.items(): curr, next = getattr(self.curr, key), getattr(self.next, key) if transition.kind == TransitionKind.Same: - assert next == curr, ConstraintUnsatFailure(f"State {key} should be same as {curr}, but got {next}") + assert next == curr, ConstraintUnsatFailure( + f"State {key} should be same as {curr}, but got {next}" + ) elif transition.kind == TransitionKind.Delta: assert next == curr + transition.value, ConstraintUnsatFailure( f"State {key} should transit to {curr + transition.value}, but got {next}" @@ -213,7 +219,9 @@ def select(self, condition: bool, when_true: FQ, when_false: FQ) -> FQ: def pair_select(self, value: int, lhs: int, rhs: int) -> Tuple[bool, bool]: return value == lhs, value == rhs - def constant_divmod(self, numerator: IntOrFQ, denominator: IntOrFQ, n_bytes: int) -> Tuple[int, int]: + def constant_divmod( + self, numerator: IntOrFQ, denominator: IntOrFQ, n_bytes: int + ) -> Tuple[int, int]: quotient, remainder = divmod(FQ(numerator).n, FQ(denominator).n) quotient, remainder = FQ(quotient), FQ(remainder) self.bytes_range_lookup(quotient, n_bytes) @@ -272,7 +280,9 @@ def rlc_to_le_bytes(self, rlc: RLC) -> bytes: def rlc_to_int_unchecked(self, rlc: RLC, n_bytes: int) -> int: rlc_le_bytes = self.rlc_to_le_bytes(rlc) - return self.bytes_to_int(rlc_le_bytes[:n_bytes]), self.is_zero(self.sum(rlc_le_bytes[n_bytes:])) + return self.bytes_to_int(rlc_le_bytes[:n_bytes]), self.is_zero( + self.sum(rlc_le_bytes[n_bytes:]) + ) def rlc_to_int_exact(self, rlc: RLC, n_bytes: int) -> int: rlc_le_bytes = self.rlc_to_le_bytes(rlc) @@ -349,7 +359,9 @@ def opcode_lookup_at(self, index: int, is_code: bool) -> int: else: return self.bytecode_lookup(self.curr.code_source, index, is_code) - def rw_lookup(self, rw: RW, tag: RWTableTag, inputs: Sequence[int], rw_counter: Optional[int] = None) -> Array10: + def rw_lookup( + self, rw: RW, tag: RWTableTag, inputs: Sequence[int], rw_counter: Optional[int] = None + ) -> Array10: if rw_counter is None: rw_counter = self.curr.rw_counter + self.rw_counter_offset self.rw_counter_offset += 1 @@ -478,7 +490,11 @@ def add_balance_with_reversion( state_write_counter: Optional[int] = None, ) -> Tuple[FQ, FQ]: balance, balance_prev = self.account_write_with_reversion( - account_address, AccountFieldTag.Balance, is_persistent, rw_counter_end_of_reversion, state_write_counter + account_address, + AccountFieldTag.Balance, + is_persistent, + rw_counter_end_of_reversion, + state_write_counter, ) result, carry = self.add_words([balance_prev, *values]) self.constrain_equal(balance, result) @@ -501,7 +517,11 @@ def sub_balance_with_reversion( state_write_counter: Optional[int] = None, ) -> Tuple[FQ, FQ]: balance, balance_prev = self.account_write_with_reversion( - account_address, AccountFieldTag.Balance, is_persistent, rw_counter_end_of_reversion, state_write_counter + account_address, + AccountFieldTag.Balance, + is_persistent, + rw_counter_end_of_reversion, + state_write_counter, ) result, carry = self.add_words([balance, *values]) self.constrain_equal(balance_prev, result) @@ -649,11 +669,15 @@ def memory_expansion_dynamic_length( rd_offset: Optional[int] = None, rd_length: Optional[int] = None, ) -> Tuple[int, int]: - cd_memory_size, _ = self.constant_divmod(cd_offset + cd_length + 31, 32, N_BYTES_MEMORY_SIZE) + cd_memory_size, _ = self.constant_divmod( + cd_offset + cd_length + 31, 32, N_BYTES_MEMORY_SIZE + ) next_memory_size = self.max(self.curr.memory_size, cd_memory_size, N_BYTES_MEMORY_SIZE) if rd_offset is not None: - rd_memory_size, _ = self.constant_divmod(rd_offset + rd_length + 31, 32, N_BYTES_MEMORY_SIZE) + rd_memory_size, _ = self.constant_divmod( + rd_offset + rd_length + 31, 32, N_BYTES_MEMORY_SIZE + ) next_memory_size = self.max(next_memory_size, rd_memory_size, N_BYTES_MEMORY_SIZE) memory_gas_cost = self.memory_gas_cost(self.curr.memory_size) diff --git a/src/zkevm_specs/evm/table.py b/src/zkevm_specs/evm/table.py index 889615513..c85c4e521 100644 --- a/src/zkevm_specs/evm/table.py +++ b/src/zkevm_specs/evm/table.py @@ -72,9 +72,14 @@ def table_assignments(self) -> Sequence[Array4]: elif self == FixedTableTag.StateWriteOpcode: return [(self, opcode, 0, 0) for opcode in state_write_opcodes()] elif self == FixedTableTag.StackOverflow: - return [(self, opcode, stack_pointer, 0) for opcode, stack_pointer in stack_underflow_pairs()] + return [ + (self, opcode, stack_pointer, 0) + for opcode, stack_pointer in stack_underflow_pairs() + ] elif self == FixedTableTag.StackUnderflow: - return [(self, opcode, stack_pointer, 0) for opcode, stack_pointer in stack_overflow_pairs()] + return [ + (self, opcode, stack_pointer, 0) for opcode, stack_pointer in stack_overflow_pairs() + ] else: ValueError("Unreacheable") @@ -234,7 +239,9 @@ def __init__(self, table_name: str, inputs: Tuple[int, ...]) -> None: class LookupAmbiguousFailure(Exception): - def __init__(self, table_name: str, inputs: Tuple[int, ...], matched_rows: Sequence[Tuple[int, ...]]) -> None: + def __init__( + self, table_name: str, inputs: Tuple[int, ...], matched_rows: Sequence[Tuple[int, ...]] + ) -> None: self.inputs = inputs self.message = f"Lookup {table_name} is ambiguous on inputs {inputs}, ${len(matched_rows)} matched rows found: {matched_rows}" diff --git a/src/zkevm_specs/evm/typing.py b/src/zkevm_specs/evm/typing.py index 4f7636513..303d163e5 100644 --- a/src/zkevm_specs/evm/typing.py +++ b/src/zkevm_specs/evm/typing.py @@ -103,7 +103,12 @@ def __init__( def call_data_gas_cost(self) -> int: return reduce( lambda acc, byte: ( - acc + (GAS_COST_TX_CALL_DATA_PER_ZERO_BYTE if byte == 0 else GAS_COST_TX_CALL_DATA_PER_NON_ZERO_BYTE) + acc + + ( + GAS_COST_TX_CALL_DATA_PER_ZERO_BYTE + if byte == 0 + else GAS_COST_TX_CALL_DATA_PER_NON_ZERO_BYTE + ) ), self.call_data, 0, @@ -122,7 +127,10 @@ def table_assignments(self, randomness: int) -> Iterator[Array4]: (self.id, TxContextFieldTag.CallDataLength, 0, len(self.call_data)), (self.id, TxContextFieldTag.CallDataGasCost, 0, self.call_data_gas_cost()), ], - map(lambda item: (self.id, TxContextFieldTag.CallData, item[0], item[1]), enumerate(self.call_data)), + map( + lambda item: (self.id, TxContextFieldTag.CallData, item[0], item[1]), + enumerate(self.call_data), + ), ) diff --git a/src/zkevm_specs/opcode/mload_mstore.py b/src/zkevm_specs/opcode/mload_mstore.py index 06ea65bef..fc203a2f5 100644 --- a/src/zkevm_specs/opcode/mload_mstore.py +++ b/src/zkevm_specs/opcode/mload_mstore.py @@ -91,7 +91,9 @@ def memory_expansion( # Calculate the gas cost for the memory expansion # This gas cost is the difference between the next and current memory costs - memory_gas_cost = (next_memory_size - curr_memory_size) * G_MEM + (next_quad_memory_cost - curr_quad_memory_cost) + memory_gas_cost = (next_memory_size - curr_memory_size) * G_MEM + ( + next_quad_memory_cost - curr_quad_memory_cost + ) # Return the new memory size and the memory expansion gas cost return (next_memory_size, memory_gas_cost) @@ -124,7 +126,9 @@ def check_memory_ops( address = address_low(address8s) # Calculate the next memory size and the gas cost for this memory access - (next_memory_size, memory_cost) = memory_expansion(curr_memory_size, address + 1 + is_not_mstore8 * 31) + (next_memory_size, memory_cost) = memory_expansion( + curr_memory_size, address + 1 + is_not_mstore8 * 31 + ) assert next_memory_size == expected_next_memory_size assert memory_cost == expected_memory_cost diff --git a/src/zkevm_specs/opcode/signextend.py b/src/zkevm_specs/opcode/signextend.py index 16d880ea1..6a1fea507 100644 --- a/src/zkevm_specs/opcode/signextend.py +++ b/src/zkevm_specs/opcode/signextend.py @@ -77,4 +77,6 @@ def test_check_byte(): r8s[j] = sign_byte selectors[j - 1] = 1 - check_signextend(value, i8s, r8s, sign_byte if i < 31 else 0, selectors, sign_byte_table) + check_signextend( + value, i8s, r8s, sign_byte if i < 31 else 0, selectors, sign_byte_table + ) diff --git a/src/zkevm_specs/util/arithmetic.py b/src/zkevm_specs/util/arithmetic.py index fadcbf1c9..e91d14635 100644 --- a/src/zkevm_specs/util/arithmetic.py +++ b/src/zkevm_specs/util/arithmetic.py @@ -24,18 +24,28 @@ class RLC: le_bytes: bytes value: FQ - def __init__(self, int_or_bytes: Union[IntOrFQ, bytes], randomness: int, n_bytes: int = 32) -> None: + def __init__( + self, int_or_bytes: Union[IntOrFQ, bytes], randomness: int, n_bytes: int = 32 + ) -> None: if isinstance(int_or_bytes, int): - assert 0 <= int_or_bytes < 256**n_bytes, f"Value {int_or_bytes} too large to fit {n_bytes} bytes" + assert ( + 0 <= int_or_bytes < 256**n_bytes + ), f"Value {int_or_bytes} too large to fit {n_bytes} bytes" self.le_bytes = int_or_bytes.to_bytes(n_bytes, "little") elif isinstance(int_or_bytes, FQ): - assert int_or_bytes.n < 256**n_bytes, f"Value {int_or_bytes} too large to fit {n_bytes} bytes" + assert ( + int_or_bytes.n < 256**n_bytes + ), f"Value {int_or_bytes} too large to fit {n_bytes} bytes" self.le_bytes = int_or_bytes.n.to_bytes(n_bytes, "little") elif isinstance(int_or_bytes, bytes): - assert len(int_or_bytes) <= n_bytes, f"Expected bytes with length less or equal than {n_bytes}" + assert ( + len(int_or_bytes) <= n_bytes + ), f"Expected bytes with length less or equal than {n_bytes}" self.le_bytes = int_or_bytes.ljust(n_bytes, b"\x00") else: - raise TypeError(f"Expected an int or bytes, but got object of type {type(int_or_bytes)}") + raise TypeError( + f"Expected an int or bytes, but got object of type {type(int_or_bytes)}" + ) self.value = fp_linear_combine(self.le_bytes, randomness) diff --git a/tests/evm/test_add.py b/tests/evm/test_add.py index 5c59caa66..c3bcf2a38 100644 --- a/tests/evm/test_add.py +++ b/tests/evm/test_add.py @@ -27,7 +27,11 @@ def test_add(opcode: Opcode, a: int, b: int, c: Optional[int]): randomness = rand_fp() - c = RLC(c, randomness) if c is not None else RLC((a + b if opcode == Opcode.ADD else a - b) % 2**256, randomness) + c = ( + RLC(c, randomness) + if c is not None + else RLC((a + b if opcode == Opcode.ADD else a - b) % 2**256, randomness) + ) a = RLC(a, randomness) b = RLC(b, randomness) diff --git a/tests/evm/test_begin_tx.py b/tests/evm/test_begin_tx.py index 31328421d..6366bf892 100644 --- a/tests/evm/test_begin_tx.py +++ b/tests/evm/test_begin_tx.py @@ -46,32 +46,47 @@ ), # Transfer random ether, successfully ( - Transaction(caller_address=rand_address(), callee_address=CALLEE_ADDRESS, value=rand_range(1e20)), + Transaction( + caller_address=rand_address(), callee_address=CALLEE_ADDRESS, value=rand_range(1e20) + ), CALLEE_WITH_RETURN_BYTECODE, True, ), # Transfer nothing with random gas_price, successfully ( - Transaction(caller_address=rand_address(), callee_address=CALLEE_ADDRESS, gas_price=rand_range(42857142857143)), + Transaction( + caller_address=rand_address(), + callee_address=CALLEE_ADDRESS, + gas_price=rand_range(42857142857143), + ), CALLEE_WITH_RETURN_BYTECODE, True, ), # Transfer random ether, tx reverts ( - Transaction(caller_address=rand_address(), callee_address=CALLEE_ADDRESS, value=rand_range(1e20)), + Transaction( + caller_address=rand_address(), callee_address=CALLEE_ADDRESS, value=rand_range(1e20) + ), CALLEE_WITH_REVERT_BYTECODE, False, ), # Transfer nothing with random gas_price, tx reverts ( - Transaction(caller_address=rand_address(), callee_address=CALLEE_ADDRESS, gas_price=rand_range(42857142857143)), + Transaction( + caller_address=rand_address(), + callee_address=CALLEE_ADDRESS, + gas_price=rand_range(42857142857143), + ), CALLEE_WITH_REVERT_BYTECODE, False, ), # Transfer nothing with some calldata ( Transaction( - caller_address=0xFE, callee_address=CALLEE_ADDRESS, gas=21080, call_data=bytes([1, 2, 3, 4, 0, 0, 0, 0]) + caller_address=0xFE, + callee_address=CALLEE_ADDRESS, + gas=21080, + call_data=bytes([1, 2, 3, 4, 0, 0, 0, 0]), ), CALLEE_WITH_RETURN_BYTECODE, True, @@ -96,126 +111,29 @@ def test_begin_tx(tx: Transaction, callee: Account, result: bool): tx_table=set(tx.table_assignments(randomness)), bytecode_table=set(callee.code.table_assignments(randomness)), rw_table=set( + # fmt: off [ (1, RW.Read, RWTableTag.CallContext, 1, CallContextFieldTag.TxId, 0, tx.id, 0, 0, 0), - ( - 2, - RW.Read, - RWTableTag.CallContext, - 1, - CallContextFieldTag.RwCounterEndOfReversion, - 0, - 0 if result else rw_counter_end_of_reversion, - 0, - 0, - 0, - ), + (2, RW.Read, RWTableTag.CallContext, 1, CallContextFieldTag.RwCounterEndOfReversion, 0, 0 if result else rw_counter_end_of_reversion, 0, 0, 0), (3, RW.Read, RWTableTag.CallContext, 1, CallContextFieldTag.IsPersistent, 0, result, 0, 0, 0), - ( - 4, - RW.Write, - RWTableTag.Account, - tx.caller_address, - AccountFieldTag.Nonce, - 0, - tx.nonce + 1, - tx.nonce, - 0, - 0, - ), + (4, RW.Write, RWTableTag.Account, tx.caller_address, AccountFieldTag.Nonce, 0, tx.nonce + 1, tx.nonce, 0, 0), (5, RW.Write, RWTableTag.TxAccessListAccount, 1, tx.caller_address, 0, 1, 0, 0, 0), (6, RW.Write, RWTableTag.TxAccessListAccount, 1, tx.callee_address, 0, 1, 0, 0, 0), - ( - 7, - RW.Write, - RWTableTag.Account, - tx.caller_address, - AccountFieldTag.Balance, - 0, - RLC(caller_balance, randomness), - RLC(caller_balance_prev, randomness), - 0, - 0, - ), - ( - 8, - RW.Write, - RWTableTag.Account, - tx.callee_address, - AccountFieldTag.Balance, - 0, - RLC(callee_balance, randomness), - RLC(callee_balance_prev, randomness), - 0, - 0, - ), - ( - 9, - RW.Read, - RWTableTag.Account, - tx.callee_address, - AccountFieldTag.CodeHash, - 0, - bytecode_hash, - bytecode_hash, - 0, - 0, - ), + (7, RW.Write, RWTableTag.Account, tx.caller_address, AccountFieldTag.Balance, 0, RLC(caller_balance, randomness), RLC(caller_balance_prev, randomness), 0, 0), + (8, RW.Write, RWTableTag.Account, tx.callee_address, AccountFieldTag.Balance, 0, RLC(callee_balance, randomness), RLC(callee_balance_prev, randomness), 0, 0), + (9, RW.Read, RWTableTag.Account, tx.callee_address, AccountFieldTag.CodeHash, 0, bytecode_hash, bytecode_hash, 0, 0), (10, RW.Read, RWTableTag.CallContext, 1, CallContextFieldTag.Depth, 0, 1, 0, 0, 0), - ( - 11, - RW.Read, - RWTableTag.CallContext, - 1, - CallContextFieldTag.CallerAddress, - 0, - tx.caller_address, - 0, - 0, - 0, - ), - ( - 12, - RW.Read, - RWTableTag.CallContext, - 1, - CallContextFieldTag.CalleeAddress, - 0, - tx.callee_address, - 0, - 0, - 0, - ), + (11, RW.Read, RWTableTag.CallContext, 1, CallContextFieldTag.CallerAddress, 0, tx.caller_address, 0, 0, 0), + (12, RW.Read, RWTableTag.CallContext, 1, CallContextFieldTag.CalleeAddress, 0, tx.callee_address, 0, 0, 0), (13, RW.Read, RWTableTag.CallContext, 1, CallContextFieldTag.CallDataOffset, 0, 0, 0, 0, 0), - ( - 14, - RW.Read, - RWTableTag.CallContext, - 1, - CallContextFieldTag.CallDataLength, - 0, - len(tx.call_data), - 0, - 0, - 0, - ), - ( - 15, - RW.Read, - RWTableTag.CallContext, - 1, - CallContextFieldTag.Value, - 0, - RLC(tx.value, randomness), - 0, - 0, - 0, - ), + (14, RW.Read, RWTableTag.CallContext, 1, CallContextFieldTag.CallDataLength, 0, len(tx.call_data), 0, 0, 0), + (15, RW.Read, RWTableTag.CallContext, 1, CallContextFieldTag.Value, 0, RLC(tx.value, randomness), 0, 0, 0), (16, RW.Read, RWTableTag.CallContext, 1, CallContextFieldTag.IsStatic, 0, 0, 0, 0, 0), (17, RW.Read, RWTableTag.CallContext, 1, CallContextFieldTag.LastCalleeId, 0, 0, 0, 0, 0), (18, RW.Read, RWTableTag.CallContext, 1, CallContextFieldTag.LastCalleeReturnDataOffset, 0, 0, 0, 0, 0), (19, RW.Read, RWTableTag.CallContext, 1, CallContextFieldTag.LastCalleeReturnDataLength, 0, 0, 0, 0, 0), ] + # fmt: on + ( [] if result @@ -258,7 +176,9 @@ def test_begin_tx(tx: Transaction, callee: Account, result: bool): rw_counter=1, ), StepState( - execution_state=ExecutionState.EndTx if callee.code_hash() == EMPTY_CODE_HASH else ExecutionState.PUSH, + execution_state=ExecutionState.EndTx + if callee.code_hash() == EMPTY_CODE_HASH + else ExecutionState.PUSH, rw_counter=20, call_id=1, is_root=True, diff --git a/tests/evm/test_calldatasize.py b/tests/evm/test_calldatasize.py index 0f652fee3..156f7bce0 100644 --- a/tests/evm/test_calldatasize.py +++ b/tests/evm/test_calldatasize.py @@ -35,8 +35,10 @@ def test_calldatasize(calldatasize: U64): bytecode_table=set(bytecode.table_assignments(randomness)), rw_table=set( [ + # fmt: off (9, RW.Read, RWTableTag.CallContext, 1, CallContextFieldTag.CallDataLength, 0, calldatasize, 0, 0, 0), (10, RW.Write, RWTableTag.Stack, 1, 1023, 0, RLC(calldatasize, randomness, N_BYTES_U64), 0, 0, 0), + # fmt: on ] ), ) diff --git a/tests/evm/test_caller.py b/tests/evm/test_caller.py index b04988eac..efe13bd26 100644 --- a/tests/evm/test_caller.py +++ b/tests/evm/test_caller.py @@ -36,8 +36,10 @@ def test_caller(caller: U160): bytecode_table=set(bytecode.table_assignments(randomness)), rw_table=set( [ + # fmt: off (9, RW.Read, RWTableTag.CallContext, 1, CallContextFieldTag.CallerAddress, 0, caller, 0, 0, 0), (10, RW.Write, RWTableTag.Stack, 1, 1023, 0, RLC(caller, randomness, N_BYTES_ACCOUNT_ADDRESS), 0, 0, 0), + # fmt: on ] ), ) diff --git a/tests/evm/test_callvalue.py b/tests/evm/test_callvalue.py index 48cf38ba1..f5a1f5ed5 100644 --- a/tests/evm/test_callvalue.py +++ b/tests/evm/test_callvalue.py @@ -38,8 +38,10 @@ def test_callvalue(callvalue: U256): bytecode_table=set(bytecode.table_assignments(randomness)), rw_table=set( [ + # fmt: off (9, RW.Read, RWTableTag.CallContext, 1, CallContextFieldTag.Value, 0, callvalue_rlc, 0, 0, 0), (10, RW.Write, RWTableTag.Stack, 1, 1023, 0, callvalue_rlc, 0, 0, 0), + # fmt: on ] ), ) diff --git a/tests/evm/test_end_block.py b/tests/evm/test_end_block.py index 005b1be8f..68f02c64c 100644 --- a/tests/evm/test_end_block.py +++ b/tests/evm/test_end_block.py @@ -31,9 +31,8 @@ def test_end_block(is_last_step: bool): chain( # dummy read/write for counting [(i, *7 * [0]) for i in range(22)], - [(22, RW.Read, RWTableTag.CallContext, 1, CallContextFieldTag.TxId, 0, tx.id, 0, 0, 0)] - if is_last_step - else [], + [(22, RW.Read, RWTableTag.CallContext, 1, CallContextFieldTag.TxId, 0, tx.id, 0, 0, 0)] # fmt: skip + if is_last_step else [], ) ), ) diff --git a/tests/evm/test_end_tx.py b/tests/evm/test_end_tx.py index 284ce88f3..1338df495 100644 --- a/tests/evm/test_end_tx.py +++ b/tests/evm/test_end_tx.py @@ -19,21 +19,27 @@ TESTING_DATA = ( # Tx with non-capped refund ( - Transaction(caller_address=0xFE, callee_address=CALLEE_ADDRESS, gas=27000, gas_price=int(2e9)), + Transaction( + caller_address=0xFE, callee_address=CALLEE_ADDRESS, gas=27000, gas_price=int(2e9) + ), 994, 4800, False, ), # Tx with capped refund ( - Transaction(caller_address=0xFE, callee_address=CALLEE_ADDRESS, gas=65000, gas_price=int(2e9)), + Transaction( + caller_address=0xFE, callee_address=CALLEE_ADDRESS, gas=65000, gas_price=int(2e9) + ), 3952, 38400, False, ), # Last tx ( - Transaction(caller_address=0xFE, callee_address=CALLEE_ADDRESS, gas=21000, gas_price=int(2e9)), + Transaction( + caller_address=0xFE, callee_address=CALLEE_ADDRESS, gas=21000, gas_price=int(2e9) + ), 0, 0, True, @@ -58,37 +64,17 @@ def test_end_tx(tx: Transaction, gas_left: int, refund: int, is_last_tx: bool): bytecode_table=set(), rw_table=set( [ + # fmt: off (17, RW.Read, RWTableTag.CallContext, 1, CallContextFieldTag.TxId, 0, tx.id, 0, 0, 0), (18, RW.Read, RWTableTag.TxRefund, tx.id, 0, 0, refund, refund, 0, 0), - ( - 19, - RW.Write, - RWTableTag.Account, - tx.caller_address, - AccountFieldTag.Balance, - 0, - RLC(caller_balance, randomness), - RLC(caller_balance_prev, randomness), - 0, - 0, - ), - ( - 20, - RW.Write, - RWTableTag.Account, - block.coinbase, - AccountFieldTag.Balance, - 0, - RLC(coinbase_balance, randomness), - RLC(coinbase_balance_prev, randomness), - 0, - 0, - ), + (19, RW.Write, RWTableTag.Account, tx.caller_address, AccountFieldTag.Balance, 0, RLC(caller_balance, randomness), RLC(caller_balance_prev, randomness), 0, 0), + (20, RW.Write, RWTableTag.Account, block.coinbase, AccountFieldTag.Balance, 0, RLC(coinbase_balance, randomness), RLC(coinbase_balance_prev, randomness), 0, 0), + # fmt: on ] + ( [] if is_last_tx - else [(21, RW.Read, RWTableTag.CallContext, 22, CallContextFieldTag.TxId, 0, tx.id + 1, 0, 0, 0)] + else [(21, RW.Read, RWTableTag.CallContext, 22, CallContextFieldTag.TxId, 0, tx.id + 1, 0, 0, 0)] # fmt: skip ) ), ) diff --git a/tests/evm/test_selfbalance.py b/tests/evm/test_selfbalance.py index 2894dd4b8..46c7c76c0 100644 --- a/tests/evm/test_selfbalance.py +++ b/tests/evm/test_selfbalance.py @@ -32,21 +32,11 @@ def test_selfbalance(callee_address: U160, balance: U256): bytecode_table=set(bytecode.table_assignments(randomness)), rw_table=set( [ + # fmt: off (9, RW.Read, RWTableTag.CallContext, 1, CallContextFieldTag.CalleeAddress, 0, callee_address, 0, 0, 0), - ( - 10, - RW.Read, - RWTableTag.Account, - callee_address, - AccountFieldTag.Balance, - 0, - rlc_balance, - rlc_balance, - 0, - 0, - 0, - ), + (10, RW.Read, RWTableTag.Account, callee_address, AccountFieldTag.Balance, 0, rlc_balance, rlc_balance, 0, 0, 0), (11, RW.Write, RWTableTag.Stack, 1, 1023, 0, rlc_balance, 0, 0, 0), + # fmt: on ] ), ) diff --git a/tests/test_memory.py b/tests/test_memory.py index ef6bbc93a..e965ed5d1 100644 --- a/tests/test_memory.py +++ b/tests/test_memory.py @@ -27,16 +27,32 @@ def test_check_memory_ops(): # Test against some values acquired from traces memory = Memory() # Store a value at address 0x12FFFF - check_memory_ops(OP_MSTORE, memory, u256_to_u8s(0x12FFFF), range(1, 33), 0, 1_245_216 // 32, 3_074_203) + check_memory_ops( + OP_MSTORE, memory, u256_to_u8s(0x12FFFF), range(1, 33), 0, 1_245_216 // 32, 3_074_203 + ) # Load a value at address 0x230212 - check_memory_ops(OP_MLOAD, memory, u256_to_u8s(0x230212), [0] * 32, 1_245_216 // 32, 2_294_336 // 32, 7_181_131) + check_memory_ops( + OP_MLOAD, + memory, + u256_to_u8s(0x230212), + [0] * 32, + 1_245_216 // 32, + 2_294_336 // 32, + 7_181_131, + ) # Store a value at address 0x131541 - check_memory_ops(OP_MSTORE, memory, u256_to_u8s(0x131541), range(1, 33), 2_294_336 // 32, 2_294_336 // 32, 0) + check_memory_ops( + OP_MSTORE, memory, u256_to_u8s(0x131541), range(1, 33), 2_294_336 // 32, 2_294_336 // 32, 0 + ) # Verify Geth max allowed address memory = Memory() - check_memory_ops(OP_MLOAD, memory, u256_to_u8s(0x1FFFFFFFC0), [0] * 32, 0, 0xFFFFFFFF, 0x800002FEFFFFFD) + check_memory_ops( + OP_MLOAD, memory, u256_to_u8s(0x1FFFFFFFC0), [0] * 32, 0, 0xFFFFFFFF, 0x800002FEFFFFFD + ) # Verify zkEVM max allowed address memory = Memory() - check_memory_ops(OP_MLOAD, memory, u256_to_u8s(0xFFFFFFFFFF), [0] * 32, 0, 0x800000001, 0x2000001808000003) + check_memory_ops( + OP_MLOAD, memory, u256_to_u8s(0xFFFFFFFFFF), [0] * 32, 0, 0x800000001, 0x2000001808000003 + )