Skip to content

Commit

Permalink
Allow to switch to compounding validator on deposit
Browse files Browse the repository at this point in the history
  • Loading branch information
dapplion committed Mar 26, 2024
1 parent 83e617a commit 23ad85e
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 19 deletions.
73 changes: 63 additions & 10 deletions specs/_features/eip7251/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
- [Helpers](#helpers)
- [Predicates](#predicates)
- [Updated `is_eligible_for_activation_queue`](#updated-is_eligible_for_activation_queue)
- [New `is_compounding_withdrawal_credential`](#new-is_compounding_withdrawal_credential)
- [New `has_compounding_withdrawal_credential`](#new-has_compounding_withdrawal_credential)
- [New `has_execution_withdrawal_credential`](#new-has_execution_withdrawal_credential)
- [Updated `is_fully_withdrawable_validator`](#updated-is_fully_withdrawable_validator)
Expand All @@ -45,6 +46,8 @@
- [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)
- [New `compute_consolidation_epoch_and_update_churn`](#new-compute_consolidation_epoch_and_update_churn)
- [Updated `slash_validator`](#updated-slash_validator)
Expand All @@ -62,7 +65,8 @@
- [Updated `process_operations`](#updated-process_operations)
- [Deposits](#deposits)
- [Updated `apply_deposit`](#updated--apply_deposit)
- [Modified `add_validator_to_registry`](#modified-add_validator_to_registry)
- [New `is_valid_deposit_signature`](#new-is_valid_deposit_signature)
- [Modified `add_validator_to_registry`](#modified-add_validator_to_registry)
- [Updated `get_validator_from_deposit`](#updated-get_validator_from_deposit)
- [Withdrawals](#withdrawals)
- [New `process_execution_layer_withdraw_request`](#new-process_execution_layer_withdraw_request)
Expand Down Expand Up @@ -292,14 +296,21 @@ def is_eligible_for_activation_queue(validator: Validator) -> bool:
)
```

#### New `is_compounding_withdrawal_credential`

```python
def is_compounding_withdrawal_credential(withdrawal_credentials: Bytes32) -> bool:
return withdrawal_credentials[:1] == COMPOUNDING_WITHDRAWAL_PREFIX
```

#### New `has_compounding_withdrawal_credential`

```python
def has_compounding_withdrawal_credential(validator: Validator) -> bool:
"""
Check if ``validator`` has an 0x02 prefixed "compounding" withdrawal credential.
"""
return validator.withdrawal_credentials[:1] == COMPOUNDING_WITHDRAWAL_PREFIX
return is_compounding_withdrawal_credential(validator.withdrawal_credentials)
```

#### New `has_execution_withdrawal_credential`
Expand Down Expand Up @@ -429,6 +440,29 @@ def set_compounding_withdrawal_credentials(state: BeaconState, index: ValidatorI
validator.withdrawal_credentials[:1] = COMPOUNDING_WITHDRAWAL_PREFIX
```

#### New `switch_to_compounding_validator`

```python
def switch_to_compounding_validator(state: BeaconState, index: ValidatorIndex) -> None:
validator = state.validators[index]
if has_eth1_withdrawal_credential(validator):
validator.withdrawal_credentials[:1] = COMPOUNDING_WITHDRAWAL_PREFIX
queue_excess_active_balance(state, index)
```

#### New `queue_excess_active_balance`

```python
def queue_excess_active_balance(state: BeaconState, index: ValidatorIndex) -> None:
balance = state.balances[index]
if balance > MAX_EFFECTIVE_BALANCE:
excess_balance = balance - MAX_EFFECTIVE_BALANCE
state.balances[index] = balance - excess_balance
state.pending_balance_deposits.append(
PendingBalanceDeposit(index=index, amount=excess_balance)
)
```

#### New `compute_exit_epoch_and_update_churn`


Expand Down Expand Up @@ -584,11 +618,12 @@ def process_pending_consolidations(state: BeaconState) -> None:
if source_validator.withdrawable_epoch > get_current_epoch(state):
break

# Churn any target excess active balance of target and raise its max
switch_to_compounding_validator(state, pending_consolidation.target_index)
# Move active balance to target. Excess balance is withdrawable.
active_balance = get_active_balance(state, pending_consolidation.source_index)
decrease_balance(state, pending_consolidation.source_index, active_balance)
increase_balance(state, pending_consolidation.target_index, active_balance)
set_compounding_withdrawal_credentials(state, pending_consolidation.target_index)
next_pending_consolidation += 1

state.pending_consolidations = state.pending_consolidations[next_pending_consolidation:]
Expand Down Expand Up @@ -752,22 +787,40 @@ def apply_deposit(state: BeaconState,
validator_pubkeys = [v.pubkey for v in state.validators]
if pubkey not in validator_pubkeys:
# Verify the deposit signature (proof of possession) which is not checked by the deposit contract
if is_valid_deposit_signature(pubkey, withdrawal_credentials, amount, signature):
add_validator_to_registry(state, pubkey, withdrawal_credentials, amount)
else:
# Increase balance by deposit amount
index = ValidatorIndex(validator_pubkeys.index(pubkey))
state.pending_balance_deposits.append(PendingBalanceDeposit(index=index, amount=amount)) # [Modified in EIP-7251]
# Check if valid deposit switch to compounding credentials
if (
is_compounding_withdrawal_credential(withdrawal_credentials)
and has_eth1_withdrawal_credential(state.validators[index])
and is_valid_deposit_signature(pubkey, withdrawal_credentials, amount, signature)
):
switch_to_compounding_validator(state, index)

```

###### New `is_valid_deposit_signature`

```python
def is_valid_deposit_signature(pubkey: BLSPubkey,
withdrawal_credentials: Bytes32,
amount: uint64,
signature: BLSSignature) -> None:
deposit_message = DepositMessage(
pubkey=pubkey,
withdrawal_credentials=withdrawal_credentials,
amount=amount,
)
domain = compute_domain(DOMAIN_DEPOSIT) # Fork-agnostic domain since deposits are valid across forks
signing_root = compute_signing_root(deposit_message, domain)
if bls.Verify(pubkey, signing_root, signature):
add_validator_to_registry(state, pubkey, withdrawal_credentials, amount)
else:
# Increase balance by deposit amount
index = ValidatorIndex(validator_pubkeys.index(pubkey))
state.pending_balance_deposits.append(PendingBalanceDeposit(index=index, amount=amount)) # [Modified in EIP-7251]
return bls.Verify(pubkey, signing_root, signature)
```

#### Modified `add_validator_to_registry`
###### Modified `add_validator_to_registry`

```python
def add_validator_to_registry(state: BeaconState,
Expand Down
12 changes: 3 additions & 9 deletions specs/_features/eip7251/fork.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,16 +130,10 @@ def upgrade_to_eip7251(pre: deneb.BeaconState) -> BeaconState:

# Ensure early adopters of compounding credentials go through the activation churn
queue_excess_active_balance(post)
for index, validator in enumerate(state.validators):
if has_compounding_withdrawal_credential(validator):
queue_excess_active_balance(state, index)

return post
```

```python
def queue_excess_active_balance(state: BeaconState):
for index, validator in enumerate(state.validators):
balance = state.balances[index]
if has_compounding_withdrawal_credential(validator) and balance > MAX_EFFECTIVE_BALANCE:
excess_balance = balance - MAX_EFFECTIVE_BALANCE
state.balances[index] = balance - excess_balance
state.pending_balance_deposits.append(PendingBalanceDeposit(index=index, amount=excess_balance))
```

0 comments on commit 23ad85e

Please sign in to comment.