Skip to content

Commit 37ceb8b

Browse files
authored
feat(tests): Add blob gas subtraction order tests (#407)
* feat(tests): Add blob gas subtraction order tests. * feat(tests): Remove duplicate fixture within test_blob_txs.py * feat(tests): Add max priority fee parameterization to blob gas subtraction tests. * docs: Add changelog entry for blob gas subtraction test.
1 parent c6ebfc5 commit 37ceb8b

File tree

2 files changed

+93
-22
lines changed

2 files changed

+93
-22
lines changed

docs/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Test fixtures for use by clients are available for each release on the [Github r
88

99
### 🧪 Test Cases
1010

11+
-[EIP-4844](https://eips.ethereum.org/EIPS/eip-4844): Adds `test_blob_gas_subtraction_tx()` verifying the blob gas fee is subtracted from the sender before executing the blob tx ([#407](https://github.com/ethereum/execution-spec-tests/pull/407)).
12+
1113
### 🛠️ Framework
1214

1315
- 🐞 State tests generated with transition forks no longer use the transition fork name in the fixture output, instead they use the actual enabled fork according to the state test's block number and timestamp ([#406](https://github.com/ethereum/execution-spec-tests/pull/406)).

tests/cancun/eip4844_blobs/test_blob_txs.py

Lines changed: 91 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,33 @@ def total_account_minimum_balance( # noqa: D103
207207
Calculates the minimum balance required for the account to be able to send
208208
the transactions in the block of the test.
209209
"""
210+
minimum_cost = 0
211+
for tx_blob_count in [len(x) for x in blob_hashes_per_tx]:
212+
blob_cost = tx_max_fee_per_blob_gas * Spec.GAS_PER_BLOB * tx_blob_count
213+
minimum_cost += (tx_gas * tx_max_fee_per_gas) + tx_value + blob_cost
214+
return minimum_cost
215+
216+
217+
@pytest.fixture
218+
def total_account_transactions_fee( # noqa: D103
219+
tx_gas: int,
220+
tx_value: int,
221+
blob_gasprice: int,
222+
block_fee_per_gas: int,
223+
tx_max_fee_per_gas: int,
224+
tx_max_priority_fee_per_gas: int,
225+
blob_hashes_per_tx: List[List[bytes]],
226+
) -> int:
227+
"""
228+
Calculates the actual fee for the blob transactions in the block of the test.
229+
"""
210230
total_cost = 0
211231
for tx_blob_count in [len(x) for x in blob_hashes_per_tx]:
212-
data_cost = tx_max_fee_per_blob_gas * Spec.GAS_PER_BLOB * tx_blob_count
213-
total_cost += (tx_gas * tx_max_fee_per_gas) + tx_value + data_cost
232+
blob_cost = blob_gasprice * Spec.GAS_PER_BLOB * tx_blob_count
233+
block_producer_fee = (
234+
tx_max_fee_per_gas - block_fee_per_gas if tx_max_priority_fee_per_gas else 0
235+
)
236+
total_cost += (tx_gas * (block_fee_per_gas + block_producer_fee)) + tx_value + blob_cost
214237
return total_cost
215238

216239

@@ -463,34 +486,17 @@ def header_verify(
463486
return header_verify
464487

465488

466-
@pytest.fixture
467-
def all_blob_gas_used(
468-
fork: Fork,
469-
txs: List[Transaction],
470-
block_number: int,
471-
block_timestamp: int,
472-
) -> Optional[int | Removable]:
473-
"""
474-
Calculates the blob gas used by the test block taking into account failed transactions.
475-
"""
476-
if not fork.header_blob_gas_used_required(
477-
block_number=block_number, timestamp=block_timestamp
478-
):
479-
return Header.EMPTY_FIELD
480-
return sum([Spec.get_total_blob_gas(tx) for tx in txs])
481-
482-
483489
@pytest.fixture
484490
def rlp_modifier(
485-
all_blob_gas_used: Optional[int | Removable],
491+
expected_blob_gas_used: Optional[int | Removable],
486492
) -> Optional[Header]:
487493
"""
488494
Header fields to modify on the output block in the BlockchainTest.
489495
"""
490-
if all_blob_gas_used == Header.EMPTY_FIELD:
496+
if expected_blob_gas_used == Header.EMPTY_FIELD:
491497
return None
492498
return Header(
493-
blob_gas_used=all_blob_gas_used,
499+
blob_gas_used=expected_blob_gas_used,
494500
)
495501

496502

@@ -896,6 +902,69 @@ def test_sufficient_balance_blob_tx_pre_fund_tx(
896902
)
897903

898904

905+
@pytest.mark.parametrize(
906+
"tx_access_list",
907+
[[], [AccessList(address=100, storage_keys=[100, 200])]],
908+
ids=["no_access_list", "access_list"],
909+
)
910+
@pytest.mark.parametrize("tx_max_fee_per_gas", [7, 14])
911+
@pytest.mark.parametrize("tx_max_priority_fee_per_gas", [0, 7])
912+
@pytest.mark.parametrize("tx_value", [0, 1])
913+
@pytest.mark.parametrize(
914+
"tx_calldata",
915+
[b"", b"\x01"],
916+
ids=["no_calldata", "single_non_zero_byte_calldata"],
917+
)
918+
@pytest.mark.parametrize("tx_max_fee_per_blob_gas", [1, 100])
919+
@pytest.mark.parametrize(
920+
"tx_gas", [500_000], ids=[""]
921+
) # Increase gas to account for contract code
922+
@pytest.mark.parametrize(
923+
"mid_tx_send_amount", [100]
924+
) # Amount sent by the contract to the sender mid execution
925+
@pytest.mark.valid_from("Cancun")
926+
def test_blob_gas_subtraction_tx(
927+
state_test: StateTestFiller,
928+
state_env: Environment,
929+
pre: Dict,
930+
txs: List[Transaction],
931+
destination_account: str,
932+
mid_tx_send_amount: int,
933+
total_account_transactions_fee: int,
934+
):
935+
"""
936+
Check that the blob gas fee for a transaction is subtracted from the sender balance before the
937+
transaction is executed, including:
938+
939+
- Transactions with max fee equal or higher than current block base fee
940+
- Transactions with and without value
941+
- Transactions with and without calldata
942+
- Transactions with max fee per blob gas lower or higher than the priority fee
943+
- Transactions where an externally owned account sends funds to the sender mid execution
944+
"""
945+
assert len(txs) == 1
946+
pre[destination_account] = Account(
947+
balance=mid_tx_send_amount,
948+
code=Op.SSTORE(0, Op.BALANCE(Op.ORIGIN))
949+
+ Op.CALL(Op.GAS, Op.ORIGIN, mid_tx_send_amount, 0, 0, 0, 0)
950+
+ Op.SSTORE(1, Op.BALANCE(Op.ORIGIN)),
951+
)
952+
post = {
953+
destination_account: Account(
954+
storage={
955+
0: pre[TestAddress].balance - total_account_transactions_fee,
956+
1: pre[TestAddress].balance - total_account_transactions_fee + mid_tx_send_amount,
957+
}
958+
)
959+
}
960+
state_test(
961+
pre=pre,
962+
post=post,
963+
tx=txs[0],
964+
env=state_env,
965+
)
966+
967+
899968
@pytest.mark.parametrize(
900969
"blobs_per_tx",
901970
all_valid_blob_combinations(),

0 commit comments

Comments
 (0)