Skip to content

test_zero_amount()

Documentation for tests/shanghai/eip4895_withdrawals/test_withdrawals.py::test_zero_amount@83970623.

Generate fixtures for these test cases for Prague with:

fill -v tests/shanghai/eip4895_withdrawals/test_withdrawals.py::test_zero_amount --fork Prague

Test withdrawals with zero amount for the following cases, all withdrawals are included in one block.

  1. Two withdrawals of zero amount to two different addresses; one to an untouched account, one to an account with a balance.
  2. As 1., but with an additional withdrawal with positive value.
  3. As 2., but with an additional withdrawal containing the maximum value possible.
  4. As 3., but with order of withdrawals in the block reversed.
Source code in tests/shanghai/eip4895_withdrawals/test_withdrawals.py
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
@pytest.mark.parametrize(
    "test_case",
    list(ZeroAmountTestCases),
    ids=[case.value for case in ZeroAmountTestCases],
)
def test_zero_amount(
    blockchain_test: BlockchainTestFiller,
    pre: Alloc,
    test_case: ZeroAmountTestCases,
):
    """
    Test withdrawals with zero amount for the following cases, all withdrawals
    are included in one block.

    1. Two withdrawals of zero amount to two different addresses; one to an
       untouched account, one to an account with a balance.
    2. As 1., but with an additional withdrawal with positive value.
    3. As 2., but with an additional withdrawal containing the maximum value
       possible.
    4. As 3., but with order of withdrawals in the block reversed.

    """
    empty_accounts = [pre.fund_eoa(0) for _ in range(3)]
    zero_balance_contract = pre.deploy_contract(Op.STOP)

    all_withdrawals = [
        # No value, untouched account
        Withdrawal(
            index=0,
            validator_index=0,
            address=empty_accounts[0],
            amount=0,
        ),
        # No value, touched account
        Withdrawal(
            index=0,
            validator_index=0,
            address=zero_balance_contract,
            amount=0,
        ),
        # Withdrawal with value
        Withdrawal(
            index=1,
            validator_index=0,
            address=empty_accounts[1],
            amount=1,
        ),
        # Withdrawal with maximum amount
        Withdrawal(
            index=2,
            validator_index=0,
            address=empty_accounts[2],
            amount=2**64 - 1,
        ),
    ]
    all_post = {
        empty_accounts[0]: Account.NONEXISTENT,
        zero_balance_contract: Account(code=Op.STOP, balance=0),
        empty_accounts[1]: Account(balance=ONE_GWEI),
        empty_accounts[2]: Account(balance=(2**64 - 1) * ONE_GWEI),
    }

    withdrawals: List[Withdrawal] = []
    post: Mapping[Address, Account | object] = {}
    if test_case == ZeroAmountTestCases.TWO_ZERO:
        withdrawals = all_withdrawals[0:2]
        post = {
            account: all_post[account]
            for account in post
            if account in [empty_accounts[0], zero_balance_contract]
        }
    elif test_case == ZeroAmountTestCases.THREE_ONE_WITH_VALUE:
        withdrawals = all_withdrawals[0:3]
        post = {
            account: all_post[account]
            for account in post
            if account
            in [
                empty_accounts[0],
                zero_balance_contract,
                empty_accounts[1],
            ]
        }
    elif test_case == ZeroAmountTestCases.FOUR_ONE_WITH_MAX:
        withdrawals = all_withdrawals
        post = all_post
    elif test_case == ZeroAmountTestCases.FOUR_ONE_WITH_MAX_REVERSED:
        for i, w in enumerate(reversed(all_withdrawals)):
            withdrawals.append(
                Withdrawal(
                    index=i,
                    validator_index=w.validator_index,
                    address=w.address,
                    amount=w.amount,
                )
            )
        post = all_post

    blockchain_test(
        pre=pre,
        # TODO: Fix in BlockchainTest? post: Mapping[str, Account | object]
        # to allow for Account.NONEXISTENT
        post=post,  # type: ignore
        blocks=[Block(withdrawals=withdrawals)],
        tag=test_case.value,
    )

Parametrized Test Cases

The interactive table below is also available as a standalone page.

Test ID (Abbreviated) test_case
...fork_Shanghai-blockchain_test-two_withdrawals_no_value ZeroAmountTestCases.TWO_ZERO
...fork_Shanghai-blockchain_test-three_withdrawals_one_with_value ZeroAmountTestCases.THREE_ONE_WITH_VALUE
...fork_Shanghai-blockchain_test-four_withdrawals_one_with_value_one_with_max ZeroAmountTestCases.FOUR_ONE_WITH_MAX
...fork_Shanghai-blockchain_test-four_withdrawals_one_with_value_one_with_max_reversed_order ZeroAmountTestCases.FOUR_ONE_WITH_MAX_REVERSED
...fork_Cancun-blockchain_test-two_withdrawals_no_value ZeroAmountTestCases.TWO_ZERO
...fork_Cancun-blockchain_test-three_withdrawals_one_with_value ZeroAmountTestCases.THREE_ONE_WITH_VALUE
...fork_Cancun-blockchain_test-four_withdrawals_one_with_value_one_with_max ZeroAmountTestCases.FOUR_ONE_WITH_MAX
...fork_Cancun-blockchain_test-four_withdrawals_one_with_value_one_with_max_reversed_order ZeroAmountTestCases.FOUR_ONE_WITH_MAX_REVERSED
...fork_Prague-blockchain_test-two_withdrawals_no_value ZeroAmountTestCases.TWO_ZERO
...fork_Prague-blockchain_test-three_withdrawals_one_with_value ZeroAmountTestCases.THREE_ONE_WITH_VALUE
...fork_Prague-blockchain_test-four_withdrawals_one_with_value_one_with_max ZeroAmountTestCases.FOUR_ONE_WITH_MAX
...fork_Prague-blockchain_test-four_withdrawals_one_with_value_one_with_max_reversed_order ZeroAmountTestCases.FOUR_ONE_WITH_MAX_REVERSED
...fork_Osaka-blockchain_test-two_withdrawals_no_value ZeroAmountTestCases.TWO_ZERO
...fork_Osaka-blockchain_test-three_withdrawals_one_with_value ZeroAmountTestCases.THREE_ONE_WITH_VALUE
...fork_Osaka-blockchain_test-four_withdrawals_one_with_value_one_with_max ZeroAmountTestCases.FOUR_ONE_WITH_MAX
...fork_Osaka-blockchain_test-four_withdrawals_one_with_value_one_with_max_reversed_order ZeroAmountTestCases.FOUR_ONE_WITH_MAX_REVERSED