diff --git a/presets/mainnet/capella.yaml b/presets/mainnet/capella.yaml index 7d9da914e..c5dfe1d4b 100644 --- a/presets/mainnet/capella.yaml +++ b/presets/mainnet/capella.yaml @@ -1 +1 @@ -# Minimal preset - Sharding +# Minimal preset - Capella diff --git a/presets/minimal/capella.yaml b/presets/minimal/capella.yaml index 7d9da914e..c5dfe1d4b 100644 --- a/presets/minimal/capella.yaml +++ b/presets/minimal/capella.yaml @@ -1 +1 @@ -# Minimal preset - Sharding +# Minimal preset - Capella diff --git a/specs/capella/beacon-chain.md b/specs/capella/beacon-chain.md index bb085a2b5..808b52a95 100644 --- a/specs/capella/beacon-chain.md +++ b/specs/capella/beacon-chain.md @@ -1,4 +1,4 @@ -# Cappela -- The Beacon Chain +# Capella -- The Beacon Chain ## Table of contents @@ -11,7 +11,7 @@ ## Introduction -Cappela is a consensus-layer upgrade containin a number of features related +Capella is a consensus-layer upgrade containin a number of features related to validator withdrawals. Including: * Automatic withdrawals of `withdrawable` validators * Partial withdrawals during block proposal @@ -40,6 +40,23 @@ to validator withdrawals. Including: ### Extended Containers +#### `Validator` + +```python +class Validator(Container): + pubkey: BLSPubkey + withdrawal_credentials: Bytes32 # Commitment to pubkey for withdrawals + effective_balance: Gwei # Balance at stake + slashed: boolean + # Status epochs + activation_eligibility_epoch: Epoch # When criteria for activation were met + activation_epoch: Epoch + exit_epoch: Epoch + withdrawable_epoch: Epoch # When validator can withdraw funds + withdrawn_epoch: Epoch # [New in Capella] +``` + + #### `BeaconState` ```python @@ -81,7 +98,7 @@ class BeaconState(Container): # Execution latest_execution_payload_header: ExecutionPayloadHeader # Withdrawals - withdrawal_receipts: List[WithdrawalReceipt, WITHDRAWAL_RECEIPT_LIMIT] # [New in Cappela] + withdrawal_receipts: List[WithdrawalReceipt, WITHDRAWAL_RECEIPT_LIMIT] # [New in Capella] ``` ### New containers @@ -144,7 +161,7 @@ def process_epoch(state: BeaconState) -> None: process_historical_roots_update(state) process_participation_flag_updates(state) process_sync_committee_updates(state) - process_withdrawals(state) # [New in Cappela] + process_withdrawals(state) # [New in Capella] ``` #### Withdrawals @@ -160,4 +177,5 @@ def process_withdrawals(state: BeaconState) -> None: is_eth1_withdrawal_prefix = validator.withdrawal_credentials[0] == ETH1_ADDRESS_WITHDRAWAL_PREFIX if is_balance_nonzero and is_eth1_withdrawal_prefix and is_withdrawable_validator(validator, current_epoch): withdraw(state, ValidatorIndex(index), balance) + validator.withdrawn_epoch = current_epoch ``` diff --git a/specs/capella/fork.md b/specs/capella/fork.md index e4c6549f7..f52512877 100644 --- a/specs/capella/fork.md +++ b/specs/capella/fork.md @@ -61,7 +61,7 @@ def upgrade_to_capella(pre: merge.BeaconState) -> BeaconState: eth1_data_votes=pre.eth1_data_votes, eth1_deposit_index=pre.eth1_deposit_index, # Registry - validators=pre.validators, + validators=[], balances=pre.balances, # Randomness randao_mixes=pre.randao_mixes, @@ -86,5 +86,19 @@ def upgrade_to_capella(pre: merge.BeaconState) -> BeaconState: withdrawal_receipts=[], ) + for pre_validator in pre.validators: + post_validator = Validator( + pubkey=pre_validator.pubkey, + withdrawal_credentials=pre_validator.withdrawal_credentials, + effective_balance=pre_validator.effective_balance, + slashed=pre_validator.slashed, + activation_eligibility_epoch=pre_validator.activation_eligibility_epoch, + activation_epoch=pre_validator.activation_epoch, + exit_epoch=pre_validator.exit_epoch, + withdrawable_epoch=pre_validator.withdrawable_epoch, + withdrawn_epoch=FAR_FUTURE_EPOCH, + ) + post.validators.append(post_validator) + return post ``` diff --git a/tests/core/pyspec/eth2spec/test/helpers/capella/fork.py b/tests/core/pyspec/eth2spec/test/helpers/capella/fork.py index f5905178e..e8c41b76a 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/capella/fork.py +++ b/tests/core/pyspec/eth2spec/test/helpers/capella/fork.py @@ -16,7 +16,7 @@ def run_fork_test(post_spec, pre_state): # Eth1 'eth1_data', 'eth1_data_votes', 'eth1_deposit_index', # Registry - 'validators', 'balances', + 'balances', # Randomness 'randao_mixes', # Slashings @@ -36,10 +36,22 @@ def run_fork_test(post_spec, pre_state): assert getattr(pre_state, field) == getattr(post_state, field) # Modified fields - modified_fields = ['fork'] + modified_fields = ['fork', 'validators'] for field in modified_fields: assert getattr(pre_state, field) != getattr(post_state, field) + assert len(pre_state.validators) == len(post_state.validators) + for pre_validator, post_validator in zip(pre_state.validators, post_state.validators): + stable_validator_fields = [ + 'pubkey', 'withdrawal_credentials', + 'effective_balance', + 'slashed', + 'activation_eligibility_epoch', 'activation_epoch', 'exit_epoch', 'withdrawable_epoch' + ] + for field in stable_validator_fields: + assert getattr(pre_validator, field) == getattr(post_validator, field) + assert post_validator.withdrawn_epoch == post_spec.FAR_FUTURE_EPOCH + assert pre_state.fork.current_version == post_state.fork.previous_version assert post_state.fork.current_version == post_spec.config.CAPELLA_FORK_VERSION assert post_state.fork.epoch == post_spec.get_current_epoch(post_state)