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
42 changes: 29 additions & 13 deletions fillers/eips/eip4844/datahash_opcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
TestAddress,
Transaction,
Yul,
add_kzg_version,
compute_create2_address,
compute_create_address,
test_from,
Expand All @@ -28,6 +29,7 @@
REFERENCE_SPEC_GIT_PATH = "EIPS/eip-4844.md"
REFERENCE_SPEC_VERSION = "ac003985b9be74ff48bd897770e6d5f2e4318715"

BLOB_COMMITMENT_VERSION_KZG = 1
DATAHASH_GAS_COST = 3
MAX_BLOB_PER_BLOCK = 4
BLOB_HASHES = [
Expand Down Expand Up @@ -199,9 +201,10 @@ def test_datahash_opcode_contexts(_: Fork):
initcode_datahash_sstore_bytecode.assemble(),
)

b_hashes: Sequence[bytes] = [
to_hash_bytes(1 << x) for x in range(MAX_BLOB_PER_BLOCK)
]
b_hashes: Sequence[bytes] = add_kzg_version(
[(1 << x) for x in range(MAX_BLOB_PER_BLOCK)],
BLOB_COMMITMENT_VERSION_KZG,
)

tags = [
"at_top_level_call_stack",
Expand Down Expand Up @@ -485,7 +488,7 @@ def test_datahash_gas_cost(_: Fork):
to=address,
nonce=i,
max_priority_fee_per_gas=10,
blob_versioned_hashes=[BLOB_HASHES[i % MAX_BLOB_PER_BLOCK]],
access_list=[],
)
)
txs_type_3.append(
Expand All @@ -494,7 +497,10 @@ def test_datahash_gas_cost(_: Fork):
to=address,
nonce=i,
max_priority_fee_per_gas=10,
blob_versioned_hashes=[BLOB_HASHES[i % MAX_BLOB_PER_BLOCK]],
blob_versioned_hashes=add_kzg_version(
[BLOB_HASHES[i % MAX_BLOB_PER_BLOCK]],
BLOB_COMMITMENT_VERSION_KZG,
),
)
)
post[address] = Account(storage={0: DATAHASH_GAS_COST})
Expand Down Expand Up @@ -537,11 +543,14 @@ def test_datahash_blob_versioned_hash(_: Fork):

# Create an arbitrary repeated list of blob hashes
# with length MAX_BLOB_PER_BLOCK * TOTAL_BLOCKS
b_hashes = list(
itertools.islice(
itertools.cycle(BLOB_HASHES),
MAX_BLOB_PER_BLOCK * TOTAL_BLOCKS,
)
b_hashes = add_kzg_version(
list(
itertools.islice(
itertools.cycle(BLOB_HASHES),
MAX_BLOB_PER_BLOCK * TOTAL_BLOCKS,
)
),
BLOB_COMMITMENT_VERSION_KZG,
)

# `DATAHASH` sstore template helper
Expand Down Expand Up @@ -678,7 +687,10 @@ def test_datahash_invalid_blob_index(_: Fork):
address = to_address(0x100 + i * 0x100)
pre[address] = Account(code=datahash_invalid_calls)
blob_per_block = (i % MAX_BLOB_PER_BLOCK) + 1
blob_hashes = [BLOB_HASHES[blob] for blob in range(blob_per_block)]
blob_hashes = add_kzg_version(
[BLOB_HASHES[blob] for blob in range(blob_per_block)],
BLOB_COMMITMENT_VERSION_KZG,
)
blocks.append(
Block(
txs=[
Expand Down Expand Up @@ -735,14 +747,18 @@ def test_datahash_multiple_txs_in_block(_: Fork):
}
pre[TestAddress] = Account(balance=10000000000000000000000)

b_hashes = add_kzg_version(
BLOB_HASHES[0:MAX_BLOB_PER_BLOCK], BLOB_COMMITMENT_VERSION_KZG
)

tx = Transaction(
data=to_hash_bytes(0),
gas_limit=3000000,
max_fee_per_gas=10,
max_priority_fee_per_gas=10,
max_fee_per_data_gas=10,
access_list=[],
blob_versioned_hashes=BLOB_HASHES[0:MAX_BLOB_PER_BLOCK],
blob_versioned_hashes=b_hashes,
)

blocks = [
Expand All @@ -768,7 +784,7 @@ def test_datahash_multiple_txs_in_block(_: Fork):

post = {
to_address(address): Account(
storage={i: BLOB_HASHES[i] for i in range(MAX_BLOB_PER_BLOCK)}
storage={i: b_hashes[i] for i in range(MAX_BLOB_PER_BLOCK)}
)
if address in (0x200, 0x400)
else Account(storage={i: 0 for i in range(MAX_BLOB_PER_BLOCK)})
Expand Down
51 changes: 38 additions & 13 deletions fillers/eips/eip4844/excess_data_gas.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
Header,
TestAddress,
Transaction,
add_kzg_version,
test_from,
test_only,
to_address,
Expand All @@ -29,6 +30,7 @@
REFERENCE_SPEC_GIT_PATH = "EIPS/eip-4844.md"
REFERENCE_SPEC_VERSION = "ac003985b9be74ff48bd897770e6d5f2e4318715"

BLOB_COMMITMENT_VERSION_KZG = 1
DATAHASH_GAS_COST = 3
MIN_DATA_GASPRICE = 1
DATA_GAS_PER_BLOB = 2**17
Expand Down Expand Up @@ -155,9 +157,10 @@ def generate(self) -> BlockchainTest:
max_priority_fee_per_gas=0,
max_fee_per_data_gas=data_gasprice,
access_list=[],
blob_versioned_hashes=[
to_hash_bytes(x) for x in range(self.blobs)
],
blob_versioned_hashes=add_kzg_version(
[to_hash_bytes(x) for x in range(self.blobs)],
BLOB_COMMITMENT_VERSION_KZG,
),
)
else:
tx = Transaction(
Expand Down Expand Up @@ -374,9 +377,10 @@ def generate(self) -> BlockchainTest:
excess_data_gas=parent_excess_data_gas
),
access_list=[],
blob_versioned_hashes=[
to_hash_bytes(x) for x in range(self.new_blobs)
],
blob_versioned_hashes=add_kzg_version(
[to_hash_bytes(x) for x in range(self.new_blobs)],
BLOB_COMMITMENT_VERSION_KZG,
),
)

return BlockchainTest(
Expand Down Expand Up @@ -603,10 +607,13 @@ def test_fork_transition_excess_data_gas_in_header(_: Fork):
excess_data_gas=parent_excess_data_gas
),
access_list=[],
blob_versioned_hashes=[
to_hash_bytes(x)
for x in range(MAX_BLOBS_PER_BLOCK)
],
blob_versioned_hashes=add_kzg_version(
[
to_hash_bytes(x)
for x in range(MAX_BLOBS_PER_BLOCK)
],
BLOB_COMMITMENT_VERSION_KZG,
),
)
],
)
Expand Down Expand Up @@ -647,6 +654,7 @@ class InvalidBlobTransactionTestCase:
tx_count: int = 1
parent_excess_blobs: Optional[int] = None
tx_max_data_gas_cost: Optional[int] = None
total_kzg_versioning: int = MAX_BLOBS_PER_BLOCK
account_balance_modifier: int = 0
block_base_fee: int = 7

Expand Down Expand Up @@ -681,6 +689,13 @@ def generate(self) -> BlockchainTest:
else data_gasprice
)

b_hashes = [to_hash_bytes(x) for x in range(self.blobs_per_tx)]
if self.total_kzg_versioning > 0:
b_hashes[0 : self.total_kzg_versioning] = add_kzg_version(
b_hashes[0 : self.total_kzg_versioning],
BLOB_COMMITMENT_VERSION_KZG,
)

txs: List[Transaction] = []
for tx_i in range(self.tx_count):
tx = Transaction(
Expand All @@ -693,9 +708,7 @@ def generate(self) -> BlockchainTest:
max_priority_fee_per_gas=0,
max_fee_per_data_gas=max_fee_per_data_gas,
access_list=[],
blob_versioned_hashes=[
to_hash_bytes(x) for x in range(self.blobs_per_tx)
],
blob_versioned_hashes=b_hashes,
error=self.tx_error if tx_i == (self.tx_count - 1) else None,
)
txs.append(tx)
Expand Down Expand Up @@ -778,6 +791,18 @@ def test_invalid_blob_txs(fork: Fork):
tx_error="too_few_blobs",
blobs_per_tx=0,
),
InvalidBlobTransactionTestCase(
tag="no_kzg_versioning",
tx_error="all_blob_hashes_unversioned",
blobs_per_tx=MAX_BLOBS_PER_BLOCK,
total_kzg_versioning=0,
),
InvalidBlobTransactionTestCase(
tag="partial_kzg_versioning",
tx_error="some_blob_hashes_unversioned",
blobs_per_tx=MAX_BLOBS_PER_BLOCK,
total_kzg_versioning=2,
),
]
else:
# Pre-Cancun, blocks with type 3 txs must be rejected
Expand Down
2 changes: 2 additions & 0 deletions src/ethereum_test_tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
TestAddress,
Transaction,
Withdrawal,
add_kzg_version,
ceiling_division,
compute_create2_address,
compute_create_address,
Expand Down Expand Up @@ -50,6 +51,7 @@
"Transaction",
"Withdrawal",
"Yul",
"add_kzg_version",
"ceiling_division",
"compute_create_address",
"compute_create2_address",
Expand Down
2 changes: 2 additions & 0 deletions src/ethereum_test_tools/common/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
TestPrivateKey,
)
from .helpers import (
add_kzg_version,
ceiling_division,
compute_create2_address,
compute_create_address,
Expand Down Expand Up @@ -57,6 +58,7 @@
"TestPrivateKey",
"Transaction",
"Withdrawal",
"add_kzg_version",
"alloc_to_accounts",
"even_padding",
"ceiling_division",
Expand Down
21 changes: 21 additions & 0 deletions src/ethereum_test_tools/common/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,24 @@ def to_hash(input: int | str) -> str:
Converts an int or str into proper 32-byte hash hex string.
"""
return "0x" + to_hash_bytes(input).hex()


def add_kzg_version(b_hashes, kzg_version):
"""
Adds the Kzg Version to each blob hash.
"""
kzg_version_hex = bytes([kzg_version])
kzg_versioned_hashes = []

for hash in b_hashes:
if isinstance(hash, int) or isinstance(hash, str):
kzg_versioned_hashes.append(
kzg_version_hex + to_hash_bytes(hash)[1:]
)
elif isinstance(hash, bytes):
kzg_versioned_hashes.append(kzg_version_hex + hash[1:])
else:
raise TypeError(
"Blob hash must be either an integer, string or bytes"
)
return kzg_versioned_hashes