Skip to content

test_use_value_in_tx()

Documentation for tests/shanghai/eip4895_withdrawals/test_withdrawals.py::TestUseValueInTx::test_use_value_in_tx@ffe48572.

Generate fixtures for these test cases for Bogota with:

fill -v tests/shanghai/eip4895_withdrawals/test_withdrawals.py::TestUseValueInTx::test_use_value_in_tx --fork Bogota

Test that the value from a withdrawal can be used in a transaction.

  1. tx_in_withdrawals_block: Test that the withdrawal value can not be used by a transaction in the same block as the withdrawal.

  2. tx_after_withdrawals_block: Test that the withdrawal value can be used by a transaction in the subsequent block.

Source code in tests/shanghai/eip4895_withdrawals/test_withdrawals.py
@pytest.mark.inclusion_test
@pytest.mark.parametrize(
    "test_case",
    [
        pytest.param(
            "tx_in_withdrawals_block",
            id="tx_in_withdrawals_block",
            marks=pytest.mark.exception_test,
        ),
        pytest.param(
            "tx_after_withdrawals_block", id="tx_after_withdrawals_block"
        ),
    ],
)
class TestUseValueInTx:
    """
    Test that the value from a withdrawal can be used in a transaction.

    1. `tx_in_withdrawals_block`: Test that the withdrawal value can not be
    used by a transaction in the same block as the withdrawal.

    2. `tx_after_withdrawals_block`: Test that the withdrawal value can be used
    by a transaction in the subsequent block.
    """

    @pytest.fixture
    def sender(self, pre: Alloc) -> EOA:
        """Funded EOA used for sending transactions."""
        return pre.fund_eoa(1)

    @pytest.fixture
    def recipient(self, pre: Alloc) -> EOA:
        """Funded EOA used for sending transactions."""
        return pre.fund_eoa(0)

    @pytest.fixture
    def tx(  # noqa: D102
        self, sender: EOA, recipient: EOA, fork: Fork
    ) -> Transaction:
        # Transaction sent from the `sender`, which has 1 wei balance at start
        gas_limit = fork.transaction_intrinsic_cost_calculator()(
            recipient_type=RecipientType.EOA,
        )
        return Transaction(
            gas_price=ONE_GWEI,
            gas_limit=gas_limit,
            to=recipient,
            sender=sender,
        )

    @pytest.fixture
    def withdrawal(self, tx: Transaction, sender: EOA) -> Withdrawal:  # noqa: D102
        return Withdrawal(
            index=0,
            validator_index=0,
            address=sender,
            amount=tx.gas_limit + 1,
        )

    @pytest.fixture
    def blocks(  # noqa: D102
        self, tx: Transaction, withdrawal: Withdrawal, test_case: str
    ) -> List[Block]:
        if test_case == "tx_in_withdrawals_block":
            return [
                Block(
                    txs=[
                        tx.with_error(
                            TransactionException.INSUFFICIENT_ACCOUNT_FUNDS
                        )
                    ],
                    withdrawals=[
                        withdrawal,
                    ],
                    exception=TransactionException.INSUFFICIENT_ACCOUNT_FUNDS,
                )
            ]
        if test_case == "tx_after_withdrawals_block":
            return [
                Block(
                    txs=[],
                    withdrawals=[
                        withdrawal,
                    ],
                ),
                Block(
                    txs=[tx],
                    withdrawals=[],
                ),
            ]
        raise Exception("Invalid test case.")

    @pytest.fixture
    def post(  # noqa: D102
        self,
        sender: EOA,
        tx: Transaction,
        withdrawal: Withdrawal,
        test_case: str,
    ) -> Dict:
        if test_case == "tx_in_withdrawals_block":
            return {}
        if test_case == "tx_after_withdrawals_block":
            # The withdrawal (in Gwei) covers the transaction's fee at a
            # gas price of one Gwei, leaving one Gwei on top of the
            # sender's initial one wei.
            return {
                sender: Account(
                    nonce=1,
                    balance_change=withdrawal.amount * ONE_GWEI
                    - GasFee(tx, gas=tx.gas_limit),
                )
            }
        raise Exception("Invalid test case.")

    def test_use_value_in_tx(
        self,
        pre: Alloc,
        blockchain_test: BlockchainTestFiller,
        post: dict,
        blocks: List[Block],
    ) -> None:
        """Test sending withdrawal value in a transaction."""
        blockchain_test(pre=pre, post=post, blocks=blocks)

test_use_value_in_tx(pre, blockchain_test, post, blocks)

Test sending withdrawal value in a transaction.

Source code in tests/shanghai/eip4895_withdrawals/test_withdrawals.py
def test_use_value_in_tx(
    self,
    pre: Alloc,
    blockchain_test: BlockchainTestFiller,
    post: dict,
    blocks: List[Block],
) -> None:
    """Test sending withdrawal value in a transaction."""
    blockchain_test(pre=pre, post=post, blocks=blocks)

Parametrized Test Cases

This test generates 2 parametrized test cases across 6 forks.