From 397c2beeb87ee3b4dfdb7c9da10744624ba2bc45 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Mon, 8 Apr 2024 15:58:36 -0600 Subject: [PATCH 1/4] Enforce Activation Rate Limit at Fork Transition --- specs/_features/eip7251/beacon-chain.md | 14 ++++++++++++++ specs/_features/eip7251/fork.md | 17 +++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/specs/_features/eip7251/beacon-chain.md b/specs/_features/eip7251/beacon-chain.md index ef61e3d3a..5d3924cd6 100644 --- a/specs/_features/eip7251/beacon-chain.md +++ b/specs/_features/eip7251/beacon-chain.md @@ -51,6 +51,7 @@ - [Updated `initiate_validator_exit`](#updated--initiate_validator_exit) - [New `switch_to_compounding_validator`](#new-switch_to_compounding_validator) - [New `queue_excess_active_balance`](#new-queue_excess_active_balance) + - [New `queue_entire_balance_and_reset_validator`](#new-queue_entire_balance_and_reset_validator) - [New `compute_exit_epoch_and_update_churn`](#new-compute_exit_epoch_and_update_churn) - [New `compute_consolidation_epoch_and_update_churn`](#new-compute_consolidation_epoch_and_update_churn) - [Updated `slash_validator`](#updated-slash_validator) @@ -526,6 +527,19 @@ def queue_excess_active_balance(state: BeaconState, index: ValidatorIndex) -> No ) ``` +#### New `queue_entire_balance_and_reset_validator` +```python +def queue_entire_balance_and_reset_validator(state: BeaconState, index: ValidatorIndex) -> None: + balance = state.balances[index] + state.balances[index] = 0 + validator = state.validators[index] + validator.effective_balance = 0 + validator.activation_eligibility_epoch = FAR_FUTURE_EPOCH + state.pending_balance_deposits.append( + PendingBalanceDeposit(index=index, amount=balance) + ) +``` + #### New `compute_exit_epoch_and_update_churn` ```python diff --git a/specs/_features/eip7251/fork.md b/specs/_features/eip7251/fork.md index 49e01ea7e..3e7c32e37 100644 --- a/specs/_features/eip7251/fork.md +++ b/specs/_features/eip7251/fork.md @@ -128,6 +128,23 @@ def upgrade_to_eip7251(pre: deneb.BeaconState) -> BeaconState: pending_consolidations=[], ) + activation_queue = [] + pre_activation_queue = [] + below_minimum = [] + for index, validator in enumerate(post.validators): + if validator.activation_epoch == FAR_FUTURE_EPOCH: + if validator.activation_eligibility_epoch != FAR_FUTURE_EPOCH: + activation_queue.append(index) + else: + if validator.effective_balance >= MIN_ACTIVATION_BALANCE: + pre_activation_queue.append(index) + else: + below_minimum.append(index) + + activation_queue.sort(key=lambda index: (post.validators[index].activation_eligibility_epoch, index)) + for index in activation_queue + pre_activation_queue + below_minimum: + queue_entire_balance_and_reset_validator(post, ValidatorIndex(index)) + # Ensure early adopters of compounding credentials go through the activation churn for index, validator in enumerate(post.validators): if has_compounding_withdrawal_credential(validator): From 21262499d7d73b9a53e7cb7a932e4a4d209fed54 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Wed, 10 Apr 2024 11:20:42 -0500 Subject: [PATCH 2/4] Simplify Sorting Logic --- specs/_features/eip7251/fork.md | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/specs/_features/eip7251/fork.md b/specs/_features/eip7251/fork.md index 3e7c32e37..dda5c7ee6 100644 --- a/specs/_features/eip7251/fork.md +++ b/specs/_features/eip7251/fork.md @@ -128,21 +128,16 @@ def upgrade_to_eip7251(pre: deneb.BeaconState) -> BeaconState: pending_consolidations=[], ) - activation_queue = [] - pre_activation_queue = [] - below_minimum = [] - for index, validator in enumerate(post.validators): - if validator.activation_epoch == FAR_FUTURE_EPOCH: - if validator.activation_eligibility_epoch != FAR_FUTURE_EPOCH: - activation_queue.append(index) - else: - if validator.effective_balance >= MIN_ACTIVATION_BALANCE: - pre_activation_queue.append(index) - else: - below_minimum.append(index) - - activation_queue.sort(key=lambda index: (post.validators[index].activation_eligibility_epoch, index)) - for index in activation_queue + pre_activation_queue + below_minimum: + # add validators that are not yet active to pending balance deposits + pre_activation = sorted([ + index for index, validator in enumerate(post.validators) + if validator.activation_epoch == FAR_FUTURE_EPOCH + ], key=lambda index: ( + post.validators[index].activation_eligibility_epoch, + post.validators[index].effective_balance < MIN_ACTIVATION_BALANCE, + index + )) + for index in pre_activation: queue_entire_balance_and_reset_validator(post, ValidatorIndex(index)) # Ensure early adopters of compounding credentials go through the activation churn From 8ff66f896d662638f3afee9c3143867443faaab7 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Wed, 10 Apr 2024 11:24:48 -0500 Subject: [PATCH 3/4] Removed Secondary Sort Condition --- specs/_features/eip7251/fork.md | 1 - 1 file changed, 1 deletion(-) diff --git a/specs/_features/eip7251/fork.md b/specs/_features/eip7251/fork.md index dda5c7ee6..479b592f8 100644 --- a/specs/_features/eip7251/fork.md +++ b/specs/_features/eip7251/fork.md @@ -134,7 +134,6 @@ def upgrade_to_eip7251(pre: deneb.BeaconState) -> BeaconState: if validator.activation_epoch == FAR_FUTURE_EPOCH ], key=lambda index: ( post.validators[index].activation_eligibility_epoch, - post.validators[index].effective_balance < MIN_ACTIVATION_BALANCE, index )) for index in pre_activation: From 805c0e18946f23dc9d508d76dc570bc9c5840228 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Wed, 10 Apr 2024 13:31:59 -0500 Subject: [PATCH 4/4] Reclaim Lost Epochs --- specs/_features/eip7251/fork.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/specs/_features/eip7251/fork.md b/specs/_features/eip7251/fork.md index 479b592f8..bd2b6e57c 100644 --- a/specs/_features/eip7251/fork.md +++ b/specs/_features/eip7251/fork.md @@ -136,7 +136,20 @@ def upgrade_to_eip7251(pre: deneb.BeaconState) -> BeaconState: post.validators[index].activation_eligibility_epoch, index )) - for index in pre_activation: + + activation_churn_limit = get_validator_activation_churn_limit(post) + adjusted_validators = 0 + adjusted_epoch = get_current_epoch(post) - 1 + for i, index in enumerate(pre_activation): + if i >= activation_churn_limit * 4 + break + if post.validators[index].activation_eligibility_epoch > post.finalized_checkpoint.epoch + break + post.validators[index].activation_eligibility_epoch = + adjusted_epoch + (i // activation_churn_limit) + adjusted_validators += 1 + + for index in pre_activation[adjusted_validators:]: queue_entire_balance_and_reset_validator(post, ValidatorIndex(index)) # Ensure early adopters of compounding credentials go through the activation churn