-
Notifications
You must be signed in to change notification settings - Fork 1.2k
remove withdrawn_epoch #2998
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
remove withdrawn_epoch #2998
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| from eth2spec.test.context import ( | ||
| spec_state_test, | ||
| with_capella_and_later, | ||
| ) | ||
| from eth2spec.test.helpers.state import next_epoch_via_block | ||
| from eth2spec.test.helpers.deposits import ( | ||
| prepare_state_and_deposit, | ||
| run_deposit_processing, | ||
| ) | ||
| from eth2spec.test.helpers.withdrawals import set_validator_fully_withdrawable | ||
|
|
||
|
|
||
| @with_capella_and_later | ||
| @spec_state_test | ||
| def test_success_top_up_to_withdrawn_validator(spec, state): | ||
| validator_index = 0 | ||
|
|
||
| # Fully withdraw validator | ||
| set_validator_fully_withdrawable(spec, state, validator_index) | ||
| assert state.balances[validator_index] > 0 | ||
| next_epoch_via_block(spec, state) | ||
| assert state.balances[validator_index] == 0 | ||
| assert state.validators[validator_index].effective_balance > 0 | ||
| next_epoch_via_block(spec, state) | ||
| assert state.validators[validator_index].effective_balance == 0 | ||
|
|
||
| # Make a top-up balance to validator | ||
| amount = spec.MAX_EFFECTIVE_BALANCE // 4 | ||
| deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True) | ||
|
|
||
| yield from run_deposit_processing(spec, state, deposit, validator_index) | ||
|
|
||
| assert state.balances[validator_index] == amount | ||
| assert state.validators[validator_index].effective_balance == 0 | ||
|
|
||
| validator = state.validators[validator_index] | ||
| balance = state.balances[validator_index] | ||
| current_epoch = spec.get_current_epoch(state) | ||
| assert spec.is_fully_withdrawable_validator(validator, balance, current_epoch) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,39 +1,40 @@ | ||
| from random import Random | ||
|
|
||
| from eth2spec.test.context import ( | ||
| with_capella_and_later, | ||
| spec_state_test, | ||
| ) | ||
| from eth2spec.test.helpers.epoch_processing import run_epoch_processing_with | ||
|
|
||
|
|
||
| def set_validator_withdrawable(spec, state, index, withdrawable_epoch=None): | ||
| if withdrawable_epoch is None: | ||
| withdrawable_epoch = spec.get_current_epoch(state) | ||
|
|
||
| validator = state.validators[index] | ||
| validator.withdrawable_epoch = withdrawable_epoch | ||
| validator.withdrawal_credentials = spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX + validator.withdrawal_credentials[1:] | ||
|
|
||
| assert spec.is_fully_withdrawable_validator(validator, withdrawable_epoch) | ||
| from eth2spec.test.helpers.random import ( | ||
| randomize_state, | ||
| ) | ||
| from eth2spec.test.helpers.epoch_processing import ( | ||
| run_epoch_processing_to, | ||
| ) | ||
| from eth2spec.test.helpers.withdrawals import ( | ||
| set_validator_fully_withdrawable, | ||
| ) | ||
|
|
||
|
|
||
| def run_process_full_withdrawals(spec, state, num_expected_withdrawals=None): | ||
| run_epoch_processing_to(spec, state, 'process_full_withdrawals') | ||
|
|
||
| pre_next_withdrawal_index = state.next_withdrawal_index | ||
| pre_withdrawal_queue = state.withdrawal_queue.copy() | ||
| to_be_withdrawn_indices = [ | ||
| index for index, validator in enumerate(state.validators) | ||
| if spec.is_fully_withdrawable_validator(validator, spec.get_current_epoch(state)) | ||
| if spec.is_fully_withdrawable_validator(validator, state.balances[index], spec.get_current_epoch(state)) | ||
| ] | ||
|
|
||
| if num_expected_withdrawals is not None: | ||
| assert len(to_be_withdrawn_indices) == num_expected_withdrawals | ||
| else: | ||
| num_expected_withdrawals = len(to_be_withdrawn_indices) | ||
|
|
||
| yield from run_epoch_processing_with(spec, state, 'process_full_withdrawals') | ||
| yield 'pre', state | ||
| spec.process_full_withdrawals(state) | ||
| yield 'post', state | ||
|
Comment on lines
-32
to
+35
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. any reason to not use the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes this pattern is useful when you need to capture information right before the function is called. In this case, balance updates can/will occur during those interim epoch processings. So in some cases this changes the |
||
|
|
||
| for index in to_be_withdrawn_indices: | ||
| validator = state.validators[index] | ||
| assert validator.fully_withdrawn_epoch == spec.get_current_epoch(state) | ||
| assert state.balances[index] == 0 | ||
|
|
||
| assert len(state.withdrawal_queue) == len(pre_withdrawal_queue) + num_expected_withdrawals | ||
|
|
@@ -42,21 +43,57 @@ def run_process_full_withdrawals(spec, state, num_expected_withdrawals=None): | |
|
|
||
| @with_capella_and_later | ||
| @spec_state_test | ||
| def test_no_withdrawals(spec, state): | ||
| def test_no_withdrawable_validators(spec, state): | ||
| pre_validators = state.validators.copy() | ||
| yield from run_process_full_withdrawals(spec, state, 0) | ||
|
|
||
| assert pre_validators == state.validators | ||
|
|
||
|
|
||
| @with_capella_and_later | ||
| @spec_state_test | ||
| def test_withdrawable_epoch_but_0_balance(spec, state): | ||
| current_epoch = spec.get_current_epoch(state) | ||
| set_validator_fully_withdrawable(spec, state, 0, current_epoch) | ||
|
|
||
| state.validators[0].effective_balance = 10000000000 | ||
| state.balances[0] = 0 | ||
|
|
||
| yield from run_process_full_withdrawals(spec, state, 0) | ||
|
|
||
|
|
||
| @with_capella_and_later | ||
| @spec_state_test | ||
| def test_withdrawable_epoch_but_0_effective_balance_0_balance(spec, state): | ||
| current_epoch = spec.get_current_epoch(state) | ||
| set_validator_fully_withdrawable(spec, state, 0, current_epoch) | ||
|
|
||
| state.validators[0].effective_balance = 0 | ||
| state.balances[0] = 0 | ||
|
|
||
| yield from run_process_full_withdrawals(spec, state, 0) | ||
|
|
||
|
|
||
| @with_capella_and_later | ||
| @spec_state_test | ||
| def test_withdrawable_epoch_but_0_effective_balance_nonzero_balance(spec, state): | ||
| current_epoch = spec.get_current_epoch(state) | ||
| set_validator_fully_withdrawable(spec, state, 0, current_epoch) | ||
|
|
||
| state.validators[0].effective_balance = 0 | ||
| state.balances[0] = 100000000 | ||
|
|
||
| yield from run_process_full_withdrawals(spec, state, 1) | ||
|
|
||
|
|
||
| @with_capella_and_later | ||
| @spec_state_test | ||
| def test_no_withdrawals_but_some_next_epoch(spec, state): | ||
| current_epoch = spec.get_current_epoch(state) | ||
|
|
||
| # Make a few validators withdrawable at the *next* epoch | ||
| for index in range(3): | ||
| set_validator_withdrawable(spec, state, index, current_epoch + 1) | ||
| set_validator_fully_withdrawable(spec, state, index, current_epoch + 1) | ||
|
|
||
| yield from run_process_full_withdrawals(spec, state, 0) | ||
|
|
||
|
|
@@ -65,7 +102,7 @@ def test_no_withdrawals_but_some_next_epoch(spec, state): | |
| @spec_state_test | ||
| def test_single_withdrawal(spec, state): | ||
| # Make one validator withdrawable | ||
| set_validator_withdrawable(spec, state, 0) | ||
| set_validator_fully_withdrawable(spec, state, 0) | ||
|
|
||
| assert state.next_withdrawal_index == 0 | ||
| yield from run_process_full_withdrawals(spec, state, 1) | ||
|
|
@@ -78,7 +115,7 @@ def test_single_withdrawal(spec, state): | |
| def test_multi_withdrawal(spec, state): | ||
| # Make a few validators withdrawable | ||
| for index in range(3): | ||
| set_validator_withdrawable(spec, state, index) | ||
| set_validator_fully_withdrawable(spec, state, index) | ||
|
|
||
| yield from run_process_full_withdrawals(spec, state, 3) | ||
|
|
||
|
|
@@ -88,6 +125,50 @@ def test_multi_withdrawal(spec, state): | |
| def test_all_withdrawal(spec, state): | ||
| # Make all validators withdrawable | ||
| for index in range(len(state.validators)): | ||
| set_validator_withdrawable(spec, state, index) | ||
| set_validator_fully_withdrawable(spec, state, index) | ||
|
|
||
| yield from run_process_full_withdrawals(spec, state, len(state.validators)) | ||
|
|
||
|
|
||
| def run_random_full_withdrawals_test(spec, state, rng): | ||
| randomize_state(spec, state, rng) | ||
| for index in range(len(state.validators)): | ||
| # 50% withdrawable | ||
| if rng.choice([True, False]): | ||
| set_validator_fully_withdrawable(spec, state, index) | ||
| validator = state.validators[index] | ||
| # 12.5% unset credentials | ||
| if rng.randint(0, 7) == 0: | ||
| validator.withdrawal_credentials = spec.BLS_WITHDRAWAL_PREFIX + validator.withdrawal_credentials[1:] | ||
| # 12.5% not enough balance | ||
| if rng.randint(0, 7) == 0: | ||
| state.balances[index] = 0 | ||
| # 12.5% not close enough epoch | ||
| if rng.randint(0, 7) == 0: | ||
| validator.withdrawable_epoch += 1 | ||
djrtwo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| yield from run_process_full_withdrawals(spec, state, None) | ||
|
|
||
|
|
||
| @with_capella_and_later | ||
| @spec_state_test | ||
| def test_random_withdrawals_0(spec, state): | ||
| yield from run_random_full_withdrawals_test(spec, state, Random(444)) | ||
|
|
||
|
|
||
| @with_capella_and_later | ||
| @spec_state_test | ||
| def test_random_withdrawals_1(spec, state): | ||
| yield from run_random_full_withdrawals_test(spec, state, Random(420)) | ||
|
|
||
|
|
||
| @with_capella_and_later | ||
| @spec_state_test | ||
| def test_random_withdrawals_2(spec, state): | ||
| yield from run_random_full_withdrawals_test(spec, state, Random(200)) | ||
|
|
||
|
|
||
| @with_capella_and_later | ||
| @spec_state_test | ||
| def test_random_withdrawals_3(spec, state): | ||
| yield from run_random_full_withdrawals_test(spec, state, Random(2000000)) | ||
Uh oh!
There was an error while loading. Please reload this page.