From b49c5b043cbb5d1b7ca7ec9a83ba503feba11782 Mon Sep 17 00:00:00 2001 From: spencer-tb Date: Sun, 28 Jan 2024 19:12:29 +0700 Subject: [PATCH] feat(tests): Add blob gas subtraction order tests. --- tests/cancun/eip4844_blobs/test_blob_txs.py | 84 ++++++++++++++++++++- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/tests/cancun/eip4844_blobs/test_blob_txs.py b/tests/cancun/eip4844_blobs/test_blob_txs.py index b5f5eee5b5..2a4f98fe6b 100644 --- a/tests/cancun/eip4844_blobs/test_blob_txs.py +++ b/tests/cancun/eip4844_blobs/test_blob_txs.py @@ -207,10 +207,28 @@ def total_account_minimum_balance( # noqa: D103 Calculates the minimum balance required for the account to be able to send the transactions in the block of the test. """ + minimum_cost = 0 + for tx_blob_count in [len(x) for x in blob_hashes_per_tx]: + blob_cost = tx_max_fee_per_blob_gas * Spec.GAS_PER_BLOB * tx_blob_count + minimum_cost += (tx_gas * tx_max_fee_per_gas) + tx_value + blob_cost + return minimum_cost + + +@pytest.fixture +def total_account_transactions_fee( # noqa: D103 + tx_gas: int, + tx_value: int, + block_fee_per_gas: int, + blob_gasprice: int, + blob_hashes_per_tx: List[List[bytes]], +) -> int: + """ + Calculates the actual fee for the blob transactions in the block of the test. + """ total_cost = 0 for tx_blob_count in [len(x) for x in blob_hashes_per_tx]: - data_cost = tx_max_fee_per_blob_gas * Spec.GAS_PER_BLOB * tx_blob_count - total_cost += (tx_gas * tx_max_fee_per_gas) + tx_value + data_cost + blob_cost = blob_gasprice * Spec.GAS_PER_BLOB * tx_blob_count + total_cost += (tx_gas * block_fee_per_gas) + tx_value + blob_cost return total_cost @@ -896,6 +914,68 @@ def test_sufficient_balance_blob_tx_pre_fund_tx( ) +@pytest.mark.parametrize( + "tx_access_list", + [[], [AccessList(address=100, storage_keys=[100, 200])]], + ids=["no_access_list", "access_list"], +) +@pytest.mark.parametrize("tx_max_fee_per_gas", [7, 14]) +@pytest.mark.parametrize("tx_value", [0, 1]) +@pytest.mark.parametrize( + "tx_calldata", + [b"", b"\x01"], + ids=["no_calldata", "single_non_zero_byte_calldata"], +) +@pytest.mark.parametrize("tx_max_fee_per_blob_gas", [1, 100]) +@pytest.mark.parametrize( + "tx_gas", [500_000], ids=[""] +) # Increase gas to account for contract code +@pytest.mark.parametrize( + "mid_tx_send_amount", [100] +) # Amount sent by the contract to the sender mid execution +@pytest.mark.valid_from("Cancun") +def test_blob_gas_subtraction_tx( + state_test: StateTestFiller, + state_env: Environment, + pre: Dict, + txs: List[Transaction], + destination_account: str, + mid_tx_send_amount: int, + total_account_transactions_fee: int, +): + """ + Check that the blob gas fee for a transaction is subtracted from the sender balance before the + transaction is executed, including: + + - Transactions with max fee equal or higher than current block base fee + - Transactions with and without value + - Transactions with and without calldata + - Transactions with max fee per blob gas lower or higher than the priority fee + - Transactions where an externally owned account sends funds to the sender mid execution + """ + assert len(txs) == 1 + pre[destination_account] = Account( + balance=mid_tx_send_amount, + code=Op.SSTORE(0, Op.BALANCE(Op.ORIGIN)) + + Op.CALL(Op.GAS, Op.ORIGIN, mid_tx_send_amount, 0, 0, 0, 0) + + Op.SSTORE(1, Op.BALANCE(Op.ORIGIN)), + ) + post = { + destination_account: Account( + storage={ + 0: pre[TestAddress].balance - total_account_transactions_fee, + 1: pre[TestAddress].balance - total_account_transactions_fee + mid_tx_send_amount, + } + ) + } + state_test( + pre=pre, + post=post, + tx=txs[0], + env=state_env, + ) + + @pytest.mark.parametrize( "blobs_per_tx", all_valid_blob_combinations(),