Skip to content

Commit

Permalink
Electra: Beacon state fixes from PR 13919
Browse files Browse the repository at this point in the history
  • Loading branch information
prestonvanloon committed Apr 30, 2024
1 parent 763edc3 commit 6fd2121
Show file tree
Hide file tree
Showing 14 changed files with 420 additions and 539 deletions.
1 change: 1 addition & 0 deletions beacon-chain/state/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ type ReadOnlyElectra interface {
NumPendingPartialWithdrawals() uint64
ExitEpochAndUpdateChurn(exitBalance uint64) (primitives.Epoch, error)
PendingBalanceToWithdraw(idx primitives.ValidatorIndex) (uint64, error)
ActiveBalanceAtIndex(idx primitives.ValidatorIndex) (uint64, error)
}

// WriteOnlyBlockRoots defines a struct which only has write access to block roots methods.
Expand Down
23 changes: 22 additions & 1 deletion beacon-chain/state/state-native/beacon_state_mainnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,19 @@ type beaconStateMarshalable struct {
NextSyncCommittee *ethpb.SyncCommittee `json:"next_sync_committee" yaml:"next_sync_committee"`
LatestExecutionPayloadHeader *enginev1.ExecutionPayloadHeader `json:"latest_execution_payload_header" yaml:"latest_execution_payload_header"`
LatestExecutionPayloadHeaderCapella *enginev1.ExecutionPayloadHeaderCapella `json:"latest_execution_payload_header_capella" yaml:"latest_execution_payload_header_capella"`
LatestExecutionPayloadHeaderDeneb *enginev1.ExecutionPayloadHeaderDeneb `json:"latest_execution_payload_header_deneb" yaml:"latest_execution_payload_header_deneb"`
LatestExecutionPayloadHeaderElectra *enginev1.ExecutionPayloadHeaderElectra `json:"latest_execution_payload_header_electra" yaml:"latest_execution_payload_header_electra"`
NextWithdrawalIndex uint64 `json:"next_withdrawal_index" yaml:"next_withdrawal_index"`
NextWithdrawalValidatorIndex primitives.ValidatorIndex `json:"next_withdrawal_validator_index" yaml:"next_withdrawal_validator_index"`
DepositReceiptsStartIndex uint64 `json:"deposit_receipt_start_index" yaml:"deposit_receipt_start_index"`
DepositBalanceToConsume uint64 `json:"deposit_balance_to_consume" yaml:"deposit_balance_to_consume"`
ExitBalanceToConsume uint64 `json:"exit_balance_to_consume" yaml:"exit_balance_to_consume"`
EarliestExitEpoch primitives.Epoch `json:"earliest_exit_epoch" yaml:"earliest_exit_epoch"`
ConsolidationBalanceToConsume uint64 `json:"consolidation_balance_to_consume" yaml:"consolidation_balance_to_consume"`
EarliestConsolidationEpoch primitives.Epoch `json:"earliest_consolidation_epoch" yaml:"earliest_consolidation_epoch"`
PendingBalanceDeposits []*ethpb.PendingBalanceDeposit `json:"pending_balance_deposits" yaml:"pending_balance_deposits"`
PendingPartialWithdrawals []*ethpb.PendingPartialWithdrawal `json:"pending_partial_withdrawals" yaml:"pending_partial_withdrawals"`
PendingConsolidations []*ethpb.PendingConsolidation `json:"pending_consolidations" yaml:"pending_consolidations"`
}

func (b *BeaconState) MarshalJSON() ([]byte, error) {
Expand Down Expand Up @@ -173,9 +184,19 @@ func (b *BeaconState) MarshalJSON() ([]byte, error) {
NextSyncCommittee: b.nextSyncCommittee,
LatestExecutionPayloadHeader: b.latestExecutionPayloadHeader,
LatestExecutionPayloadHeaderCapella: b.latestExecutionPayloadHeaderCapella,
LatestExecutionPayloadHeaderDeneb: b.latestExecutionPayloadHeaderDeneb,
LatestExecutionPayloadHeaderElectra: b.latestExecutionPayloadHeaderElectra,
NextWithdrawalIndex: b.nextWithdrawalIndex,
NextWithdrawalValidatorIndex: b.nextWithdrawalValidatorIndex,
// TODO: Electra fields!
DepositReceiptsStartIndex: b.depositReceiptsStartIndex,
DepositBalanceToConsume: b.depositBalanceToConsume,
ExitBalanceToConsume: b.exitBalanceToConsume,
EarliestExitEpoch: b.earliestExitEpoch,
ConsolidationBalanceToConsume: b.consolidationBalanceToConsume,
EarliestConsolidationEpoch: b.earliestConsolidationEpoch,
PendingBalanceDeposits: b.pendingBalanceDeposits,
PendingPartialWithdrawals: b.pendingPartialWithdrawals,
PendingConsolidations: b.pendingConsolidations,
}
return json.Marshal(marshalable)
}
23 changes: 22 additions & 1 deletion beacon-chain/state/state-native/beacon_state_minimal.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,19 @@ type beaconStateMarshalable struct {
NextSyncCommittee *ethpb.SyncCommittee `json:"next_sync_committee" yaml:"next_sync_committee"`
LatestExecutionPayloadHeader *enginev1.ExecutionPayloadHeader `json:"latest_execution_payload_header" yaml:"latest_execution_payload_header"`
LatestExecutionPayloadHeaderCapella *enginev1.ExecutionPayloadHeaderCapella `json:"latest_execution_payload_header_capella" yaml:"latest_execution_payload_header_capella"`
LatestExecutionPayloadHeaderDeneb *enginev1.ExecutionPayloadHeaderDeneb `json:"latest_execution_payload_header_deneb" yaml:"latest_execution_payload_header_deneb"`
LatestExecutionPayloadHeaderElectra *enginev1.ExecutionPayloadHeaderElectra `json:"latest_execution_payload_header_electra" yaml:"latest_execution_payload_header_electra"`
NextWithdrawalIndex uint64 `json:"next_withdrawal_index" yaml:"next_withdrawal_index"`
NextWithdrawalValidatorIndex primitives.ValidatorIndex `json:"next_withdrawal_validator_index" yaml:"next_withdrawal_validator_index"`
DepositReceiptsStartIndex uint64 `json:"deposit_receipt_start_index" yaml:"deposit_receipt_start_index"`
DepositBalanceToConsume uint64 `json:"deposit_balance_to_consume" yaml:"deposit_balance_to_consume"`
ExitBalanceToConsume uint64 `json:"exit_balance_to_consume" yaml:"exit_balance_to_consume"`
EarliestExitEpoch primitives.Epoch `json:"earliest_exit_epoch" yaml:"earliest_exit_epoch"`
ConsolidationBalanceToConsume uint64 `json:"consolidation_balance_to_consume" yaml:"consolidation_balance_to_consume"`
EarliestConsolidationEpoch primitives.Epoch `json:"earliest_consolidation_epoch" yaml:"earliest_consolidation_epoch"`
PendingBalanceDeposits []*ethpb.PendingBalanceDeposit `json:"pending_balance_deposits" yaml:"pending_balance_deposits"`
PendingPartialWithdrawals []*ethpb.PendingPartialWithdrawal `json:"pending_partial_withdrawals" yaml:"pending_partial_withdrawals"`
PendingConsolidations []*ethpb.PendingConsolidation `json:"pending_consolidations" yaml:"pending_consolidations"`
}

func (b *BeaconState) MarshalJSON() ([]byte, error) {
Expand Down Expand Up @@ -173,9 +184,19 @@ func (b *BeaconState) MarshalJSON() ([]byte, error) {
NextSyncCommittee: b.nextSyncCommittee,
LatestExecutionPayloadHeader: b.latestExecutionPayloadHeader,
LatestExecutionPayloadHeaderCapella: b.latestExecutionPayloadHeaderCapella,
LatestExecutionPayloadHeaderDeneb: b.latestExecutionPayloadHeaderDeneb,
LatestExecutionPayloadHeaderElectra: b.latestExecutionPayloadHeaderElectra,
NextWithdrawalIndex: b.nextWithdrawalIndex,
NextWithdrawalValidatorIndex: b.nextWithdrawalValidatorIndex,
// TODO: Electra fields!
DepositReceiptsStartIndex: b.depositReceiptsStartIndex,
DepositBalanceToConsume: b.depositBalanceToConsume,
ExitBalanceToConsume: b.exitBalanceToConsume,
EarliestExitEpoch: b.earliestExitEpoch,
ConsolidationBalanceToConsume: b.consolidationBalanceToConsume,
EarliestConsolidationEpoch: b.earliestConsolidationEpoch,
PendingBalanceDeposits: b.pendingBalanceDeposits,
PendingPartialWithdrawals: b.pendingPartialWithdrawals,
PendingConsolidations: b.pendingConsolidations,
}
return json.Marshal(marshalable)
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func (b *BeaconState) PendingBalanceDeposits() ([]*ethpb.PendingBalanceDeposit,
}
b.lock.RLock()
defer b.lock.RUnlock()
return b.pendingBalanceDeposits, nil
return b.pendingBalanceDepositsVal(), nil
}

func (b *BeaconState) pendingBalanceDepositsVal() []*ethpb.PendingBalanceDeposit {
Expand Down
2 changes: 1 addition & 1 deletion beacon-chain/state/state-native/getters_consolidation.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (b *BeaconState) PendingConsolidations() ([]*ethpb.PendingConsolidation, er
}
b.lock.RLock()
defer b.lock.RUnlock()
return b.pendingConsolidations, nil
return b.pendingConsolidationsVal(), nil
}

func (b *BeaconState) NumPendingConsolidations() uint64 {
Expand Down
4 changes: 2 additions & 2 deletions beacon-chain/state/state-native/getters_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ func ProtobufBeaconStateCapella(s interface{}) (*ethpb.BeaconStateCapella, error
func ProtobufBeaconStateDeneb(s interface{}) (*ethpb.BeaconStateDeneb, error) {
pbState, ok := s.(*ethpb.BeaconStateDeneb)
if !ok {
return nil, errors.New("input is not type pb.ProtobufBeaconStateDeneb")
return nil, errors.New("input is not type pb.BeaconStateDeneb")
}
return pbState, nil
}
Expand All @@ -539,7 +539,7 @@ func ProtobufBeaconStateDeneb(s interface{}) (*ethpb.BeaconStateDeneb, error) {
func ProtobufBeaconStateElectra(s interface{}) (*ethpb.BeaconStateElectra, error) {
pbState, ok := s.(*ethpb.BeaconStateElectra)
if !ok {
return nil, errors.New("input is not type pb.ProtobufBeaconStateElectra")
return nil, errors.New("input is not type pb.BeaconStateElectra")
}
return pbState, nil
}
70 changes: 70 additions & 0 deletions beacon-chain/state/state-native/getters_validator_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package state_native_test

import (
"math"
"testing"

"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
statenative "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native"
testtmpl "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/testing"
"github.com/prysmaticlabs/prysm/v5/config/params"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/testing/require"
"github.com/prysmaticlabs/prysm/v5/testing/util"
Expand Down Expand Up @@ -66,3 +68,71 @@ func TestValidatorIndexes(t *testing.T) {
require.Equal(t, hexutil.Encode(readOnlyBytes[:]), hexutil.Encode(byteValue[:]))
})
}

func TestActiveBalanceAtIndex(t *testing.T) {
// Test setup with a state with 4 validators.
// Validators 0 & 1 have compounding withdrawal credentials while validators 2 & 3 have BLS withdrawal credentials.
pb := &ethpb.BeaconStateElectra{
Validators: []*ethpb.Validator{
{
WithdrawalCredentials: []byte{params.BeaconConfig().CompoundingWithdrawalPrefixByte},
},
{
WithdrawalCredentials: []byte{params.BeaconConfig().CompoundingWithdrawalPrefixByte},
},
{
WithdrawalCredentials: []byte{params.BeaconConfig().BLSWithdrawalPrefixByte},
},
{
WithdrawalCredentials: []byte{params.BeaconConfig().BLSWithdrawalPrefixByte},
},
},
Balances: []uint64{
55,
math.MaxUint64,
55,
math.MaxUint64,
},
}
state, err := statenative.InitializeFromProtoUnsafeElectra(pb)
require.NoError(t, err)

ab, err := state.ActiveBalanceAtIndex(0)
require.NoError(t, err)
require.Equal(t, uint64(55), ab)

ab, err = state.ActiveBalanceAtIndex(1)
require.NoError(t, err)
require.Equal(t, params.BeaconConfig().MaxEffectiveBalanceElectra, ab)

ab, err = state.ActiveBalanceAtIndex(2)
require.NoError(t, err)
require.Equal(t, uint64(55), ab)

ab, err = state.ActiveBalanceAtIndex(3)
require.NoError(t, err)
require.Equal(t, params.BeaconConfig().MinActivationBalance, ab)

}

func TestPendingBalanceToWithdraw(t *testing.T) {
pb := &ethpb.BeaconStateElectra{
PendingPartialWithdrawals: []*ethpb.PendingPartialWithdrawal{
{
Amount: 100,
},
{
Amount: 200,
},
{
Amount: 300,
},
},
}
state, err := statenative.InitializeFromProtoUnsafeElectra(pb)
require.NoError(t, err)

ab, err := state.PendingBalanceToWithdraw(0)
require.NoError(t, err)
require.Equal(t, uint64(600), ab)
}
4 changes: 2 additions & 2 deletions beacon-chain/state/state-native/getters_withdrawal.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ func (b *BeaconState) ExpectedWithdrawals() ([]*enginev1.Withdrawal, uint64, err
epoch := slots.ToEpoch(b.slot)

// Electra partial withdrawals functionality.
if epoch >= params.BeaconConfig().ElectraForkEpoch {
if b.version >= version.Electra {
for _, w := range b.pendingPartialWithdrawals {
if primitives.Epoch(w.WithdrawableEpoch) > epoch || len(withdrawals) >= int(params.BeaconConfig().MaxPendingPartialsPerWithdrawalSweep) {
if w.WithdrawableEpoch > epoch || len(withdrawals) >= int(params.BeaconConfig().MaxPendingPartialsPerWithdrawalSweep) {
break
}

Expand Down
Loading

0 comments on commit 6fd2121

Please sign in to comment.