Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exhaustive check fixes #52

Merged
Merged
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
28 changes: 21 additions & 7 deletions src/ethereum_test_forks/forks/forks.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,9 @@ def call_opcodes(
"""
At Homestead, DELEGATECALL opcode was introduced.
"""
return [(Opcodes.DELEGATECALL, EVMCodeType.LEGACY),] + super(
return [
(Opcodes.DELEGATECALL, EVMCodeType.LEGACY),
] + super(
Homestead, cls
).call_opcodes(block_number, timestamp)

Expand Down Expand Up @@ -449,7 +451,9 @@ def call_opcodes(
"""
At Byzantium, STATICCALL opcode was introduced.
"""
return [(Opcodes.STATICCALL, EVMCodeType.LEGACY),] + super(
return [
(Opcodes.STATICCALL, EVMCodeType.LEGACY),
] + super(
Byzantium, cls
).call_opcodes(block_number, timestamp)

Expand Down Expand Up @@ -483,7 +487,9 @@ def create_opcodes(
"""
At Constantinople, `CREATE2` opcode is added.
"""
return [(Opcodes.CREATE2, EVMCodeType.LEGACY),] + super(
return [
(Opcodes.CREATE2, EVMCodeType.LEGACY),
] + super(
Constantinople, cls
).create_opcodes(block_number, timestamp)

Expand Down Expand Up @@ -974,7 +980,7 @@ def pre_allocation_blockchain(cls) -> Mapping:
type tests.
"""
new_allocation = {
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE: {
Address(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE): {
"nonce": 1,
"code": (
"0x60203611603157600143035f35116029575f35612000014311602957612000"
Expand Down Expand Up @@ -1020,7 +1026,10 @@ def evm_code_types(cls, block_number: int = 0, timestamp: int = 0) -> List[EVMCo
"""
EOF V1 is supported starting from this fork.
"""
return super(CancunEIP7692, cls,).evm_code_types( # noqa: SC200
return super(
CancunEIP7692,
cls,
).evm_code_types( # noqa: SC200
block_number,
timestamp,
) + [EVMCodeType.EOF_V1]
Expand Down Expand Up @@ -1049,7 +1058,9 @@ def create_opcodes(
"""
EOF V1 introduces `EOFCREATE`.
"""
return [(Opcodes.EOFCREATE, EVMCodeType.EOF_V1),] + super(
return [
(Opcodes.EOFCREATE, EVMCodeType.EOF_V1),
] + super(
CancunEIP7692, cls # noqa: SC200
).create_opcodes(block_number, timestamp)

Expand Down Expand Up @@ -1084,7 +1095,10 @@ def evm_code_types(cls, block_number: int = 0, timestamp: int = 0) -> List[EVMCo
"""
EOF V1 is supported starting from this fork.
"""
return super(PragueEIP7692, cls,).evm_code_types( # noqa: SC200
return super(
PragueEIP7692,
cls,
).evm_code_types( # noqa: SC200
block_number,
timestamp,
) + [EVMCodeType.EOF_V1]
Expand Down
49 changes: 26 additions & 23 deletions tests/verkle/eip4762_verkle_gas_witness/test_balance.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,23 @@
Block,
BlockchainTestFiller,
Environment,
Hash,
TestAddress,
TestAddress2,
Transaction,
WitnessCheck,
)
from ethereum_test_tools.vm.opcode import Opcodes as Op
from ethereum_test_forks import Fork
from ethereum_test_types.verkle.helpers import chunkify_code

# TODO(verkle): Update reference spec version
REFERENCE_SPEC_GIT_PATH = "EIPS/eip-4762.md"
REFERENCE_SPEC_VERSION = "2f8299df31bb8173618901a03a8366a3183479b0"

precompile_address = Address("0x04")
system_contract_address = Address("0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02")
system_contract_address = Address("0xfffffffffffffffffffffffffffffffffffffffe")
example_address = Address("0xd94f5374fce5edbc8e2a8697c15331677e6ebf0c")


# TODO(verkle): update to Osaka when t8n supports the fork.
@pytest.mark.valid_from("Verkle")
@pytest.mark.parametrize(
"target",
Expand All @@ -43,28 +41,27 @@
],
)
@pytest.mark.parametrize("warm", [True, False])
def test_balance(blockchain_test: BlockchainTestFiller, fork: str, target, warm):
def test_balance(blockchain_test: BlockchainTestFiller, fork: Fork, target, warm):
"""
Test BALANCE witness with/without WARM access.
"""
_balance(blockchain_test, fork, target, [target], warm=warm)
_balance(blockchain_test, fork, target, True, warm=warm)


# TODO(verkle): update to Osaka when t8n supports the fork.
@pytest.mark.valid_from("Verkle")
@pytest.mark.parametrize("target", [example_address, precompile_address])
def test_balance_insufficient_gas(blockchain_test: BlockchainTestFiller, fork: str, target):
def test_balance_insufficient_gas(blockchain_test: BlockchainTestFiller, fork: Fork, target):
"""
Test BALANCE with insufficient gas.
"""
_balance(blockchain_test, fork, target, [], 21_042)
_balance(blockchain_test, fork, target, False, 21_042)


def _balance(
blockchain_test: BlockchainTestFiller,
fork: str,
fork: Fork,
target: Address,
exp_addr_basic_data: list[Address],
exp_target_basic_data: bool,
gas_limit=1_000_000,
warm=False,
):
Expand All @@ -78,10 +75,12 @@ def _balance(
pre = {
TestAddress: Account(balance=1000000000000000000000),
TestAddress2: Account(code=Op.BALANCE(target) * (2 if warm else 1) + Op.PUSH0 + Op.SSTORE),
target: Account(balance=0xF1),
precompile_address: Account(balance=0xF2),
precompile_address: Account(balance=0xF0),
}

if target != precompile_address and target != system_contract_address:
pre[target] = Account(balance=0xF2)

tx = Transaction(
ty=0x0,
chain_id=0x01,
Expand All @@ -92,19 +91,23 @@ def _balance(
)

witness_check = WitnessCheck(fork=Verkle)
witness_check.add_account_full(address=TestAddress, account=pre[TestAddress])
witness_check.add_account_full(address=TestAddress2, account=pre[TestAddress2])
witness_check.add_storage_slot(address=TestAddress2, storage_slot=0, value=None)
for address in [TestAddress, TestAddress2, env.fee_recipient]:
witness_check.add_account_full(address=address, account=pre.get(address))

code_chunks = chunkify_code(pre[TestAddress2].code)
for i, chunk in enumerate(code_chunks, start=0):
witness_check.add_code_chunk(address=TestAddress2, chunk_number=i, value=chunk)

witness_check.add_account_full(address=env.fee_recipient, account=None)
for address in exp_addr_basic_data:
witness_check.add_account_basic_data(
address=address,
account=pre[address],
)
witness_check.add_storage_slot(address=TestAddress2, storage_slot=0, value=None)

target_account = (
pre[target]
if target != system_contract_address
else Account(**fork.pre_allocation_blockchain()[system_contract_address])
)

if exp_target_basic_data:
witness_check.add_account_basic_data(address=target, account=target_account)

blocks = [
Block(
Expand All @@ -114,7 +117,7 @@ def _balance(
]

post = {
TestAddress2: Account(code=pre[TestAddress2].code, storage={0: pre[target].balance}),
TestAddress2: Account(code=pre[TestAddress2].code, storage={0: target_account.balance}),
}

blockchain_test(
Expand Down
58 changes: 28 additions & 30 deletions tests/verkle/eip4762_verkle_gas_witness/test_calls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import pytest

from ethereum_test_forks import Verkle
from ethereum_test_tools import (
Account,
Address,
Expand All @@ -21,17 +22,16 @@
WitnessCheck,
)
from ethereum_test_tools.vm.opcode import Opcodes as Op
from ethereum_test_types.verkle.helpers import chunkify_code

# TODO(verkle): Update reference spec version
REFERENCE_SPEC_GIT_PATH = "EIPS/eip-4762.md"
REFERENCE_SPEC_VERSION = "2f8299df31bb8173618901a03a8366a3183479b0"

caller_address = Address("0xd94f5374fce5edbc8e2a8697c15331677e6ebf0c")
system_contract_address = Address("0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02")
system_contract_address = Address("0xfffffffffffffffffffffffffffffffffffffffe")
precompile_address = Address("0x04")


# TODO(verkle): update to Osaka when t8n supports the fork.
@pytest.mark.valid_from("Verkle")
@pytest.mark.parametrize(
"call_instruction, value",
Expand All @@ -48,9 +48,9 @@
@pytest.mark.parametrize(
"target",
[
TestAddress2,
# TestAddress2,
precompile_address,
system_contract_address,
# system_contract_address,
],
)
def test_calls(
Expand All @@ -66,7 +66,6 @@ def test_calls(
_generic_call(blockchain_test, call_instruction, target, value)


# TODO(verkle): update to Osaka when t8n supports the fork.
@pytest.mark.valid_from("Verkle")
@pytest.mark.parametrize(
"call_instruction",
Expand All @@ -84,7 +83,6 @@ def test_calls_warm(blockchain_test: BlockchainTestFiller, fork: str, call_instr
_generic_call(blockchain_test, call_instruction, TestAddress2, 0, warm=True)


# TODO(verkle): update to Osaka when t8n supports the fork.
@pytest.mark.valid_from("Verkle")
@pytest.mark.skip("Pending TBD gas limits")
@pytest.mark.parametrize(
Expand Down Expand Up @@ -174,17 +172,20 @@ def _generic_call(
value=tx_value,
)

witness_check = WitnessCheck()
witness_check = WitnessCheck(fork=Verkle)
for address in [TestAddress, caller_address, env.fee_recipient]:
witness_check.add_account_full(
address=address,
account=(None if address == env.fee_recipient else pre[address]),
)
if target != precompile_address and enough_gas_read_witness:
witness_check.add_account_basic_data(
address=target,
account=pre[target],
)
witness_check.add_account_full(address=address, account=pre.get(address))
if enough_gas_read_witness:
if value > 0 or (target != precompile_address and target != precompile_address):
witness_check.add_account_basic_data(address=target, account=pre[target])

code_chunks = chunkify_code(pre[caller_address].code)
for i, chunk in enumerate(code_chunks, start=0):
witness_check.add_code_chunk(address=caller_address, chunk_number=i, value=chunk)
code_chunks = chunkify_code(pre[target].code)
if target != precompile_address and target != system_contract_address:
for i, chunk in enumerate(code_chunks, start=0):
witness_check.add_code_chunk(address=target, chunk_number=i, value=chunk)

blocks = [
Block(
Expand Down Expand Up @@ -213,7 +214,6 @@ def _generic_call(
)


# TODO(verkle): update to Osaka when t8n supports the fork.
@pytest.mark.valid_from("Verkle")
@pytest.mark.parametrize(
"call_instruction, gas_limit, enough_gas_account_creation",
Expand All @@ -231,7 +231,7 @@ def test_call_non_existent_account(
enough_gas_account_creation: bool,
):
"""
Test *CALL witness assertion when there's insufficient gas for different scenarios.
Test *CALL witness assertion when target account does not exist.
"""
env = Environment(
fee_recipient="0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
Expand Down Expand Up @@ -260,14 +260,16 @@ def test_call_non_existent_account(
gas_price=10,
)

witness_check = WitnessCheck()
witness_check = WitnessCheck(fork=Verkle)
for address in [TestAddress, caller_address, env.fee_recipient]:
witness_check.add_account_full(
address=address,
account=(None if address == env.fee_recipient else pre[address]),
)
witness_check.add_account_full(address=address, account=pre.get(address))

code_chunks = chunkify_code(pre[caller_address].code)
for i, chunk in enumerate(code_chunks, start=0):
witness_check.add_code_chunk(address=caller_address, chunk_number=i, value=chunk)

if enough_gas_account_creation:
witness_check.add_account_basic_data(address=TestAddress2, account=None)
witness_check.add_account_full(address=TestAddress2, account=None)

blocks = [
Block(
Expand All @@ -278,11 +280,7 @@ def test_call_non_existent_account(

post: Alloc = Alloc()
if enough_gas_account_creation:
post = Alloc(
{
TestAddress2: Account(balance=call_value),
}
)
post = Alloc({TestAddress2: Account(balance=call_value)})

blockchain_test(
genesis_environment=env,
Expand Down
Loading
Loading