Skip to content

Commit

Permalink
test set code tx ideas
Browse files Browse the repository at this point in the history
  • Loading branch information
winsvega committed Dec 2, 2024
1 parent 5cf1f24 commit 7524711
Showing 1 changed file with 398 additions and 0 deletions.
398 changes: 398 additions & 0 deletions tests/prague/eip7702_set_code_tx/test_set_code_txs_2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,398 @@
"""
A state test for [EIP-7702 SetCodeTX](https://eips.ethereum.org/EIPS/eip-7702).
"""

import pytest

from ethereum_test_tools import (
Account,
Alloc,
AuthorizationTuple,
Block,
BlockchainTestFiller,
Environment,
StateTestFiller,
Storage,
Transaction,
compute_create_address,
)
from ethereum_test_tools.vm.opcode import Opcodes as Op

from .spec import Spec, ref_spec_7702

REFERENCE_SPEC_GIT_PATH = ref_spec_7702.git_path
REFERENCE_SPEC_VERSION = ref_spec_7702.version


@pytest.mark.valid_from("Prague")
def test_7702_pointer_contract_pointer_loop(state_test: StateTestFiller, pre: Alloc):
"""
tx -> call -> pointer A -> contract A -> pointer B -> contract loop C
Call pointer that goes more level of depth to call a contract loop
Loop is created only if pointers are set with auth tuples
"""
env = Environment()

storage: Storage = Storage()

sender = pre.fund_eoa()
pointer_a = pre.fund_eoa()
pointer_b = pre.fund_eoa()
contract_a = pre.deploy_contract(
code=Op.SSTORE(storage.store_next(1, "contract_a_worked"), 0x1)
+ Op.CALL(1_000_000, pointer_b, 0, 0, 0, 0, 0)
+ Op.STOP,
)

storage_loop = storage.store_next(0, "contract_loop_worked")
contract_loop = pre.deploy_contract(
code=Op.SSTORE(storage_loop, Op.ADD(1, Op.SLOAD(0)))
+ Op.CALL(1_000_000, pointer_a, 0, 0, 0, 0, 0)
+ Op.STOP,
)
tx = Transaction(
to=pointer_a,
gas_limit=100_000_000,
data=b"",
value=0,
sender=sender,
authorization_list=[
AuthorizationTuple(
address=contract_a,
nonce=0,
signer=pointer_a,
),
AuthorizationTuple(
address=contract_loop,
nonce=0,
signer=pointer_b,
),
],
)

# TODO: Modify post-state allocations here.
post = {pointer_a: Account(storage=storage)}

state_test(env=env, pre=pre, post=post, tx=tx)


@pytest.mark.valid_from("Prague")
def test_7702_pointer_to_pointer(state_test: StateTestFiller, pre: Alloc):
"""
tx -> call -> pointer A -> pointer B
Direct call from pointer to pointer is OOG
"""
env = Environment()

storage: Storage = Storage()

sender = pre.fund_eoa()
pointer_a = pre.fund_eoa()
pointer_b = pre.fund_eoa()

contract_a = pre.deploy_contract(
code=Op.SSTORE(storage.store_next(0, "contract_a_worked"), 0x1)
+ Op.CALL(1_000_000, pointer_b, 0, 0, 0, 0, 0)
+ Op.STOP,
)

tx = Transaction(
to=pointer_a,
gas_limit=100_000_000,
data=b"",
value=0,
sender=sender,
authorization_list=[
AuthorizationTuple(
address=pointer_b,
nonce=0,
signer=pointer_a,
),
AuthorizationTuple(
address=contract_a,
nonce=0,
signer=pointer_b,
),
],
)
post = {pointer_a: Account(storage=storage)}
state_test(env=env, pre=pre, post=post, tx=tx)


@pytest.mark.valid_from("Prague")
@pytest.mark.parametrize("create_opcode", [Op.CREATE, Op.CREATE2])
def test_7702_create_pointer_style_contract(
state_test: StateTestFiller, pre: Alloc, create_opcode: Op
):
"""
tx -> create -> pointer bytecode
Attempt to deploy contract with magic bytes result in no contract being created
"""
env = Environment()

storage: Storage = Storage()

sender = pre.fund_eoa()

# An attempt to deploy code starting with ef01 result in no
# contract being created as it is prohibited
create_init = Op.MSTORE(0, "0xef01" + sender.hex()[2:]) + Op.RETURN(10, 22)
contract_a = pre.deploy_contract(
balance=100,
code=Op.MSTORE(0, Op.CALLDATALOAD(0))
+ Op.SSTORE(
storage.store_next(0, "contract_a_create_result"),
create_opcode(value=1, offset=0, size=Op.CALLDATASIZE(), salt=0),
)
+ Op.STOP,
)

tx = Transaction(
to=contract_a,
gas_limit=100_000_000,
data=create_init,
value=0,
sender=sender,
)

create_address = compute_create_address(
address=contract_a, nonce=1, initcode=create_init, salt=0, opcode=create_opcode
)
post = {contract_a: Account(balance=100, storage=storage), create_address: Account.NONEXISTENT}
state_test(env=env, pre=pre, post=post, tx=tx)


def test_7702_create_pointer_style_contract_tx_deploy(state_test: StateTestFiller, pre: Alloc):
"""
tx -> deploy pointer bytecode
Attempt to deploy contract with magic bytes result in no contract being created
"""
env = Environment()
sender = pre.fund_eoa()

create_init = Op.MSTORE(0, "0xef01" + sender.hex()[2:]) + Op.RETURN(10, 22)

tx = Transaction(
to=b"",
gas_limit=100_000_000,
data=create_init,
value=0,
sender=sender,
)

create_address = compute_create_address(
address=sender, nonce=0, initcode=create_init, salt=0, opcode=Op.CREATE
)
post = {sender: Account(nonce=1), create_address: Account.NONEXISTENT}
state_test(env=env, pre=pre, post=post, tx=tx)


@pytest.mark.valid_from("Prague")
def test_7702_pointer_normal(blockchain_test: BlockchainTestFiller, pre: Alloc):
"""
tx -> call -> pointer A -> contract
Other normal tx can interact with previously assigned pointers
"""
env = Environment()

storage: Storage = Storage()

sender = pre.fund_eoa()
pointer_a = pre.fund_eoa()

slot_worked = storage.store_next(3, "contract_a_worked")
contract_a = pre.deploy_contract(
code=Op.SSTORE(slot_worked, Op.ADD(1, Op.SLOAD(slot_worked))) + Op.STOP,
)

tx = Transaction(
to=pointer_a,
gas_limit=100_000_000,
data=b"",
value=0,
sender=sender,
authorization_list=[
AuthorizationTuple(
address=contract_a,
nonce=0,
signer=pointer_a,
)
],
)

# Other normal tx can interact with previously assigned pointers
tx_2 = Transaction(
to=pointer_a,
gas_limit=100_000_000,
data=b"",
value=0,
sender=sender,
)

# Event from another block
tx_3 = Transaction(
to=pointer_a,
gas_limit=100_000_000,
data=b"",
value=0,
sender=sender,
)

post = {pointer_a: Account(storage=storage)}
blockchain_test(
genesis_environment=env,
pre=pre,
post=post,
blocks=[Block(txs=[tx, tx_2]), Block(txs=[tx_3])],
)


@pytest.mark.valid_from("Prague")
def test_7702_pointer_measurements(blockchain_test: BlockchainTestFiller, pre: Alloc):
"""
Check extcode* operations on pointer before and after pointer is set
Check context opcode results when called under pointer call
Opcodes have context of an original pointer account (balance)
"""
env = Environment()

sender = pre.fund_eoa()
pointer = pre.fund_eoa(amount=100)

storage_normal: Storage = Storage()
storage_pointer: Storage = Storage()
storage_pointer_code: Storage = Storage() # this storage will be applied to pointer address
pointer_code = pre.deploy_contract(
balance=200,
code=Op.SSTORE(
storage_pointer_code.store_next(pointer.hex(), "address"),
Op.ADDRESS(),
)
+ Op.SSTORE(
storage_pointer_code.store_next(3, "callvalue"),
Op.CALLVALUE(),
)
+ Op.CALL(1000, 0, 3, 0, 0, 0, 0)
+ Op.SSTORE(
storage_pointer_code.store_next(100, "selfbalance"),
Op.SELFBALANCE(),
)
+ Op.SSTORE(
storage_pointer_code.store_next(sender.hex(), "origin"),
Op.ORIGIN(),
)
+ Op.SSTORE(
storage_pointer_code.store_next(
"0x1122334400000000000000000000000000000000000000000000000000000000",
"calldataload",
),
Op.CALLDATALOAD(0),
)
+ Op.SSTORE(
storage_pointer_code.store_next(
4,
"calldatasize",
),
Op.CALLDATASIZE(),
)
+ Op.CALLDATACOPY(0, 0, 32)
+ Op.SSTORE(
storage_pointer_code.store_next(
"0x1122334400000000000000000000000000000000000000000000000000000000",
"calldatacopy",
),
Op.MLOAD(0),
)
+ Op.MSTORE(0, 0)
+ Op.SSTORE(
storage_pointer_code.store_next(77, "codesize"),
Op.CODESIZE(),
)
+ Op.CODECOPY(0, 0, 32)
+ Op.SSTORE(
storage_pointer_code.store_next(
"0x30600055346001556000600060006000600360006103e8f14760025532600355", "codecopy"
),
Op.MLOAD(0),
),
)

contract_measurements = pre.deploy_contract(
code=Op.EXTCODECOPY(pointer, 0, 0, 32)
+ Op.SSTORE(
storage_normal.store_next(
0xC5D2460186F7233C927E7DB2DCC703C0E500B653CA82273B7BFAD8045D85A470, "extcodehash"
),
Op.EXTCODEHASH(pointer),
)
+ Op.SSTORE(storage_normal.store_next(0, "extcodesize"), Op.EXTCODESIZE(pointer))
+ Op.SSTORE(storage_normal.store_next(0, "extcodecopy"), Op.MLOAD(0))
+ Op.SSTORE(storage_normal.store_next(100, "balance"), Op.BALANCE(pointer))
+ Op.STOP,
)

contract_measurements_pointer = pre.deploy_contract(
code=Op.EXTCODECOPY(pointer, 0, 0, 32)
+ Op.SSTORE(
storage_pointer.store_next(
0xEB7A7B863A31F9C2252A1A4253666B272B8620FB0F00EA6F26CAC7DBB5997E4, "extcodehash"
),
Op.EXTCODEHASH(pointer),
)
+ Op.SSTORE(storage_pointer.store_next(77, "extcodesize"), Op.EXTCODESIZE(pointer))
+ Op.SSTORE(
storage_pointer.store_next(
0x30600055346001556000600060006000600360006103E8F14760025532600355, "extcodecopy"
),
Op.MLOAD(0),
)
+ Op.SSTORE(storage_pointer.store_next(100, "balance"), Op.BALANCE(pointer))
+ Op.STOP,
)

tx = Transaction(
to=contract_measurements,
gas_limit=100_000_000,
data=b"",
value=0,
sender=sender,
)

tx_pointer = Transaction(
to=contract_measurements_pointer,
gas_limit=100_000_000,
data=b"",
value=0,
sender=sender,
authorization_list=[
AuthorizationTuple(
address=pointer_code,
nonce=0,
signer=pointer,
)
],
)

tx_pointer_call = Transaction(
to=pointer,
gas_limit=100_000_000,
data=bytes.fromhex("11223344"),
value=3,
sender=sender,
)

post = {
contract_measurements: Account(storage=storage_normal),
contract_measurements_pointer: Account(storage=storage_pointer),
pointer: Account(storage=storage_pointer_code),
}
blockchain_test(
genesis_environment=env,
pre=pre,
post=post,
blocks=[Block(txs=[tx]), Block(txs=[tx_pointer, tx_pointer_call])],
)

0 comments on commit 7524711

Please sign in to comment.