From cda10d059b61bc610493509803120e92c1bdf85b Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Wed, 27 Mar 2024 16:49:12 +0600 Subject: [PATCH 01/11] Refactor EL withdraw request processing --- specs/_features/eip7251/beacon-chain.md | 29 +++++++++++++++++-------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/specs/_features/eip7251/beacon-chain.md b/specs/_features/eip7251/beacon-chain.md index c4aad0a6f8..19fb7a91dc 100644 --- a/specs/_features/eip7251/beacon-chain.md +++ b/specs/_features/eip7251/beacon-chain.md @@ -8,6 +8,7 @@ - [Introduction](#introduction) - [Constants](#constants) + - [Misc](#misc) - [Withdrawal prefixes](#withdrawal-prefixes) - [Domains](#domains) - [Presets](#presets) @@ -87,6 +88,12 @@ See [a modest proposal](https://notes.ethereum.org/@mikeneuder/increase-maxeb), The following values are (non-configurable) constants used throughout the specification. +### Misc + +| Name | Value | +| - | - | +| `FULL_EXIT_REQUEST_AMOUNT` | `uint64(2**64 - 1)` | + ### Withdrawal prefixes | Name | Value | @@ -866,7 +873,8 @@ def process_execution_layer_withdraw_request( execution_layer_withdraw_request: ExecutionLayerWithdrawRequest ) -> None: amount = execution_layer_withdraw_request.amount - is_full_exit_request = amount == 0 + is_full_exit_request = amount == FULL_EXIT_REQUEST_AMOUNT + # If partial withdrawal queue is full, only full exits are processed if len(state.pending_partial_withdrawals) >= PENDING_PARTIAL_WITHDRAWALS_LIMIT and not is_full_exit_request: return @@ -888,20 +896,23 @@ def process_execution_layer_withdraw_request( and get_current_epoch(state) >= validator.activation_epoch + SHARD_COMMITTEE_PERIOD ): return - # New condition: only allow partial withdrawals with compounding withdrawal credentials - if not (is_full_exit_request or has_compounding_withdrawal_credential(validator)): - return pending_balance_to_withdraw = sum( item.amount for item in state.pending_partial_withdrawals if item.index == index ) - # only exit validator if it has no pending withdrawals in the queue - if is_full_exit_request and pending_balance_to_withdraw > 0: - return if is_full_exit_request: - initiate_validator_exit(state, index) - elif state.balances[index] > MIN_ACTIVATION_BALANCE + pending_balance_to_withdraw: + # Only exit validator if it has no pending withdrawals in the queue + if pending_balance_to_withdraw == 0: + initiate_validator_exit(state, index) + + return + + + has_excess_balance = state.balances[index] > MIN_ACTIVATION_BALANCE + pending_balance_to_withdraw + + # Only allow partial withdrawals with compounding withdrawal credentials + if has_compounding_withdrawal_credential(validator) and has_excess_balance: to_withdraw = min( state.balances[index] - MIN_ACTIVATION_BALANCE - pending_balance_to_withdraw, amount From 6f5cc4baf5e6b8cb9b753085fb9738c540147b8a Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Wed, 27 Mar 2024 17:35:27 +0600 Subject: [PATCH 02/11] Replace MIN_ACTIVATION_BALANCE with MAX_EFFECTIVE_BALANCE --- specs/_features/eip7251/beacon-chain.md | 28 +++++++++---------------- 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/specs/_features/eip7251/beacon-chain.md b/specs/_features/eip7251/beacon-chain.md index 19fb7a91dc..b7c2ffdb16 100644 --- a/specs/_features/eip7251/beacon-chain.md +++ b/specs/_features/eip7251/beacon-chain.md @@ -373,7 +373,7 @@ def get_validator_max_effective_balance(validator: Validator) -> Gwei: if has_compounding_withdrawal_credential(validator): return MAX_EFFECTIVE_BALANCE_EIP7251 else: - return MIN_ACTIVATION_BALANCE + return MAX_EFFECTIVE_BALANCE ``` #### New `get_churn_limit` @@ -411,12 +411,8 @@ def get_consolidation_churn_limit(state: BeaconState) -> Gwei: ```python def get_active_balance(state: BeaconState, validator_index: ValidatorIndex) -> Gwei: - active_balance_ceil = ( - MIN_ACTIVATION_BALANCE - if has_eth1_withdrawal_credential(state.validators[validator_index]) - else MAX_EFFECTIVE_BALANCE_EIP7251 - ) - return min(state.balances[validator_index], active_balance_ceil) + max_effective_balance = get_validator_max_effective_balance(state.validators[validator_index]) + return min(state.balances[validator_index], max_effective_balance) ``` ### Beacon state mutators @@ -649,16 +645,12 @@ def process_effective_balance_updates(state: BeaconState) -> None: HYSTERESIS_INCREMENT = uint64(EFFECTIVE_BALANCE_INCREMENT // HYSTERESIS_QUOTIENT) DOWNWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_DOWNWARD_MULTIPLIER UPWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_UPWARD_MULTIPLIER - EFFECTIVE_BALANCE_LIMIT = ( - MAX_EFFECTIVE_BALANCE_EIP7251 if has_compounding_withdrawal_credential(validator) - else MIN_ACTIVATION_BALANCE - ) - + max_effective_balance = get_validator_max_effective_balance(validator) if ( balance + DOWNWARD_THRESHOLD < validator.effective_balance or validator.effective_balance + UPWARD_THRESHOLD < balance ): - validator.effective_balance = min(balance - balance % EFFECTIVE_BALANCE_INCREMENT, EFFECTIVE_BALANCE_LIMIT) + validator.effective_balance = min(balance - balance % EFFECTIVE_BALANCE_INCREMENT, max_effective_balance) # [Modified in EIP7251] ``` ### Block processing @@ -689,8 +681,8 @@ def get_expected_withdrawals(state: BeaconState) -> Tuple[Sequence[Withdrawal], break validator = state.validators[withdrawal.index] - if validator.exit_epoch == FAR_FUTURE_EPOCH and state.balances[withdrawal.index] > MIN_ACTIVATION_BALANCE: - withdrawable_balance = min(state.balances[withdrawal.index] - MIN_ACTIVATION_BALANCE, withdrawal.amount) + if validator.exit_epoch == FAR_FUTURE_EPOCH and state.balances[withdrawal.index] > MAX_EFFECTIVE_BALANCE: + withdrawable_balance = min(state.balances[withdrawal.index] - MAX_EFFECTIVE_BALANCE, withdrawal.amount) withdrawals.append(Withdrawal( index=withdrawal_index, validator_index=withdrawal.index, @@ -909,12 +901,12 @@ def process_execution_layer_withdraw_request( return - has_excess_balance = state.balances[index] > MIN_ACTIVATION_BALANCE + pending_balance_to_withdraw + has_excess_balance = state.balances[index] > MAX_EFFECTIVE_BALANCE + pending_balance_to_withdraw # Only allow partial withdrawals with compounding withdrawal credentials if has_compounding_withdrawal_credential(validator) and has_excess_balance: to_withdraw = min( - state.balances[index] - MIN_ACTIVATION_BALANCE - pending_balance_to_withdraw, + state.balances[index] - MAX_EFFECTIVE_BALANCE - pending_balance_to_withdraw, amount ) exit_queue_epoch = compute_exit_epoch_and_update_churn(state, to_withdraw) @@ -935,7 +927,7 @@ def process_consolidation(state: BeaconState, signed_consolidation: SignedConsol # If the pending consolidations queue is full, no consolidations are allowed in the block assert len(state.pending_consolidations) < PENDING_CONSOLIDATIONS_LIMIT # If there is too little available consolidation churn limit, no consolidations are allowed in the block - assert get_consolidation_churn_limit(state) > MIN_ACTIVATION_BALANCE + assert get_consolidation_churn_limit(state) > MAX_EFFECTIVE_BALANCE consolidation = signed_consolidation.message # Verify that source != target, so a consolidation cannot be used as an exit. assert consolidation.source_index != consolidation.target_index From 31142b0ba18572c888618bd8ef87deb1dd96bc92 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Wed, 27 Mar 2024 17:41:00 +0600 Subject: [PATCH 03/11] Require sufficient EB to emit partial withdrawal --- specs/_features/eip7251/beacon-chain.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/specs/_features/eip7251/beacon-chain.md b/specs/_features/eip7251/beacon-chain.md index b7c2ffdb16..2035180af8 100644 --- a/specs/_features/eip7251/beacon-chain.md +++ b/specs/_features/eip7251/beacon-chain.md @@ -681,7 +681,9 @@ def get_expected_withdrawals(state: BeaconState) -> Tuple[Sequence[Withdrawal], break validator = state.validators[withdrawal.index] - if validator.exit_epoch == FAR_FUTURE_EPOCH and state.balances[withdrawal.index] > MAX_EFFECTIVE_BALANCE: + has_sufficient_effective_balance = validator.effective_balance == MAX_EFFECTIVE_BALANCE + has_excess_balance = state.balances[withdrawal.index] > MAX_EFFECTIVE_BALANCE + if validator.exit_epoch == FAR_FUTURE_EPOCH and has_sufficient_effective_balance and has_excess_balance: withdrawable_balance = min(state.balances[withdrawal.index] - MAX_EFFECTIVE_BALANCE, withdrawal.amount) withdrawals.append(Withdrawal( index=withdrawal_index, @@ -901,10 +903,11 @@ def process_execution_layer_withdraw_request( return + has_sufficient_effective_balance = validator.effective_balance == MAX_EFFECTIVE_BALANCE has_excess_balance = state.balances[index] > MAX_EFFECTIVE_BALANCE + pending_balance_to_withdraw # Only allow partial withdrawals with compounding withdrawal credentials - if has_compounding_withdrawal_credential(validator) and has_excess_balance: + if has_compounding_withdrawal_credential(validator) and has_sufficient_effective_balance and has_excess_balance: to_withdraw = min( state.balances[index] - MAX_EFFECTIVE_BALANCE - pending_balance_to_withdraw, amount From 46638d31baf38b5d2b8178b7b51343822438b548 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Wed, 27 Mar 2024 17:42:10 +0600 Subject: [PATCH 04/11] Remove unused method --- specs/_features/eip7251/beacon-chain.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/specs/_features/eip7251/beacon-chain.md b/specs/_features/eip7251/beacon-chain.md index 2035180af8..e8c4e8a511 100644 --- a/specs/_features/eip7251/beacon-chain.md +++ b/specs/_features/eip7251/beacon-chain.md @@ -46,7 +46,6 @@ - [New `get_active_balance`](#new-get_active_balance) - [Beacon state mutators](#beacon-state-mutators) - [Updated `initiate_validator_exit`](#updated--initiate_validator_exit) - - [New `set_compounding_withdrawal_credentials`](#new-set_compounding_withdrawal_credentials) - [New `switch_to_compounding_validator`](#new-switch_to_compounding_validator) - [New `queue_excess_active_balance`](#new-queue_excess_active_balance) - [New `compute_exit_epoch_and_update_churn`](#new-compute_exit_epoch_and_update_churn) @@ -437,15 +436,6 @@ def initiate_validator_exit(state: BeaconState, index: ValidatorIndex) -> None: validator.withdrawable_epoch = Epoch(validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY) ``` -#### New `set_compounding_withdrawal_credentials` - -```python -def set_compounding_withdrawal_credentials(state: BeaconState, index: ValidatorIndex) -> None: - validator = state.validators[index] - if has_eth1_withdrawal_credential(validator): - validator.withdrawal_credentials[:1] = COMPOUNDING_WITHDRAWAL_PREFIX -``` - #### New `switch_to_compounding_validator` ```python From 517f741f29a53ff8068283dc5ac8f694b5d5cc58 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Wed, 27 Mar 2024 17:57:54 +0600 Subject: [PATCH 05/11] Abort voluntary exit if validator has pending partial withdrawals --- specs/_features/eip7251/beacon-chain.md | 42 ++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/specs/_features/eip7251/beacon-chain.md b/specs/_features/eip7251/beacon-chain.md index e8c4e8a511..3bd4615667 100644 --- a/specs/_features/eip7251/beacon-chain.md +++ b/specs/_features/eip7251/beacon-chain.md @@ -44,6 +44,7 @@ - [New `get_activation_exit_churn_limit`](#new-get_activation_exit_churn_limit) - [New `get_consolidation_churn_limit`](#new-get_consolidation_churn_limit) - [New `get_active_balance`](#new-get_active_balance) + - [New `get_pending_balance_to_withdraw`](#new-get_pending_balance_to_withdraw) - [Beacon state mutators](#beacon-state-mutators) - [Updated `initiate_validator_exit`](#updated--initiate_validator_exit) - [New `switch_to_compounding_validator`](#new-switch_to_compounding_validator) @@ -72,6 +73,8 @@ - [New `process_execution_layer_withdraw_request`](#new-process_execution_layer_withdraw_request) - [Consolidations](#consolidations) - [New `process_consolidation`](#new-process_consolidation) + - [Voluntary exits](#voluntary-exits) + - [Updated `process_voluntary_exit`](#updated-process_voluntary_exit) @@ -414,6 +417,14 @@ def get_active_balance(state: BeaconState, validator_index: ValidatorIndex) -> G return min(state.balances[validator_index], max_effective_balance) ``` +#### New `get_pending_balance_to_withdraw` + +```python +def get_pending_balance_to_withdraw(state: BeaconState, validator_index: ValidatorIndex) -> Gwei: + return sum( + withdrawal.amount for withdrawal in state.pending_partial_withdrawals if withdrawal.index == validator_index) +``` + ### Beacon state mutators #### Updated `initiate_validator_exit` @@ -762,7 +773,7 @@ def process_operations(state: BeaconState, body: BeaconBlockBody) -> None: for_ops(body.attester_slashings, process_attester_slashing) for_ops(body.attestations, process_attestation) for_ops(body.deposits, process_deposit) # [Modified in EIP7251] - for_ops(body.voluntary_exits, process_voluntary_exit) + for_ops(body.voluntary_exits, process_voluntary_exit) # [Modified in EIP7251] for_ops(body.bls_to_execution_changes, process_bls_to_execution_change) for_ops(body.execution_payload.withdraw_requests, process_execution_layer_withdraw_request) # New in EIP7251 for_ops(body.consolidations, process_consolidation) # New in EIP7251 @@ -881,9 +892,7 @@ def process_execution_layer_withdraw_request( ): return - pending_balance_to_withdraw = sum( - item.amount for item in state.pending_partial_withdrawals if item.index == index - ) + pending_balance_to_withdraw = get_pending_balance_to_withdraw(state, index) if is_full_exit_request: # Only exit validator if it has no pending withdrawals in the queue @@ -961,3 +970,28 @@ def process_consolidation(state: BeaconState, signed_consolidation: SignedConsol )) ``` +##### Voluntary exits + +###### Updated `process_voluntary_exit` + +```python +def process_voluntary_exit(state: BeaconState, signed_voluntary_exit: SignedVoluntaryExit) -> None: + voluntary_exit = signed_voluntary_exit.message + validator = state.validators[voluntary_exit.validator_index] + # Verify the validator is active + assert is_active_validator(validator, get_current_epoch(state)) + # Verify exit has not been initiated + assert validator.exit_epoch == FAR_FUTURE_EPOCH + # Exits must specify an epoch when they become valid; they are not valid before then + assert get_current_epoch(state) >= voluntary_exit.epoch + # Verify the validator has been active long enough + assert get_current_epoch(state) >= validator.activation_epoch + SHARD_COMMITTEE_PERIOD + # Verify signature + domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, voluntary_exit.epoch) + signing_root = compute_signing_root(voluntary_exit, domain) + assert bls.Verify(validator.pubkey, signing_root, signed_voluntary_exit.signature) + # Only exit validator if it has no pending withdrawals in the queue + assert get_pending_balance_to_withdraw(state, voluntary_exit.validator_index) == 0 # [New in EIP7251] + # Initiate exit + initiate_validator_exit(state, voluntary_exit.validator_index) +``` \ No newline at end of file From 915f90e13eddf4ddfcc38b3b1b3d89a91d10b86c Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Wed, 27 Mar 2024 18:05:05 +0600 Subject: [PATCH 06/11] Strictly check withdrawal address upon consolidation --- specs/_features/eip7251/beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/_features/eip7251/beacon-chain.md b/specs/_features/eip7251/beacon-chain.md index 3bd4615667..366eabe4c8 100644 --- a/specs/_features/eip7251/beacon-chain.md +++ b/specs/_features/eip7251/beacon-chain.md @@ -950,7 +950,7 @@ def process_consolidation(state: BeaconState, signed_consolidation: SignedConsol assert has_execution_withdrawal_credential(source_validator) assert has_execution_withdrawal_credential(target_validator) # Verify the same withdrawal address - assert source_validator.withdrawal_credentials[1:] == target_validator.withdrawal_credentials[1:] + assert source_validator.withdrawal_credentials[12:] == target_validator.withdrawal_credentials[12:] # Verify consolidation is signed by the source and the target domain = compute_domain(DOMAIN_CONSOLIDATION, genesis_validators_root=state.genesis_validators_root) From 534bcfc116980efe92a032115f883e79d4825393 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Thu, 28 Mar 2024 11:49:44 +0600 Subject: [PATCH 07/11] Use source.effective_balance for consolidaiton churn --- specs/_features/eip7251/beacon-chain.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/_features/eip7251/beacon-chain.md b/specs/_features/eip7251/beacon-chain.md index 366eabe4c8..a0bc3bc8d4 100644 --- a/specs/_features/eip7251/beacon-chain.md +++ b/specs/_features/eip7251/beacon-chain.md @@ -959,8 +959,8 @@ def process_consolidation(state: BeaconState, signed_consolidation: SignedConsol assert bls.FastAggregateVerify(pubkeys, signing_root, signed_consolidation.signature) # Initiate source validator exit and append pending consolidation - active_balance = get_active_balance(state, consolidation.source_index) - source_validator.exit_epoch = compute_consolidation_epoch_and_update_churn(state, active_balance) + source_validator.exit_epoch = compute_consolidation_epoch_and_update_churn( + state, source_validator.effective_balance) source_validator.withdrawable_epoch = Epoch( source_validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY ) From 7bbecfb7625ce1411d4cf902a9dc54be0f76165d Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Fri, 29 Mar 2024 15:27:12 +0600 Subject: [PATCH 08/11] Revert "Replace MIN_ACTIVATION_BALANCE with MAX_EFFECTIVE_BALANCE" This reverts commit 6f5cc4baf5e6b8cb9b753085fb9738c540147b8a. --- specs/_features/eip7251/beacon-chain.md | 32 +++++++++++++++---------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/specs/_features/eip7251/beacon-chain.md b/specs/_features/eip7251/beacon-chain.md index a0bc3bc8d4..db6d7601a8 100644 --- a/specs/_features/eip7251/beacon-chain.md +++ b/specs/_features/eip7251/beacon-chain.md @@ -375,7 +375,7 @@ def get_validator_max_effective_balance(validator: Validator) -> Gwei: if has_compounding_withdrawal_credential(validator): return MAX_EFFECTIVE_BALANCE_EIP7251 else: - return MAX_EFFECTIVE_BALANCE + return MIN_ACTIVATION_BALANCE ``` #### New `get_churn_limit` @@ -413,8 +413,12 @@ def get_consolidation_churn_limit(state: BeaconState) -> Gwei: ```python def get_active_balance(state: BeaconState, validator_index: ValidatorIndex) -> Gwei: - max_effective_balance = get_validator_max_effective_balance(state.validators[validator_index]) - return min(state.balances[validator_index], max_effective_balance) + active_balance_ceil = ( + MIN_ACTIVATION_BALANCE + if has_eth1_withdrawal_credential(state.validators[validator_index]) + else MAX_EFFECTIVE_BALANCE_EIP7251 + ) + return min(state.balances[validator_index], active_balance_ceil) ``` #### New `get_pending_balance_to_withdraw` @@ -646,12 +650,16 @@ def process_effective_balance_updates(state: BeaconState) -> None: HYSTERESIS_INCREMENT = uint64(EFFECTIVE_BALANCE_INCREMENT // HYSTERESIS_QUOTIENT) DOWNWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_DOWNWARD_MULTIPLIER UPWARD_THRESHOLD = HYSTERESIS_INCREMENT * HYSTERESIS_UPWARD_MULTIPLIER - max_effective_balance = get_validator_max_effective_balance(validator) + EFFECTIVE_BALANCE_LIMIT = ( + MAX_EFFECTIVE_BALANCE_EIP7251 if has_compounding_withdrawal_credential(validator) + else MIN_ACTIVATION_BALANCE + ) + if ( balance + DOWNWARD_THRESHOLD < validator.effective_balance or validator.effective_balance + UPWARD_THRESHOLD < balance ): - validator.effective_balance = min(balance - balance % EFFECTIVE_BALANCE_INCREMENT, max_effective_balance) # [Modified in EIP7251] + validator.effective_balance = min(balance - balance % EFFECTIVE_BALANCE_INCREMENT, EFFECTIVE_BALANCE_LIMIT) ``` ### Block processing @@ -682,10 +690,10 @@ def get_expected_withdrawals(state: BeaconState) -> Tuple[Sequence[Withdrawal], break validator = state.validators[withdrawal.index] - has_sufficient_effective_balance = validator.effective_balance == MAX_EFFECTIVE_BALANCE - has_excess_balance = state.balances[withdrawal.index] > MAX_EFFECTIVE_BALANCE + has_sufficient_effective_balance = validator.effective_balance == MIN_ACTIVATION_BALANCE + has_excess_balance = state.balances[withdrawal.index] > MIN_ACTIVATION_BALANCE if validator.exit_epoch == FAR_FUTURE_EPOCH and has_sufficient_effective_balance and has_excess_balance: - withdrawable_balance = min(state.balances[withdrawal.index] - MAX_EFFECTIVE_BALANCE, withdrawal.amount) + withdrawable_balance = min(state.balances[withdrawal.index] - MIN_ACTIVATION_BALANCE, withdrawal.amount) withdrawals.append(Withdrawal( index=withdrawal_index, validator_index=withdrawal.index, @@ -902,13 +910,13 @@ def process_execution_layer_withdraw_request( return - has_sufficient_effective_balance = validator.effective_balance == MAX_EFFECTIVE_BALANCE - has_excess_balance = state.balances[index] > MAX_EFFECTIVE_BALANCE + pending_balance_to_withdraw + has_sufficient_effective_balance = validator.effective_balance == MIN_ACTIVATION_BALANCE + has_excess_balance = state.balances[index] > MIN_ACTIVATION_BALANCE + pending_balance_to_withdraw # Only allow partial withdrawals with compounding withdrawal credentials if has_compounding_withdrawal_credential(validator) and has_sufficient_effective_balance and has_excess_balance: to_withdraw = min( - state.balances[index] - MAX_EFFECTIVE_BALANCE - pending_balance_to_withdraw, + state.balances[index] - MIN_ACTIVATION_BALANCE - pending_balance_to_withdraw, amount ) exit_queue_epoch = compute_exit_epoch_and_update_churn(state, to_withdraw) @@ -929,7 +937,7 @@ def process_consolidation(state: BeaconState, signed_consolidation: SignedConsol # If the pending consolidations queue is full, no consolidations are allowed in the block assert len(state.pending_consolidations) < PENDING_CONSOLIDATIONS_LIMIT # If there is too little available consolidation churn limit, no consolidations are allowed in the block - assert get_consolidation_churn_limit(state) > MAX_EFFECTIVE_BALANCE + assert get_consolidation_churn_limit(state) > MIN_ACTIVATION_BALANCE consolidation = signed_consolidation.message # Verify that source != target, so a consolidation cannot be used as an exit. assert consolidation.source_index != consolidation.target_index From 221f273e14aff0356d1b98ac1920dcc7dd523765 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Fri, 29 Mar 2024 22:35:12 +0600 Subject: [PATCH 09/11] Fix lint --- specs/_features/eip7251/beacon-chain.md | 1 - 1 file changed, 1 deletion(-) diff --git a/specs/_features/eip7251/beacon-chain.md b/specs/_features/eip7251/beacon-chain.md index db6d7601a8..845ff1b968 100644 --- a/specs/_features/eip7251/beacon-chain.md +++ b/specs/_features/eip7251/beacon-chain.md @@ -909,7 +909,6 @@ def process_execution_layer_withdraw_request( return - has_sufficient_effective_balance = validator.effective_balance == MIN_ACTIVATION_BALANCE has_excess_balance = state.balances[index] > MIN_ACTIVATION_BALANCE + pending_balance_to_withdraw From 4f8fb6f7162e4559a4d051b0cf6996e125911806 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Thu, 4 Apr 2024 14:49:25 +0300 Subject: [PATCH 10/11] Update specs/_features/eip7251/beacon-chain.md Co-authored-by: fradamt <104826920+fradamt@users.noreply.github.com> --- specs/_features/eip7251/beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/_features/eip7251/beacon-chain.md b/specs/_features/eip7251/beacon-chain.md index 845ff1b968..662d851c4b 100644 --- a/specs/_features/eip7251/beacon-chain.md +++ b/specs/_features/eip7251/beacon-chain.md @@ -909,7 +909,7 @@ def process_execution_layer_withdraw_request( return - has_sufficient_effective_balance = validator.effective_balance == MIN_ACTIVATION_BALANCE + has_sufficient_effective_balance = validator.effective_balance >= MIN_ACTIVATION_BALANCE has_excess_balance = state.balances[index] > MIN_ACTIVATION_BALANCE + pending_balance_to_withdraw # Only allow partial withdrawals with compounding withdrawal credentials From ace9db9aa9a75ff1231a9631af598728d311763b Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Fri, 5 Apr 2024 15:35:06 +0300 Subject: [PATCH 11/11] Set FULL_EXIT_REQUEST_AMOUNT to 0 --- specs/_features/eip7251/beacon-chain.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/_features/eip7251/beacon-chain.md b/specs/_features/eip7251/beacon-chain.md index 662d851c4b..852742a643 100644 --- a/specs/_features/eip7251/beacon-chain.md +++ b/specs/_features/eip7251/beacon-chain.md @@ -94,7 +94,7 @@ The following values are (non-configurable) constants used throughout the specif | Name | Value | | - | - | -| `FULL_EXIT_REQUEST_AMOUNT` | `uint64(2**64 - 1)` | +| `FULL_EXIT_REQUEST_AMOUNT` | `uint64(0)` | ### Withdrawal prefixes @@ -1001,4 +1001,4 @@ def process_voluntary_exit(state: BeaconState, signed_voluntary_exit: SignedVolu assert get_pending_balance_to_withdraw(state, voluntary_exit.validator_index) == 0 # [New in EIP7251] # Initiate exit initiate_validator_exit(state, voluntary_exit.validator_index) -``` \ No newline at end of file +```