Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@
from pydantic import Field

from execution_testing.base_types import Address, Bytes
from execution_testing.forks import Fork
from execution_testing.test_types import EOA, Transaction, ceiling_division
from execution_testing.forks import Fork, Frontier
from execution_testing.test_types import EOA, Transaction
from execution_testing.vm import Bytecode, ForkOpcodeInterface, Op

GAS_PER_DEPLOYED_CODE_BYTE = 0xC8


class Initcode(Bytecode):
"""
Expand Down Expand Up @@ -47,13 +45,16 @@ def __new__(
deploy_code: SupportsBytes | Bytes | None = None,
initcode_length: int | None = None,
initcode_prefix: Bytecode | None = None,
initcode_prefix_execution_gas: int = 0,
padding_byte: int = 0x00,
name: str = "",
fork: Fork = Frontier,
) -> Self:
"""
Generate legacy initcode that inits a contract with the specified code.
The initcode can be padded to a specified length for testing purposes.

Gas costs are calculated using the fork's gas costs and memory
expansion formula. Defaults to Frontier if no fork is provided.
"""
if deploy_code is None:
deploy_code = Bytecode()
Expand All @@ -62,44 +63,33 @@ def __new__(

initcode = initcode_prefix
code_length = len(bytes(deploy_code))
execution_gas = initcode_prefix_execution_gas

# PUSH2: length=<bytecode length>
initcode += Op.PUSH2(code_length)
execution_gas = 3

# PUSH1: offset=0
initcode += Op.PUSH1(0)
execution_gas += 3

# DUP2
initcode += Op.DUP2
execution_gas += 3

# PUSH1: initcode_length=11 + len(initcode_prefix_bytes) (constant)
no_prefix_length = 0x0B
assert no_prefix_length + len(initcode_prefix) <= 0xFF, (
"initcode prefix too long"
)
initcode += Op.PUSH1(no_prefix_length + len(initcode_prefix))
execution_gas += 3

# DUP3
initcode += Op.DUP3
execution_gas += 3

# CODECOPY: destinationOffset=0, offset=0, length
initcode += Op.CODECOPY
execution_gas += (
3
+ (3 * ceiling_division(code_length, 32))
+ (3 * code_length)
+ ((code_length * code_length) // 512)
initcode += Op.CODECOPY(
data_size=code_length, new_memory_size=code_length
)

# RETURN: offset=0, length
initcode += Op.RETURN
execution_gas += 0

initcode_plus_deploy_code = bytes(initcode) + bytes(deploy_code)
padding_bytes = bytes()
Expand All @@ -125,10 +115,10 @@ def __new__(
)
instance._name_ = name
instance.deploy_code = deploy_code
instance.execution_gas = execution_gas
instance.deployment_gas = GAS_PER_DEPLOYED_CODE_BYTE * len(
bytes(instance.deploy_code)
)
instance.execution_gas = initcode.gas_cost(fork)
instance.deployment_gas = Op.RETURN(
code_deposit_size=len(bytes(instance.deploy_code))
).gas_cost(fork)

return instance

Expand Down
6 changes: 5 additions & 1 deletion tests/cancun/eip1153_tstore/test_tstorage_clear_after_tx.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
Op,
Transaction,
)
from execution_testing.forks.helpers import Fork

from .spec import ref_spec_1153

Expand All @@ -22,6 +23,7 @@
def test_tstore_clear_after_deployment_tx(
blockchain_test: BlockchainTestFiller,
pre: Alloc,
fork: Fork,
) -> None:
"""
First creates a contract, which TSTOREs a value 1 in slot 1. After creating
Expand All @@ -34,7 +36,9 @@ def test_tstore_clear_after_deployment_tx(
init_code = Op.TSTORE(1, 1)
deploy_code = Op.SSTORE(1, Op.TLOAD(1))

code = Initcode(deploy_code=deploy_code, initcode_prefix=init_code)
code = Initcode(
deploy_code=deploy_code, initcode_prefix=init_code, fork=fork
)

sender = pre.fund_eoa()

Expand Down
6 changes: 5 additions & 1 deletion tests/cancun/eip1153_tstore/test_tstorage_create_contexts.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
Transaction,
compute_create_address,
)
from execution_testing.forks.helpers import Fork

from . import CreateOpcodeParams, PytestParameterEnum
from .spec import ref_spec_1153
Expand Down Expand Up @@ -164,9 +165,12 @@ def initcode( # noqa: D102
self,
deploy_code: Bytecode,
constructor_code: Bytecode,
fork: Fork,
) -> Initcode:
return Initcode(
deploy_code=deploy_code, initcode_prefix=constructor_code
deploy_code=deploy_code,
initcode_prefix=constructor_code,
fork=fork,
)

@pytest.fixture()
Expand Down
Loading
Loading