From 9cbc54401595a9c26c792e53858f821077ae66bc Mon Sep 17 00:00:00 2001 From: Rez Date: Tue, 8 Apr 2025 13:51:08 +1000 Subject: [PATCH 01/18] Annotated with Bera context Signed-off-by: Rez --- specs/electra/validator.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/specs/electra/validator.md b/specs/electra/validator.md index 280fd9e007..2dfa53c58b 100644 --- a/specs/electra/validator.md +++ b/specs/electra/validator.md @@ -46,7 +46,7 @@ Please see related Beacon Chain doc before continuing and use them as a referenc ## Helpers ### Modified `GetPayloadResponse` - +@BERA: BuiltExecutionPayloadEnv for Bectra has been implemented. ```python @dataclass class GetPayloadResponse(object): @@ -61,6 +61,7 @@ class GetPayloadResponse(object): ### Modified containers #### `AggregateAndProof` +@BERA: Skip as we don't implement EIP7549 ```python class AggregateAndProof(Container): @@ -70,6 +71,7 @@ class AggregateAndProof(Container): ``` #### `SignedAggregateAndProof` +@BERA: Skip as we don't implement EIP7549 ```python class SignedAggregateAndProof(Container): @@ -82,7 +84,7 @@ class SignedAggregateAndProof(Container): ### `ExecutionEngine` #### Modified `get_payload` - +@BERA: Implemented already Given the `payload_id`, `get_payload` returns the most recent version of the execution payload that has been built since the corresponding call to `notify_forkchoice_updated` method. @@ -100,10 +102,11 @@ def get_payload(self: ExecutionEngine, payload_id: PayloadId) -> GetPayloadRespo ### Constructing the `BeaconBlockBody` #### Attester slashings - +@BERA: Skip as we don't implement slashing Changed the max attester slashings size to `MAX_ATTESTER_SLASHINGS_ELECTRA`. #### Attestations +@BERA: Skip as we don't implement attestations Changed the max attestations size to `MAX_ATTESTATIONS_ELECTRA`. @@ -136,6 +139,7 @@ def compute_on_chain_aggregate(network_aggregates: Sequence[Attestation]) -> Att ``` #### Deposits +@BERA: Skip as we don't EIP6110 at the moment *[New in Electra:EIP6110]* The expected number of deposits MUST be changed from `min(MAX_DEPOSITS, eth1_data.deposit_count - state.eth1_deposit_index)` to the result of the following function: @@ -183,6 +187,7 @@ def get_eth1_vote(state: BeaconState, eth1_chain: Sequence[Eth1Block]) -> Eth1Da ``` #### Execution payload +@BERA: We must update `get_expected_withdrawals`. `prepare_execution_payload` is updated from the Deneb specs. @@ -219,6 +224,7 @@ def prepare_execution_payload(state: BeaconState, ``` #### Execution Requests +@BERA: Already implemented *[New in Electra]* @@ -274,6 +280,7 @@ def get_execution_requests(execution_requests_list: Sequence[bytes]) -> Executio ``` ### Constructing the `BlobSidecar`s +@BERA: Skip as we don't implement BlobSidecars #### Sidecar @@ -285,6 +292,7 @@ def compute_subnet_for_blob_sidecar(blob_index: BlobIndex) -> SubnetID: ``` ## Attesting +@BERA: Skip as we don't implement Attestations ### Construct attestation From d46687fa3e110b88346b95be9166028acdd11645 Mon Sep 17 00:00:00 2001 From: Rez Date: Tue, 8 Apr 2025 13:52:03 +1000 Subject: [PATCH 02/18] Fix spacing Signed-off-by: Rez --- specs/electra/validator.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/specs/electra/validator.md b/specs/electra/validator.md index 2dfa53c58b..946ecc5fde 100644 --- a/specs/electra/validator.md +++ b/specs/electra/validator.md @@ -85,6 +85,7 @@ class SignedAggregateAndProof(Container): #### Modified `get_payload` @BERA: Implemented already + Given the `payload_id`, `get_payload` returns the most recent version of the execution payload that has been built since the corresponding call to `notify_forkchoice_updated` method. @@ -103,6 +104,7 @@ def get_payload(self: ExecutionEngine, payload_id: PayloadId) -> GetPayloadRespo #### Attester slashings @BERA: Skip as we don't implement slashing + Changed the max attester slashings size to `MAX_ATTESTER_SLASHINGS_ELECTRA`. #### Attestations From 63f3119698ab5ac87561583ab24eaba399430dd3 Mon Sep 17 00:00:00 2001 From: Rez Date: Tue, 8 Apr 2025 13:52:49 +1000 Subject: [PATCH 03/18] Update validator.md Signed-off-by: Rez --- specs/electra/validator.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/electra/validator.md b/specs/electra/validator.md index 946ecc5fde..897758aa18 100644 --- a/specs/electra/validator.md +++ b/specs/electra/validator.md @@ -282,7 +282,7 @@ def get_execution_requests(execution_requests_list: Sequence[bytes]) -> Executio ``` ### Constructing the `BlobSidecar`s -@BERA: Skip as we don't implement BlobSidecars +@BERA: Skip as we don't implement EIP7691 #### Sidecar From 7cdf7784a1cd88907a8795d009e09bb54547d226 Mon Sep 17 00:00:00 2001 From: Rez Date: Tue, 8 Apr 2025 13:53:56 +1000 Subject: [PATCH 04/18] Update fork.md Signed-off-by: Rez --- specs/electra/fork.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/specs/electra/fork.md b/specs/electra/fork.md index fc59bae498..d88568cccf 100644 --- a/specs/electra/fork.md +++ b/specs/electra/fork.md @@ -62,6 +62,8 @@ Note that for the pure Electra networks, we don't apply `upgrade_to_electra` sin ### Upgrading the state +@BERA: We need to update the BeaconState fork version + If `state.slot % SLOTS_PER_EPOCH == 0` and `compute_epoch_at_slot(state.slot) == ELECTRA_FORK_EPOCH`, an irregular state change is made to upgrade to Electra. From 994c745d5e9470fb6afef02449c8bf1f01b37b8e Mon Sep 17 00:00:00 2001 From: Rez Date: Tue, 8 Apr 2025 17:26:34 +1000 Subject: [PATCH 05/18] Update beacon-chain.md --- specs/electra/beacon-chain.md | 78 +++++++++++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 9 deletions(-) diff --git a/specs/electra/beacon-chain.md b/specs/electra/beacon-chain.md index 5581ac264b..674078baa4 100644 --- a/specs/electra/beacon-chain.md +++ b/specs/electra/beacon-chain.md @@ -217,6 +217,8 @@ The following values are (non-configurable) constants used throughout the specif #### `PendingDeposit` +@BERA: Not used + *Note*: The container is new in EIP7251. ```python @@ -230,6 +232,8 @@ class PendingDeposit(Container): #### `PendingPartialWithdrawal` +@BERA: REZ - Maybe used? + *Note*: The container is new in EIP7251. ```python @@ -241,6 +245,8 @@ class PendingPartialWithdrawal(Container): #### `PendingConsolidation` +@BERA: Not used + *Note*: The container is new in EIP7251. ```python @@ -251,6 +257,8 @@ class PendingConsolidation(Container): #### `DepositRequest` +@BERA: Added but unused + *Note*: The container is new in EIP6110. ```python @@ -264,6 +272,8 @@ class DepositRequest(Container): #### `WithdrawalRequest` +@BERA: Added + *Note*: The container is new in EIP7251:EIP7002. ```python @@ -275,6 +285,8 @@ class WithdrawalRequest(Container): #### `ConsolidationRequest` +@BERA: Added but unused + *Note*: The container is new in EIP7251. ```python @@ -286,6 +298,8 @@ class ConsolidationRequest(Container): #### `ExecutionRequests` +@BERA: Added + ```python class ExecutionRequests(Container): deposits: List[DepositRequest, MAX_DEPOSIT_REQUESTS_PER_PAYLOAD] # [New in Electra:EIP6110] @@ -295,6 +309,8 @@ class ExecutionRequests(Container): #### `SingleAttestation` +@BERA: Unused + ```python class SingleAttestation(Container): committee_index: CommitteeIndex @@ -307,6 +323,8 @@ class SingleAttestation(Container): #### `AttesterSlashing` +@BERA: Unused + ```python class AttesterSlashing(Container): attestation_1: IndexedAttestation # [Modified in Electra:EIP7549] @@ -315,6 +333,8 @@ class AttesterSlashing(Container): #### `BeaconBlockBody` +@BERA: `execution_requests` added. + ```python class BeaconBlockBody(Container): randao_reveal: BLSSignature @@ -338,6 +358,8 @@ class BeaconBlockBody(Container): #### `Attestation` +@BERA: Unused + ```python class Attestation(Container): aggregation_bits: Bitlist[MAX_VALIDATORS_PER_COMMITTEE * MAX_COMMITTEES_PER_SLOT] # [Modified in Electra:EIP7549] @@ -348,6 +370,8 @@ class Attestation(Container): #### `IndexedAttestation` +@BERA: Unused + ```python class IndexedAttestation(Container): # [Modified in Electra:EIP7549] @@ -358,6 +382,8 @@ class IndexedAttestation(Container): #### `BeaconState` +@BERA: Potentially need `pending_partial_withdrawals` ? + ```python class BeaconState(Container): # Versioning @@ -401,16 +427,16 @@ class BeaconState(Container): next_withdrawal_validator_index: ValidatorIndex # Deep history valid from Capella onwards historical_summaries: List[HistoricalSummary, HISTORICAL_ROOTS_LIMIT] - deposit_requests_start_index: uint64 # [New in Electra:EIP6110] - deposit_balance_to_consume: Gwei # [New in Electra:EIP7251] - exit_balance_to_consume: Gwei # [New in Electra:EIP7251] - earliest_exit_epoch: Epoch # [New in Electra:EIP7251] - consolidation_balance_to_consume: Gwei # [New in Electra:EIP7251] - earliest_consolidation_epoch: Epoch # [New in Electra:EIP7251] - pending_deposits: List[PendingDeposit, PENDING_DEPOSITS_LIMIT] # [New in Electra:EIP7251] + deposit_requests_start_index: uint64 # [New in Electra:EIP6110] @BERA: Unused + deposit_balance_to_consume: Gwei # [New in Electra:EIP7251] @BERA: Unused + exit_balance_to_consume: Gwei # [New in Electra:EIP7251] @BERA: Unused + earliest_exit_epoch: Epoch # [New in Electra:EIP7251] @BERA: Unused + consolidation_balance_to_consume: Gwei # [New in Electra:EIP7251] @BERA: Unused + earliest_consolidation_epoch: Epoch # [New in Electra:EIP7251] @BERA: Unused + pending_deposits: List[PendingDeposit, PENDING_DEPOSITS_LIMIT] # [New in Electra:EIP7251] @BERA: Unused # [New in Electra:EIP7251] pending_partial_withdrawals: List[PendingPartialWithdrawal, PENDING_PARTIAL_WITHDRAWALS_LIMIT] - pending_consolidations: List[PendingConsolidation, PENDING_CONSOLIDATIONS_LIMIT] # [New in Electra:EIP7251] + pending_consolidations: List[PendingConsolidation, PENDING_CONSOLIDATIONS_LIMIT] # [New in Electra:EIP7251] @BERA: Unused ``` ## Helper functions @@ -419,10 +445,12 @@ class BeaconState(Container): #### Modified `compute_proposer_index` +@BERA: We do not use this for computing proposer index in berachain. + *Note*: The function `compute_proposer_index` is modified to use `MAX_EFFECTIVE_BALANCE_ELECTRA` and to use a 16-bit random value instead of an 8-bit random byte in the effective balance filter. ```python -def compute_proposer_index(state: BeaconState, indices: Sequence[ValidatorIndex], seed: Bytes32) -> ValidatorIndex: + def compute_proposer_index(state: BeaconState, indices: Sequence[ValidatorIndex], seed: Bytes32) -> ValidatorIndex: """ Return from ``indices`` a random index sampled by effective balance. """ @@ -445,6 +473,8 @@ def compute_proposer_index(state: BeaconState, indices: Sequence[ValidatorIndex] #### Modified `is_eligible_for_activation_queue` +@BERA: Effectively already implemented as we have `v.EffectiveBalance >= threshold`, where `threshold` is equivalent to `MIN_ACTIVATION_BALANCE`. + *Note*: The function `is_eligible_for_activation_queue` is modified to use `MIN_ACTIVATION_BALANCE` instead of `MAX_EFFECTIVE_BALANCE`. ```python @@ -460,6 +490,8 @@ def is_eligible_for_activation_queue(validator: Validator) -> bool: #### New `is_compounding_withdrawal_credential` +@BERA: Unused + ```python def is_compounding_withdrawal_credential(withdrawal_credentials: Bytes32) -> bool: return withdrawal_credentials[:1] == COMPOUNDING_WITHDRAWAL_PREFIX @@ -467,6 +499,8 @@ def is_compounding_withdrawal_credential(withdrawal_credentials: Bytes32) -> boo #### New `has_compounding_withdrawal_credential` +@BERA: Unused + ```python def has_compounding_withdrawal_credential(validator: Validator) -> bool: """ @@ -477,6 +511,8 @@ def has_compounding_withdrawal_credential(validator: Validator) -> bool: #### New `has_execution_withdrawal_credential` +@BERA: Will always return true for us as all validators have 0x01 prefixed withdrawal credentials. + ```python def has_execution_withdrawal_credential(validator: Validator) -> bool: """ @@ -487,6 +523,8 @@ def has_execution_withdrawal_credential(validator: Validator) -> bool: #### Modified `is_fully_withdrawable_validator` +@BERA: Should be easy change. + *Note*: The function `is_fully_withdrawable_validator` is modified to use `has_execution_withdrawal_credential` instead of `has_eth1_withdrawal_credential`. ```python @@ -503,6 +541,8 @@ def is_fully_withdrawable_validator(validator: Validator, balance: Gwei, epoch: #### Modified `is_partially_withdrawable_validator` +@BERA: Will need adopt this change so that we can appropriately check if a validator has excess balance, i.e. greater than 250k BERA. + *Note*: The function `is_partially_withdrawable_validator` is modified to use `get_max_effective_balance` instead of `MAX_EFFECTIVE_BALANCE` and `has_execution_withdrawal_credential` instead of `has_eth1_withdrawal_credential`. ```python @@ -524,6 +564,8 @@ def is_partially_withdrawable_validator(validator: Validator, balance: Gwei) -> #### New `get_committee_indices` +@BERA: Unused + ```python def get_committee_indices(committee_bits: Bitvector) -> Sequence[CommitteeIndex]: return [CommitteeIndex(index) for index, bit in enumerate(committee_bits) if bit] @@ -531,6 +573,8 @@ def get_committee_indices(committee_bits: Bitvector) -> Sequence[CommitteeIndex] #### New `get_max_effective_balance` +@BERA: Adopt, but will always return MIN_ACTIVATION_BALANCE for us, i.e 250k BERA. + ```python def get_max_effective_balance(validator: Validator) -> Gwei: """ @@ -546,6 +590,8 @@ def get_max_effective_balance(validator: Validator) -> Gwei: #### New `get_balance_churn_limit` +@BERA: Unknown if needed. Ideally not. + ```python def get_balance_churn_limit(state: BeaconState) -> Gwei: """ @@ -560,6 +606,8 @@ def get_balance_churn_limit(state: BeaconState) -> Gwei: #### New `get_activation_exit_churn_limit` +@BERA: Unknown if needed. Ideally not. + ```python def get_activation_exit_churn_limit(state: BeaconState) -> Gwei: """ @@ -570,6 +618,8 @@ def get_activation_exit_churn_limit(state: BeaconState) -> Gwei: #### New `get_consolidation_churn_limit` +@BERA: Unknown if needed. Ideally not. + ```python def get_consolidation_churn_limit(state: BeaconState) -> Gwei: return get_balance_churn_limit(state) - get_activation_exit_churn_limit(state) @@ -577,6 +627,8 @@ def get_consolidation_churn_limit(state: BeaconState) -> Gwei: #### New `get_pending_balance_to_withdraw` +@BERA: Used in `process_withdrawal_request`. + ```python def get_pending_balance_to_withdraw(state: BeaconState, validator_index: ValidatorIndex) -> Gwei: return sum( @@ -587,6 +639,8 @@ def get_pending_balance_to_withdraw(state: BeaconState, validator_index: Validat #### Modified `get_attesting_indices` +@BERA: Unused. + *Note*: The function `get_attesting_indices` is modified to support EIP7549. ```python @@ -612,6 +666,8 @@ def get_attesting_indices(state: BeaconState, attestation: Attestation) -> Set[V #### Modified `get_next_sync_committee_indices` +@BERA: Unused + *Note*: The function `get_next_sync_committee_indices` is modified to use `MAX_EFFECTIVE_BALANCE_ELECTRA` and to use a 16-bit random value instead of an 8-bit random byte in the effective balance filter. ```python @@ -646,6 +702,8 @@ def get_next_sync_committee_indices(state: BeaconState) -> Sequence[ValidatorInd #### Modified `initiate_validator_exit` +@BERA: We may need to add this as it's used in `processRegistryUpdates`. + *Note*: The function `initiate_validator_exit` is modified to use the new `compute_exit_epoch_and_update_churn` function. ```python @@ -668,6 +726,8 @@ def initiate_validator_exit(state: BeaconState, index: ValidatorIndex) -> None: #### New `switch_to_compounding_validator` +@BERA: Unused. + ```python def switch_to_compounding_validator(state: BeaconState, index: ValidatorIndex) -> None: validator = state.validators[index] From e97ad863328a86c351c5b20a7e4663cb626b359d Mon Sep 17 00:00:00 2001 From: Rez Date: Wed, 9 Apr 2025 09:07:03 +1000 Subject: [PATCH 06/18] Update beacon-chain.md --- specs/electra/beacon-chain.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/specs/electra/beacon-chain.md b/specs/electra/beacon-chain.md index 674078baa4..2bfd10c80e 100644 --- a/specs/electra/beacon-chain.md +++ b/specs/electra/beacon-chain.md @@ -573,7 +573,7 @@ def get_committee_indices(committee_bits: Bitvector) -> Sequence[CommitteeIndex] #### New `get_max_effective_balance` -@BERA: Adopt, but will always return MIN_ACTIVATION_BALANCE for us, i.e 250k BERA. +@BERA: Not needed as we always return the chainspec Max effective balance. ```python def get_max_effective_balance(validator: Validator) -> Gwei: @@ -737,6 +737,8 @@ def switch_to_compounding_validator(state: BeaconState, index: ValidatorIndex) - #### New `queue_excess_active_balance` +@BERA: Unused. + ```python def queue_excess_active_balance(state: BeaconState, index: ValidatorIndex) -> None: balance = state.balances[index] @@ -1044,7 +1046,7 @@ 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 - # [Modified in Electra:EIP7251] + # [Modified in Electra:EIP7251] @BERA: This is effectively already done. max_effective_balance = get_max_effective_balance(validator) if ( From 5c9e9a3e920944eb7923f6980fd546b152b95072 Mon Sep 17 00:00:00 2001 From: Rez Date: Tue, 15 Apr 2025 06:11:54 +1000 Subject: [PATCH 07/18] Update beacon-chain.md --- specs/electra/beacon-chain.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/specs/electra/beacon-chain.md b/specs/electra/beacon-chain.md index 2bfd10c80e..0ce8718bed 100644 --- a/specs/electra/beacon-chain.md +++ b/specs/electra/beacon-chain.md @@ -232,7 +232,7 @@ class PendingDeposit(Container): #### `PendingPartialWithdrawal` -@BERA: REZ - Maybe used? +@BERA: Must be introduced *Note*: The container is new in EIP7251. @@ -855,12 +855,12 @@ def process_epoch(state: BeaconState) -> None: process_justification_and_finalization(state) process_inactivity_updates(state) process_rewards_and_penalties(state) - process_registry_updates(state) # [Modified in Electra:EIP7251] - process_slashings(state) # [Modified in Electra:EIP7251] + process_registry_updates(state) # [Modified in Electra:EIP7251] @BERA: TBD + process_slashings(state) # [Modified in Electra:EIP7251] @BERA: Unused process_eth1_data_reset(state) - process_pending_deposits(state) # [New in Electra:EIP7251] - process_pending_consolidations(state) # [New in Electra:EIP7251] - process_effective_balance_updates(state) # [Modified in Electra:EIP7251] + process_pending_deposits(state) # [New in Electra:EIP7251] @BERA: Unused + process_pending_consolidations(state) # [New in Electra:EIP7251] @BERA: Unused + process_effective_balance_updates(state) # [Modified in Electra:EIP7251] @BERA: No Change process_slashings_reset(state) process_randao_mixes_reset(state) process_historical_summaries_update(state) From 36bd981501e299349d2e6a42f0914e7e4dea739e Mon Sep 17 00:00:00 2001 From: Rez Date: Tue, 15 Apr 2025 06:44:17 +1000 Subject: [PATCH 08/18] Updating comments --- specs/electra/beacon-chain.md | 96 ++++++++++++++++++++++------------- 1 file changed, 60 insertions(+), 36 deletions(-) diff --git a/specs/electra/beacon-chain.md b/specs/electra/beacon-chain.md index 0ce8718bed..e90bbc5f31 100644 --- a/specs/electra/beacon-chain.md +++ b/specs/electra/beacon-chain.md @@ -112,11 +112,11 @@ Electra is a consensus-layer upgrade containing a number of features. Including: -- [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110): Supply validator deposits on chain -- [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002): Execution layer triggerable exits +- [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110): Supply validator deposits on chain - @BERA: Changes related to EIP are is skipped as we have a functional deposit system. +- [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002): Execution layer triggerable exits. - [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251): Increase the MAX_EFFECTIVE_BALANCE -- [EIP-7549](https://eips.ethereum.org/EIPS/eip-7549): Move committee index outside Attestation -- [EIP-7691](https://eips.ethereum.org/EIPS/eip-7691): Blob throughput increase +- [EIP-7549](https://eips.ethereum.org/EIPS/eip-7549): Move committee index outside Attestation - @BERA: Changes related to EIP are is skipped as we do not use attestations. +- [EIP-7691](https://eips.ethereum.org/EIPS/eip-7691): Changes related to EIP are is skipped as we will not increase blob throughput. *Note*: This specification is built upon [Deneb](../deneb/beacon-chain.md) and is under active development. @@ -131,12 +131,18 @@ The following values are (non-configurable) constants used throughout the specif | `UNSET_DEPOSIT_REQUESTS_START_INDEX` | `uint64(2**64 - 1)` | *[New in Electra:EIP6110]* Value which indicates no start index has been assigned | | `FULL_EXIT_REQUEST_AMOUNT` | `uint64(0)` | *[New in Electra:EIP7002]* Withdrawal amount used to signal a full validator exit | +@BERA: + +- `UNSET_DEPOSIT_REQUESTS_START_INDEX` is not introduced due to excluding EIP6110. + ### Withdrawal prefixes | Name | Value | Description | | ------------------------------- | ---------------- | ----------------------------------------------------------------------------------- | | `COMPOUNDING_WITHDRAWAL_PREFIX` | `Bytes1('0x02')` | *[New in Electra:EIP7251]* Withdrawal credential prefix for a compounding validator | +@BERA: In Ethereum, compounding validators are those can have a balance higher than 32 ETH, introduced as part of EIP-7251. In Berachain, all validators are considered 'compounding validators' as they can all have a balance above 250k BERA. As such, we skip distinguishing between compounding and non-compounding validators. + ### Execution layer triggered requests | Name | Value | @@ -145,6 +151,8 @@ The following values are (non-configurable) constants used throughout the specif | `WITHDRAWAL_REQUEST_TYPE` | `Bytes1('0x01')` | | `CONSOLIDATION_REQUEST_TYPE` | `Bytes1('0x02')` | +@BERA: We introduce all of these fields, however, the Consensus Layer will only process `WITHDRAWAL_REQUEST_TYPE`. This means that if a user attempts to submit a `CONSOLIDATION_REQUEST_TYPE` or `DEPOSIT_REQUEST_TYPE`, they should expect to see no change to the system. However, their transaction will still be accepted on the execution layer. + ## Preset ### Gwei values @@ -154,6 +162,8 @@ The following values are (non-configurable) constants used throughout the specif | `MIN_ACTIVATION_BALANCE` | `Gwei(2**5 * 10**9)` (= 32,000,000,000) | *[New in Electra:EIP7251]* Minimum balance for a validator to become active | | `MAX_EFFECTIVE_BALANCE_ELECTRA` | `Gwei(2**11 * 10**9)` (= 2048,000,000,000) | *[New in Electra:EIP7251]* Maximum effective balance for a compounding validator | +@BERA: In Berachain, `MIN_ACTIVATION_BALANCE` will be set to reflected as 250K Bera and `MAX_EFFECTIVE_BALANCE_ELECTRA` will be reflected as 10_000_000 BERA. + ### Rewards and penalties | Name | Value | @@ -161,6 +171,8 @@ The following values are (non-configurable) constants used throughout the specif | `MIN_SLASHING_PENALTY_QUOTIENT_ELECTRA` | `uint64(2**12)` (= 4,096) | | `WHISTLEBLOWER_REWARD_QUOTIENT_ELECTRA` | `uint64(2**12)` (= 4,096) | +@BERA: These are slashing related and hence not introduced. + ### State list lengths | Name | Value | Unit | @@ -184,12 +196,16 @@ The following values are (non-configurable) constants used throughout the specif | `MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD` | `uint64(2**4)` (= 16) | *[New in Electra:EIP7002]* Maximum number of execution layer withdrawal requests in each payload | | `MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD` | `uint64(2**1)` (= 2) | *[New in Electra:EIP7251]* Maximum number of execution layer consolidation requests in each payload | +@BERA: We keep the values the same in Berachain. + ### Withdrawals processing | Name | Value | Description | | -------------------------------------------- | -------------------- | ----------------------------------------------------------------------------------------------- | | `MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP` | `uint64(2**3)` (= 8) | *[New in Electra:EIP7002]* Maximum number of pending partial withdrawals to process per payload | +@BERA: We keep the values the same in Berachain. + ### Pending deposits processing | Name | Value | Description | @@ -204,6 +220,8 @@ The following values are (non-configurable) constants used throughout the specif | ----------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------- | | `MAX_BLOBS_PER_BLOCK_ELECTRA` | `uint64(9)` | *[New in Electra:EIP7691]* Maximum number of blobs in a single block limited by `MAX_BLOB_COMMITMENTS_PER_BLOCK` | +@BERA: We do not increase the `MAX_BLOBS_PER_BLOCK` and hence keep it at `6` rather than increasing to `9`. + ### Validator cycle | Name | Value | @@ -211,14 +229,14 @@ The following values are (non-configurable) constants used throughout the specif | `MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA` | `Gwei(2**7 * 10**9)` (= 128,000,000,000) | | `MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT` | `Gwei(2**8 * 10**9)` (= 256,000,000,000) | +@BERA: Churn is related to how many validators can exit at any given point, such that too many validators cannot exit in a short period of time. We adopt these values for spec parity, although realistically we will never hit these as our validator set size is much smaller. + ## Containers ### New containers #### `PendingDeposit` -@BERA: Not used - *Note*: The container is new in EIP7251. ```python @@ -230,9 +248,9 @@ class PendingDeposit(Container): slot: Slot ``` -#### `PendingPartialWithdrawal` +@BERA: Not used and hence not introduced. -@BERA: Must be introduced +#### `PendingPartialWithdrawal` *Note*: The container is new in EIP7251. @@ -243,6 +261,8 @@ class PendingPartialWithdrawal(Container): withdrawable_epoch: Epoch ``` +@BERA: Must be introduced to support the withdrawals logic. + #### `PendingConsolidation` @BERA: Not used @@ -255,9 +275,9 @@ class PendingConsolidation(Container): target_index: ValidatorIndex ``` -#### `DepositRequest` +@BERA: Not used and hence not introduced. -@BERA: Added but unused +#### `DepositRequest` *Note*: The container is new in EIP6110. @@ -270,6 +290,8 @@ class DepositRequest(Container): index: uint64 ``` +@BERA: Introduced for parity in ExecutionRequestsRoot calculation but unused. + #### `WithdrawalRequest` @BERA: Added @@ -296,9 +318,9 @@ class ConsolidationRequest(Container): target_pubkey: BLSPubkey ``` -#### `ExecutionRequests` +@BERA: Introduced for parity in ExecutionRequestsRoot calculation but unused. -@BERA: Added +#### `ExecutionRequests` ```python class ExecutionRequests(Container): @@ -309,8 +331,6 @@ class ExecutionRequests(Container): #### `SingleAttestation` -@BERA: Unused - ```python class SingleAttestation(Container): committee_index: CommitteeIndex @@ -323,17 +343,15 @@ class SingleAttestation(Container): #### `AttesterSlashing` -@BERA: Unused - ```python class AttesterSlashing(Container): attestation_1: IndexedAttestation # [Modified in Electra:EIP7549] attestation_2: IndexedAttestation # [Modified in Electra:EIP7549] ``` -#### `BeaconBlockBody` +@BERA: Not used and hence not introduced. -@BERA: `execution_requests` added. +#### `BeaconBlockBody` ```python class BeaconBlockBody(Container): @@ -354,12 +372,12 @@ class BeaconBlockBody(Container): execution_requests: ExecutionRequests # [New in Electra] ``` +@BERA: We extend the beacon block body with `execution_requests`. + ### Modified containers #### `Attestation` -@BERA: Unused - ```python class Attestation(Container): aggregation_bits: Bitlist[MAX_VALIDATORS_PER_COMMITTEE * MAX_COMMITTEES_PER_SLOT] # [Modified in Electra:EIP7549] @@ -368,9 +386,9 @@ class Attestation(Container): committee_bits: Bitvector[MAX_COMMITTEES_PER_SLOT] # [New in Electra:EIP7549] ``` -#### `IndexedAttestation` +@BERA: Not used and hence changes not introduced. -@BERA: Unused +#### `IndexedAttestation` ```python class IndexedAttestation(Container): @@ -380,9 +398,9 @@ class IndexedAttestation(Container): signature: BLSSignature ``` -#### `BeaconState` +@BERA: Not used and hence changes not introduced. -@BERA: Potentially need `pending_partial_withdrawals` ? +#### `BeaconState` ```python class BeaconState(Container): @@ -439,14 +457,14 @@ class BeaconState(Container): pending_consolidations: List[PendingConsolidation, PENDING_CONSOLIDATIONS_LIMIT] # [New in Electra:EIP7251] @BERA: Unused ``` +@BERA: We must introduce the `pending_partial_withdrawals` as it's necessarily for the core withdrawals logic. + ## Helper functions ### Predicates #### Modified `compute_proposer_index` -@BERA: We do not use this for computing proposer index in berachain. - *Note*: The function `compute_proposer_index` is modified to use `MAX_EFFECTIVE_BALANCE_ELECTRA` and to use a 16-bit random value instead of an 8-bit random byte in the effective balance filter. ```python @@ -471,9 +489,9 @@ class BeaconState(Container): i += 1 ``` -#### Modified `is_eligible_for_activation_queue` +@BERA: We do not use this for computing proposer index in berachain. -@BERA: Effectively already implemented as we have `v.EffectiveBalance >= threshold`, where `threshold` is equivalent to `MIN_ACTIVATION_BALANCE`. +#### Modified `is_eligible_for_activation_queue` *Note*: The function `is_eligible_for_activation_queue` is modified to use `MIN_ACTIVATION_BALANCE` instead of `MAX_EFFECTIVE_BALANCE`. @@ -488,18 +506,18 @@ def is_eligible_for_activation_queue(validator: Validator) -> bool: ) ``` -#### New `is_compounding_withdrawal_credential` +@BERA: Effectively already implemented as we have `v.EffectiveBalance >= threshold`, where `threshold` is equivalent to `MIN_ACTIVATION_BALANCE`. -@BERA: Unused +#### 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` +@BERA: `is_compounding_withdrawal_credential` is only used in `has_compounding_withdrawal_credential`. In Berachain `has_compounding_withdrawal_credential` will always return True as all validators are considered compounding validators. As such, we do not introduce this function. -@BERA: Unused +#### New `has_compounding_withdrawal_credential` ```python def has_compounding_withdrawal_credential(validator: Validator) -> bool: @@ -509,9 +527,9 @@ def has_compounding_withdrawal_credential(validator: Validator) -> bool: return is_compounding_withdrawal_credential(validator.withdrawal_credentials) ``` -#### New `has_execution_withdrawal_credential` +@BERA: `has_compounding_withdrawal_credential` but always returns true. See reasoning in `is_compounding_withdrawal_credential`. -@BERA: Will always return true for us as all validators have 0x01 prefixed withdrawal credentials. +#### New `has_execution_withdrawal_credential` ```python def has_execution_withdrawal_credential(validator: Validator) -> bool: @@ -521,9 +539,15 @@ def has_execution_withdrawal_credential(validator: Validator) -> bool: return has_compounding_withdrawal_credential(validator) or has_eth1_withdrawal_credential(validator) ``` -#### Modified `is_fully_withdrawable_validator` +@BERA: Berachain only supports 0x01 credentials, so all validators should have this return true. We modify the implementation as below since `has_compounding_withdrawal_credential` will always returns true: -@BERA: Should be easy change. +```go + func (v Validator) HasExecutionWithdrawalCredential() bool { + return v.HasEth1WithdrawalCredentials() + } +``` + +#### Modified `is_fully_withdrawable_validator` *Note*: The function `is_fully_withdrawable_validator` is modified to use `has_execution_withdrawal_credential` instead of `has_eth1_withdrawal_credential`. From 43afd1ad72e364afba884c527b3bcf69626f308c Mon Sep 17 00:00:00 2001 From: Rez Date: Tue, 15 Apr 2025 06:48:09 +1000 Subject: [PATCH 09/18] Comments --- specs/electra/beacon-chain.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/specs/electra/beacon-chain.md b/specs/electra/beacon-chain.md index e90bbc5f31..38ef764bb0 100644 --- a/specs/electra/beacon-chain.md +++ b/specs/electra/beacon-chain.md @@ -265,8 +265,6 @@ class PendingPartialWithdrawal(Container): #### `PendingConsolidation` -@BERA: Not used - *Note*: The container is new in EIP7251. ```python @@ -294,8 +292,6 @@ class DepositRequest(Container): #### `WithdrawalRequest` -@BERA: Added - *Note*: The container is new in EIP7251:EIP7002. ```python @@ -307,8 +303,6 @@ class WithdrawalRequest(Container): #### `ConsolidationRequest` -@BERA: Added but unused - *Note*: The container is new in EIP7251. ```python @@ -339,6 +333,8 @@ class SingleAttestation(Container): signature: BLSSignature ``` +@BERA: Not used and hence not introduced. + ### Modified containers #### `AttesterSlashing` @@ -489,7 +485,7 @@ class BeaconState(Container): i += 1 ``` -@BERA: We do not use this for computing proposer index in berachain. +@BERA: We do not use this for computing proposer index in berachain as the proposer is chosen by CometBFT. #### Modified `is_eligible_for_activation_queue` From 9a9788d7fafe1a8feb41730c8e09b80c9585156f Mon Sep 17 00:00:00 2001 From: Rez Date: Tue, 15 Apr 2025 07:46:37 +1000 Subject: [PATCH 10/18] Update beacon-chain.md --- specs/electra/beacon-chain.md | 80 ++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 25 deletions(-) diff --git a/specs/electra/beacon-chain.md b/specs/electra/beacon-chain.md index 38ef764bb0..f7e50030fd 100644 --- a/specs/electra/beacon-chain.md +++ b/specs/electra/beacon-chain.md @@ -229,7 +229,7 @@ The following values are (non-configurable) constants used throughout the specif | `MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA` | `Gwei(2**7 * 10**9)` (= 128,000,000,000) | | `MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT` | `Gwei(2**8 * 10**9)` (= 256,000,000,000) | -@BERA: Churn is related to how many validators can exit at any given point, such that too many validators cannot exit in a short period of time. We adopt these values for spec parity, although realistically we will never hit these as our validator set size is much smaller. +@BERA: Churn is related to how many validators can exit at any given point, such that too many validators cannot exit in a short period of time. We choose to ignore all churn related changes due to our dramatically smaller validator set size, where churn is less relevant. ## Containers @@ -561,8 +561,6 @@ def is_fully_withdrawable_validator(validator: Validator, balance: Gwei, epoch: #### Modified `is_partially_withdrawable_validator` -@BERA: Will need adopt this change so that we can appropriately check if a validator has excess balance, i.e. greater than 250k BERA. - *Note*: The function `is_partially_withdrawable_validator` is modified to use `get_max_effective_balance` instead of `MAX_EFFECTIVE_BALANCE` and `has_execution_withdrawal_credential` instead of `has_eth1_withdrawal_credential`. ```python @@ -580,20 +578,20 @@ def is_partially_withdrawable_validator(validator: Validator, balance: Gwei) -> ) ``` +@BERA: We do not need to deviate from this. + ### Misc #### New `get_committee_indices` -@BERA: Unused - ```python def get_committee_indices(committee_bits: Bitvector) -> Sequence[CommitteeIndex]: return [CommitteeIndex(index) for index, bit in enumerate(committee_bits) if bit] ``` -#### New `get_max_effective_balance` +@BERA: Not used and hence changes not introduced. -@BERA: Not needed as we always return the chainspec Max effective balance. +#### New `get_max_effective_balance` ```python def get_max_effective_balance(validator: Validator) -> Gwei: @@ -606,12 +604,12 @@ def get_max_effective_balance(validator: Validator) -> Gwei: return MIN_ACTIVATION_BALANCE ``` +@BERA: This will always return 10_000_000 million on Berachain. + ### Beacon state accessors #### New `get_balance_churn_limit` -@BERA: Unknown if needed. Ideally not. - ```python def get_balance_churn_limit(state: BeaconState) -> Gwei: """ @@ -624,9 +622,9 @@ def get_balance_churn_limit(state: BeaconState) -> Gwei: return churn - churn % EFFECTIVE_BALANCE_INCREMENT ``` -#### New `get_activation_exit_churn_limit` +@BERA: We ignore churn related changes. -@BERA: Unknown if needed. Ideally not. +#### New `get_activation_exit_churn_limit` ```python def get_activation_exit_churn_limit(state: BeaconState) -> Gwei: @@ -636,18 +634,18 @@ def get_activation_exit_churn_limit(state: BeaconState) -> Gwei: return min(MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT, get_balance_churn_limit(state)) ``` -#### New `get_consolidation_churn_limit` +@BERA: We ignore churn related changes. -@BERA: Unknown if needed. Ideally not. +#### New `get_consolidation_churn_limit` ```python def get_consolidation_churn_limit(state: BeaconState) -> Gwei: return get_balance_churn_limit(state) - get_activation_exit_churn_limit(state) ``` -#### New `get_pending_balance_to_withdraw` +@BERA: Not introduced as we ignore consolidation processing. -@BERA: Used in `process_withdrawal_request`. +#### New `get_pending_balance_to_withdraw` ```python def get_pending_balance_to_withdraw(state: BeaconState, validator_index: ValidatorIndex) -> Gwei: @@ -657,9 +655,9 @@ def get_pending_balance_to_withdraw(state: BeaconState, validator_index: Validat ) ``` -#### Modified `get_attesting_indices` +@BERA: Introduced and used in `process_withdrawal_request`. -@BERA: Unused. +#### Modified `get_attesting_indices` *Note*: The function `get_attesting_indices` is modified to support EIP7549. @@ -684,9 +682,9 @@ def get_attesting_indices(state: BeaconState, attestation: Attestation) -> Set[V return output ``` -#### Modified `get_next_sync_committee_indices` +@BERA: Not introduced as related to attestations. -@BERA: Unused +#### Modified `get_next_sync_committee_indices` *Note*: The function `get_next_sync_committee_indices` is modified to use `MAX_EFFECTIVE_BALANCE_ELECTRA` and to use a 16-bit random value instead of an 8-bit random byte in the effective balance filter. @@ -718,12 +716,12 @@ def get_next_sync_committee_indices(state: BeaconState) -> Sequence[ValidatorInd return sync_committee_indices ``` +@BERA: Not introduced as we don't use sync committees + ### Beacon state mutators #### Modified `initiate_validator_exit` -@BERA: We may need to add this as it's used in `processRegistryUpdates`. - *Note*: The function `initiate_validator_exit` is modified to use the new `compute_exit_epoch_and_update_churn` function. ```python @@ -744,9 +742,19 @@ def initiate_validator_exit(state: BeaconState, index: ValidatorIndex) -> None: validator.withdrawable_epoch = Epoch(validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY) ``` -#### New `switch_to_compounding_validator` +@BERA: We introduce `initiate_validator_exit`. We deviate from the spec by NOT computing the `exit_queue_epoch` using churn, as all churn related changes are not relevant. Instead, the `exit_queue_epoch` will always just follow the existing pattern for validator set cap exits, with the small new introduction of `MinValidatorWithdrawabilityDelay`. `MinValidatorWithdrawabilityDelay` is used to ensure that sufficient time remains to detect slashable behaviour in the scenario that a validator does malicious behaviour before attempting to quickly exit the system. + +```go + nextEpoch := sp.cs.SlotToEpoch(slot) + 1 + exitQueueEpoch = nextEpoch + withdrawableEpoch = nextEpoch + 1 + sp.cs.MinValidatorWithdrawabilityDelay() + + // Set validator exit epoch and withdrawable epoch. + validator.SetExitEpoch(exitQueueEpoch) + validator.SetWithdrawableEpoch(withdrawableEpoch) +``` -@BERA: Unused. +#### New `switch_to_compounding_validator` ```python def switch_to_compounding_validator(state: BeaconState, index: ValidatorIndex) -> None: @@ -755,9 +763,9 @@ def switch_to_compounding_validator(state: BeaconState, index: ValidatorIndex) - queue_excess_active_balance(state, index) ``` -#### New `queue_excess_active_balance` +@BERA: Unused as all validators are compounding validators. -@BERA: Unused. +#### New `queue_excess_active_balance` ```python def queue_excess_active_balance(state: BeaconState, index: ValidatorIndex) -> None: @@ -777,6 +785,8 @@ def queue_excess_active_balance(state: BeaconState, index: ValidatorIndex) -> No )) ``` +@BERA: Unused as this is for EIP6110. + #### New `compute_exit_epoch_and_update_churn` ```python @@ -803,6 +813,8 @@ def compute_exit_epoch_and_update_churn(state: BeaconState, exit_balance: Gwei) return state.earliest_exit_epoch ``` +@BERA: We will not introduce churn related changes. + #### New `compute_consolidation_epoch_and_update_churn` ```python @@ -830,6 +842,8 @@ def compute_consolidation_epoch_and_update_churn(state: BeaconState, consolidati return state.earliest_consolidation_epoch ``` +@BERA: Not used and hence not introduced. + #### Modified `slash_validator` *Note*: The function `slash_validator` is modified to change how the slashing penalty and proposer/whistleblower rewards are calculated in accordance with EIP7251. @@ -1028,6 +1042,8 @@ def process_pending_deposits(state: BeaconState) -> None: state.deposit_balance_to_consume = Gwei(0) ``` +@BERA: Not used and hence not introduced. + #### New `process_pending_consolidations` ```python @@ -1548,6 +1564,8 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None: ) ``` +@BERA: We have custom deposit processing and as such do not modify here. + ##### Voluntary exits ###### Modified `process_voluntary_exit` @@ -1643,6 +1661,12 @@ def process_withdrawal_request( )) ``` +@BERA: This is the meat of the logic introduced for Pectra. We deviate slightly in the following ways: + +1. `initiate_validator_exit` does not rely on churn. +2. `has_compounding_withdrawal_credential` will always be true. +3. Partial withdrawals will not rely on churn to calculate the exit and withdrawable epochs. + ##### Deposit requests ###### New `process_deposit_request` @@ -1663,6 +1687,8 @@ def process_deposit_request(state: BeaconState, deposit_request: DepositRequest) )) ``` +@BERA: Not processed and hence not introduced. + ##### Execution layer consolidation requests ###### New `is_valid_switch_to_compounding_request` @@ -1704,6 +1730,8 @@ def is_valid_switch_to_compounding_request( return True ``` +@BERA: We do not process switches to consolidation requests. + ###### New `process_consolidation_request` ```python @@ -1783,3 +1811,5 @@ def process_consolidation_request( target_index=target_index )) ``` + +@BERA: We do not process switches to consolidation requests. From 8b13de9143bbff7aa6f784294c04768327b7ec34 Mon Sep 17 00:00:00 2001 From: Rez Date: Tue, 15 Apr 2025 08:45:27 +1000 Subject: [PATCH 11/18] Update beacon-chain.md --- specs/electra/beacon-chain.md | 52 +++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/specs/electra/beacon-chain.md b/specs/electra/beacon-chain.md index f7e50030fd..e7265e7cb8 100644 --- a/specs/electra/beacon-chain.md +++ b/specs/electra/beacon-chain.md @@ -742,7 +742,7 @@ def initiate_validator_exit(state: BeaconState, index: ValidatorIndex) -> None: validator.withdrawable_epoch = Epoch(validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY) ``` -@BERA: We introduce `initiate_validator_exit`. We deviate from the spec by NOT computing the `exit_queue_epoch` using churn, as all churn related changes are not relevant. Instead, the `exit_queue_epoch` will always just follow the existing pattern for validator set cap exits, with the small new introduction of `MinValidatorWithdrawabilityDelay`. `MinValidatorWithdrawabilityDelay` is used to ensure that sufficient time remains to detect slashable behaviour in the scenario that a validator does malicious behaviour before attempting to quickly exit the system. +@BERA: We introduce `initiate_validator_exit`. We deviate from the spec by NOT computing the `exit_queue_epoch` using churn, as all churn related changes are not relevant. Instead, the `exit_queue_epoch` will always just follow the existing pattern for validator set cap exits, with the small new introduction of `MinValidatorWithdrawabilityDelay`. `MinValidatorWithdrawabilityDelay` is used to ensure that sufficient time remains to detect slashable behaviour in the scenario that a validator does malicious behaviour before attempting to quickly exit the system. We do not have slashing yet, but introduce `MinValidatorWithdrawabilityDelay` for the future when we do. ```go nextEpoch := sp.cs.SlotToEpoch(slot) + 1 @@ -876,6 +876,8 @@ def slash_validator(state: BeaconState, increase_balance(state, whistleblower_index, Gwei(whistleblower_reward - proposer_reward)) ``` +@BERA: We do not have slashing yet and as such, do not introduce this slashing related change. + ## Beacon chain state transition function ### Epoch processing @@ -924,6 +926,8 @@ def process_registry_updates(state: BeaconState) -> None: validator.activation_epoch = activation_epoch ``` +@BERA: Previously we ignored the case where a validator's balance fell below the `EJECTION_BALANCE` as this was not possible since we didn't have slashing or partial withdrawals. We now introduce this. + #### Modified `process_slashings` *Note*: The function `process_slashings` is modified to use a new algorithm to compute correlation penalty. @@ -946,6 +950,8 @@ def process_slashings(state: BeaconState) -> None: decrease_balance(state, ValidatorIndex(index), penalty) ``` +@BERA: We do not process slashings. + #### New `apply_pending_deposit` ```python @@ -968,6 +974,8 @@ def apply_pending_deposit(state: BeaconState, deposit: PendingDeposit) -> None: increase_balance(state, validator_index, deposit.amount) ``` +@BERA: We have a custom deposit processing loop and as such, ignore this. + #### New `process_pending_deposits` Iterating over `pending_deposits` queue this function runs the following checks before applying pending deposit: @@ -1042,7 +1050,7 @@ def process_pending_deposits(state: BeaconState) -> None: state.deposit_balance_to_consume = Gwei(0) ``` -@BERA: Not used and hence not introduced. +@BERA: We have a custom deposit processing loop and as such, ignore this. #### New `process_pending_consolidations` @@ -1070,6 +1078,8 @@ def process_pending_consolidations(state: BeaconState) -> None: state.pending_consolidations = state.pending_consolidations[next_pending_consolidation:] ``` +@BERA: We do not process consolidations and as such ignore this. + #### Modified `process_effective_balance_updates` *Note*: The function `process_effective_balance_updates` is modified to use the new limit for the maximum effective balance. @@ -1092,6 +1102,8 @@ def process_effective_balance_updates(state: BeaconState) -> None: validator.effective_balance = min(balance - balance % EFFECTIVE_BALANCE_INCREMENT, max_effective_balance) ``` + @BERA: This is effectively already done. + ### Execution engine #### Request data @@ -1107,6 +1119,8 @@ class NewPayloadRequest(object): execution_requests: ExecutionRequests # [New in Electra] ``` +@BERA: Implemented. + #### Engine APIs ##### Modified `is_valid_block_hash` @@ -1124,6 +1138,8 @@ def is_valid_block_hash(self: ExecutionEngine, ... ``` +@BERA: Implemented. + ##### Modified `notify_new_payload` *Note*: The function `notify_new_payload` is modified to include the additional `execution_requests_list`. @@ -1140,6 +1156,8 @@ def notify_new_payload(self: ExecutionEngine, ... ``` +@BERA: Implemented. + ##### Modified `verify_and_notify_new_payload` *Note*: The function `verify_and_notify_new_payload` is modified to pass the additional parameter @@ -1178,6 +1196,8 @@ def verify_and_notify_new_payload(self: ExecutionEngine, return True ``` +@BERA: Implemented. + ### Block processing ```python @@ -1191,6 +1211,12 @@ def process_block(state: BeaconState, block: BeaconBlock) -> None: process_sync_aggregate(state, block.body.sync_aggregate) ``` +@BERA: We modify: + +- `process_withdrawals` - Update pending partial withdrawals +- `process_execution_payload` - Implemented. +- `process_operations` - Call `process_withdrawal_request` in `process_operations` + #### Withdrawals ##### Modified `get_expected_withdrawals` @@ -1257,6 +1283,8 @@ def get_expected_withdrawals(state: BeaconState) -> Tuple[Sequence[Withdrawal], return withdrawals, processed_partial_withdrawals_count ``` +@BERA: We need to extend our implementation to handle `pending_partial_withdrawals`. + ##### Modified `process_withdrawals` *Note*: The function `process_withdrawals` is modified to support EIP7251. @@ -1291,6 +1319,8 @@ def process_withdrawals(state: BeaconState, payload: ExecutionPayload) -> None: state.next_withdrawal_validator_index = next_validator_index ``` +@BERA: We adopt the change around `processed_partial_withdrawals_count`. + #### Execution payload ##### New `get_execution_requests_list` @@ -1312,6 +1342,8 @@ def get_execution_requests_list(execution_requests: ExecutionRequests) -> Sequen ] ``` +@BERA: Implemented. + ##### Modified `process_execution_payload` *Note*: The function `process_execution_payload` is modified to pass `execution_requests` into `execution_engine.verify_and_notify_new_payload` (via the updated `NewPayloadRequest`). @@ -1360,6 +1392,8 @@ def process_execution_payload(state: BeaconState, body: BeaconBlockBody, executi ) ``` +@BERA: Implemented. + #### Operations ##### Modified `process_operations` @@ -1391,6 +1425,8 @@ def process_operations(state: BeaconState, body: BeaconBlockBody) -> None: for_ops(body.execution_requests.consolidations, process_consolidation_request) # [New in Electra:EIP7251] ``` +@BERA: We implement the change where we handle each `process_withdrawal_request`. + ##### Attestations ###### Modified `process_attestation` @@ -1446,6 +1482,8 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None: increase_balance(state, get_beacon_proposer_index(state), proposer_reward) ``` +@BERA: Ignore as we don't handle attestations. + ##### Deposits ###### Modified `get_validator_from_deposit` @@ -1472,6 +1510,8 @@ def get_validator_from_deposit(pubkey: BLSPubkey, withdrawal_credentials: Bytes3 return validator ``` +@BERA: In Berachain, the implementation can be found in `NewValidatorFromDeposit`. No change is required. + ###### Modified `add_validator_to_registry` *Note*: The function `add_validator_to_registry` is modified to use the modified `get_validator_from_deposit`. @@ -1490,6 +1530,8 @@ def add_validator_to_registry(state: BeaconState, set_or_append_list(state.inactivity_scores, index, uint64(0)) ``` +@BERA: No change is required. + ###### Modified `apply_deposit` *Note*: The function `apply_deposit` is modified to support EIP7251. @@ -1519,6 +1561,8 @@ def apply_deposit(state: BeaconState, )) ``` +@BERA: We do not implement EIP7251 and as such no change is required. + ###### New `is_valid_deposit_signature` ```python @@ -1536,6 +1580,8 @@ def is_valid_deposit_signature(pubkey: BLSPubkey, return bls.Verify(pubkey, signing_root, signature) ``` +@BERA: We do not implement EIP7251 and as such no change is required. + ###### Modified `process_deposit` *Note*: The function `process_deposit` is modified to to use the modified `apply_deposit`. @@ -1594,6 +1640,8 @@ def process_voluntary_exit(state: BeaconState, signed_voluntary_exit: SignedVolu initiate_validator_exit(state, voluntary_exit.validator_index) ``` +@BERA: This is used for voluntary exits, signed using the signing key. We do not support this mechanism of exiting and as such ignore this method entirely. + ##### Execution layer withdrawal requests ###### New `process_withdrawal_request` From bd8829fee292a587c5d3a3156daaa4d5a452e98a Mon Sep 17 00:00:00 2001 From: Rez Date: Tue, 15 Apr 2025 08:54:52 +1000 Subject: [PATCH 12/18] Update beacon-chain.md --- specs/electra/beacon-chain.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/electra/beacon-chain.md b/specs/electra/beacon-chain.md index e7265e7cb8..c8deb5904c 100644 --- a/specs/electra/beacon-chain.md +++ b/specs/electra/beacon-chain.md @@ -453,7 +453,7 @@ class BeaconState(Container): pending_consolidations: List[PendingConsolidation, PENDING_CONSOLIDATIONS_LIMIT] # [New in Electra:EIP7251] @BERA: Unused ``` -@BERA: We must introduce the `pending_partial_withdrawals` as it's necessarily for the core withdrawals logic. +@BERA: We must introduce the `pending_partial_withdrawals` as it's necessary for the core withdrawals logic. ## Helper functions @@ -464,7 +464,7 @@ class BeaconState(Container): *Note*: The function `compute_proposer_index` is modified to use `MAX_EFFECTIVE_BALANCE_ELECTRA` and to use a 16-bit random value instead of an 8-bit random byte in the effective balance filter. ```python - def compute_proposer_index(state: BeaconState, indices: Sequence[ValidatorIndex], seed: Bytes32) -> ValidatorIndex: +def compute_proposer_index(state: BeaconState, indices: Sequence[ValidatorIndex], seed: Bytes32) -> ValidatorIndex: """ Return from ``indices`` a random index sampled by effective balance. """ From f4f9962cf0330afbdb29abc010b92f4d53649521 Mon Sep 17 00:00:00 2001 From: Rez Date: Tue, 15 Apr 2025 08:57:35 +1000 Subject: [PATCH 13/18] Update beacon-chain.md --- specs/electra/beacon-chain.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/electra/beacon-chain.md b/specs/electra/beacon-chain.md index c8deb5904c..369bafb820 100644 --- a/specs/electra/beacon-chain.md +++ b/specs/electra/beacon-chain.md @@ -891,12 +891,12 @@ def process_epoch(state: BeaconState) -> None: process_justification_and_finalization(state) process_inactivity_updates(state) process_rewards_and_penalties(state) - process_registry_updates(state) # [Modified in Electra:EIP7251] @BERA: TBD + process_registry_updates(state) # [Modified in Electra:EIP7251] @BERA: Change required. process_slashings(state) # [Modified in Electra:EIP7251] @BERA: Unused process_eth1_data_reset(state) process_pending_deposits(state) # [New in Electra:EIP7251] @BERA: Unused process_pending_consolidations(state) # [New in Electra:EIP7251] @BERA: Unused - process_effective_balance_updates(state) # [Modified in Electra:EIP7251] @BERA: No Change + process_effective_balance_updates(state) # [Modified in Electra:EIP7251] @BERA: No Change. process_slashings_reset(state) process_randao_mixes_reset(state) process_historical_summaries_update(state) From 6b0bdbbd4e7a4399a9a7641085e14371b4795911 Mon Sep 17 00:00:00 2001 From: Rez Date: Tue, 15 Apr 2025 09:40:36 +1000 Subject: [PATCH 14/18] Update specs/electra/beacon-chain.md Co-authored-by: Cal Bera Signed-off-by: Rez --- specs/electra/beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/electra/beacon-chain.md b/specs/electra/beacon-chain.md index 369bafb820..9c78e8e109 100644 --- a/specs/electra/beacon-chain.md +++ b/specs/electra/beacon-chain.md @@ -453,7 +453,7 @@ class BeaconState(Container): pending_consolidations: List[PendingConsolidation, PENDING_CONSOLIDATIONS_LIMIT] # [New in Electra:EIP7251] @BERA: Unused ``` -@BERA: We must introduce the `pending_partial_withdrawals` as it's necessary for the core withdrawals logic. +@BERA: We must introduce the `pending_partial_withdrawals` as it's necessary for the core withdrawals logic (specifically to allow partial withdrawals). ## Helper functions From 0c855f55e8f31e73e5883a1e3b59fa03154d4a7a Mon Sep 17 00:00:00 2001 From: Rez Date: Tue, 15 Apr 2025 09:50:04 +1000 Subject: [PATCH 15/18] Update beacon-chain.md --- specs/electra/beacon-chain.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/specs/electra/beacon-chain.md b/specs/electra/beacon-chain.md index 369bafb820..5dbc7ad8e5 100644 --- a/specs/electra/beacon-chain.md +++ b/specs/electra/beacon-chain.md @@ -110,6 +110,8 @@ ## Introduction +@BERA: In Berachain, we break the Electra hardfork into multiple hard forks, the first of which is electra0. This annotation is purely for Electra0 and we may consider adding support for excluded EIPs in later Electra hard-forks, e.g. Electra1. + Electra is a consensus-layer upgrade containing a number of features. Including: - [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110): Supply validator deposits on chain - @BERA: Changes related to EIP are is skipped as we have a functional deposit system. From ccba826f28fb2bb380b99703d5ab02067a1dde2a Mon Sep 17 00:00:00 2001 From: Rez Date: Tue, 15 Apr 2025 11:55:51 +1000 Subject: [PATCH 16/18] Update fork.md --- specs/electra/fork.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/electra/fork.md b/specs/electra/fork.md index d88568cccf..1d36048750 100644 --- a/specs/electra/fork.md +++ b/specs/electra/fork.md @@ -62,8 +62,6 @@ Note that for the pure Electra networks, we don't apply `upgrade_to_electra` sin ### Upgrading the state -@BERA: We need to update the BeaconState fork version - If `state.slot % SLOTS_PER_EPOCH == 0` and `compute_epoch_at_slot(state.slot) == ELECTRA_FORK_EPOCH`, an irregular state change is made to upgrade to Electra. @@ -173,3 +171,5 @@ def upgrade_to_electra(pre: deneb.BeaconState) -> BeaconState: return post ``` + +@BERA: We need to update the BeaconState fork version and set `pending_partial_withdrawals=[]`. From 344f90959490a773517bdeaa1de42b07a4e44f5e Mon Sep 17 00:00:00 2001 From: Rez Date: Mon, 21 Apr 2025 10:41:36 +1000 Subject: [PATCH 17/18] Update comments --- specs/electra/beacon-chain.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/specs/electra/beacon-chain.md b/specs/electra/beacon-chain.md index c14c60b673..ea4f905316 100644 --- a/specs/electra/beacon-chain.md +++ b/specs/electra/beacon-chain.md @@ -110,7 +110,7 @@ ## Introduction -@BERA: In Berachain, we break the Electra hardfork into multiple hard forks, the first of which is electra0. This annotation is purely for Electra0 and we may consider adding support for excluded EIPs in later Electra hard-forks, e.g. Electra1. +@BERA: In Berachain, we break the Electra hardfork into multiple hard forks, the first of which is electra0. This annotation is purely for Electra0 and we may consider adding support for excluded EIPs in later Electra hard-forks, e.g. EIP6110 in Electra1. Electra is a consensus-layer upgrade containing a number of features. Including: @@ -744,7 +744,9 @@ def initiate_validator_exit(state: BeaconState, index: ValidatorIndex) -> None: validator.withdrawable_epoch = Epoch(validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY) ``` -@BERA: We introduce `initiate_validator_exit`. We deviate from the spec by NOT computing the `exit_queue_epoch` using churn, as all churn related changes are not relevant. Instead, the `exit_queue_epoch` will always just follow the existing pattern for validator set cap exits, with the small new introduction of `MinValidatorWithdrawabilityDelay`. `MinValidatorWithdrawabilityDelay` is used to ensure that sufficient time remains to detect slashable behaviour in the scenario that a validator does malicious behaviour before attempting to quickly exit the system. We do not have slashing yet, but introduce `MinValidatorWithdrawabilityDelay` for the future when we do. +@BERA: We introduce `initiate_validator_exit`. We deviate from the spec by NOT computing the `exit_queue_epoch` using churn, as all churn related changes are not relevant. Instead, the `exit_queue_epoch` will always just follow the existing pattern for validator set cap exits, with the small new introduction of `MIN_VALIDATOR_WITHDRAWABILITY_DELAY`. `MIN_VALIDATOR_WITHDRAWABILITY_DELAY` is used to ensure that sufficient time remains to detect slashable behaviour in the scenario that a validator does malicious behaviour before attempting to quickly exit the system. We do not have slashing yet, but introduce `MIN_VALIDATOR_WITHDRAWABILITY_DELAY` for the future when we do. + +By default, `MIN_VALIDATOR_WITHDRAWABILITY_DELAY` is set to 192 epochs which is 27 hours on Berachain. We're still considering the appropriate value for this but a large delay gives us bandwidth for emergency hard forks if a vulnerability is found. ```go nextEpoch := sp.cs.SlotToEpoch(slot) + 1 @@ -928,7 +930,11 @@ def process_registry_updates(state: BeaconState) -> None: validator.activation_epoch = activation_epoch ``` -@BERA: Previously we ignored the case where a validator's balance fell below the `EJECTION_BALANCE` as this was not possible since we didn't have slashing or partial withdrawals. We now introduce this. +@BERA: Previously we ignored the case where a validator's balance fell below the `EJECTION_BALANCE` as this was not possible since we didn't have slashing or partial withdrawals. + +We continue to ignore this case as there is not forseeable way for a validator's balance to fall below the EJECTION_BALANCE balance, without it directly initiating a validator exit. + +For example, post-electra, if a Partial Withdrawal Request is made, the balance must remain above `MIN_ACTIVATION_BALANCE`. A Full Withdrawal Request will remove the entire balance and initiate a validator #### Modified `process_slashings` From d44b7e001d042b02c479333dba62a68917dcdd3a Mon Sep 17 00:00:00 2001 From: Rez Date: Mon, 21 Apr 2025 10:58:26 +1000 Subject: [PATCH 18/18] Update beacon-chain.md --- specs/electra/beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/electra/beacon-chain.md b/specs/electra/beacon-chain.md index ea4f905316..3367d45d91 100644 --- a/specs/electra/beacon-chain.md +++ b/specs/electra/beacon-chain.md @@ -895,7 +895,7 @@ def process_epoch(state: BeaconState) -> None: process_justification_and_finalization(state) process_inactivity_updates(state) process_rewards_and_penalties(state) - process_registry_updates(state) # [Modified in Electra:EIP7251] @BERA: Change required. + process_registry_updates(state) # [Modified in Electra:EIP7251] @BERA: Modified to use MinActivationBalance process_slashings(state) # [Modified in Electra:EIP7251] @BERA: Unused process_eth1_data_reset(state) process_pending_deposits(state) # [New in Electra:EIP7251] @BERA: Unused