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 00b695f
Show file tree
Hide file tree
Showing 13 changed files with 164 additions and 34 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)
}
2 changes: 1 addition & 1 deletion beacon-chain/state/state-native/getters_withdrawal.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func (b *BeaconState) ExpectedWithdrawals() ([]*enginev1.Withdrawal, uint64, err
// Electra partial withdrawals functionality.
if epoch >= params.BeaconConfig().ElectraForkEpoch {
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
7 changes: 4 additions & 3 deletions beacon-chain/state/state-native/setters_balance_deposits.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package state_native

import (
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native/types"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state/stateutil"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
Expand All @@ -14,7 +15,9 @@ func (b *BeaconState) AppendPendingBalanceDeposit(index primitives.ValidatorInde
b.lock.Lock()
defer b.lock.Unlock()

// TODO: Shared field references
b.sharedFieldReferences[types.PendingBalanceDeposits].MinusRef()
b.sharedFieldReferences[types.PendingBalanceDeposits] = stateutil.NewRef(1)

b.pendingBalanceDeposits = append(b.pendingBalanceDeposits, &ethpb.PendingBalanceDeposit{Index: index, Amount: amount})

b.markFieldAsDirty(types.PendingBalanceDeposits)
Expand All @@ -29,7 +32,6 @@ func (b *BeaconState) SetPendingBalanceDeposits(val []*ethpb.PendingBalanceDepos
b.lock.Lock()
defer b.lock.Unlock()

// TODO: Shared field references
b.pendingBalanceDeposits = val

b.markFieldAsDirty(types.PendingBalanceDeposits)
Expand All @@ -44,7 +46,6 @@ func (b *BeaconState) SetDepositBalanceToConsume(gwei uint64) error {
b.lock.Lock()
defer b.lock.Unlock()

// TODO: Shared field references
b.depositBalanceToConsume = gwei

b.markFieldAsDirty(types.DepositBalanceToConsume)
Expand Down
9 changes: 7 additions & 2 deletions beacon-chain/state/state-native/setters_consolidation.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package state_native

import (
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native/types"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state/stateutil"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
Expand All @@ -14,7 +15,9 @@ func (b *BeaconState) AppendPendingConsolidation(val *ethpb.PendingConsolidation
b.lock.Lock()
defer b.lock.Unlock()

// TODO: Shared field references
b.sharedFieldReferences[types.PendingConsolidations].MinusRef()
b.sharedFieldReferences[types.PendingConsolidations] = stateutil.NewRef(1)

b.pendingConsolidations = append(b.pendingConsolidations, val)

b.markFieldAsDirty(types.PendingConsolidations)
Expand All @@ -29,7 +32,9 @@ func (b *BeaconState) SetPendingConsolidations(val []*ethpb.PendingConsolidation
b.lock.Lock()
defer b.lock.Unlock()

// TODO: Shared field references
b.sharedFieldReferences[types.PendingConsolidations].MinusRef()
b.sharedFieldReferences[types.PendingConsolidations] = stateutil.NewRef(1)

b.pendingConsolidations = val

b.markFieldAsDirty(types.PendingConsolidations)
Expand Down
6 changes: 5 additions & 1 deletion beacon-chain/state/state-native/setters_withdrawal.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package state_native

import (
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native/types"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state/stateutil"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
Expand Down Expand Up @@ -44,8 +45,11 @@ func (b *BeaconState) AppendPendingPartialWithdrawal(ppw *eth.PendingPartialWith
b.lock.Lock()
defer b.lock.Unlock()

// TODO: Shared field references
b.sharedFieldReferences[types.PendingPartialWithdrawals].MinusRef()
b.sharedFieldReferences[types.PendingPartialWithdrawals] = stateutil.NewRef(1)

b.pendingPartialWithdrawals = append(b.pendingPartialWithdrawals, ppw)

b.markFieldAsDirty(types.PendingPartialWithdrawals)
return nil
}
15 changes: 8 additions & 7 deletions beacon-chain/state/state-native/state_trie.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ var denebFields = append(

var electraFields = append(
denebFields,
types.LatestExecutionPayloadHeaderElectra,
types.DepositReceiptsStartIndex,
types.DepositBalanceToConsume,
types.ExitBalanceToConsume,
Expand All @@ -118,7 +119,7 @@ const (
experimentalStateBellatrixSharedFieldRefCount = 6
experimentalStateCapellaSharedFieldRefCount = 8
experimentalStateDenebSharedFieldRefCount = 8
experimentalStateElectraSharedFieldRefCount = 8 // TODO: Is this correct?
experimentalStateElectraSharedFieldRefCount = 8
)

// InitializeFromProtoPhase0 the beacon state from a protobuf representation.
Expand Down Expand Up @@ -763,7 +764,7 @@ func InitializeFromProtoUnsafeElectra(st *ethpb.BeaconStateElectra) (state.Beaco
b.balancesMultiValue = NewMultiValueBalances(st.Balances)
b.validatorsMultiValue = NewMultiValueValidators(st.Validators)
b.inactivityScoresMultiValue = NewMultiValueInactivityScores(st.InactivityScores)
b.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, experimentalStateDenebSharedFieldRefCount)
b.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, experimentalStateElectraSharedFieldRefCount)
} else {
bRoots := make([][32]byte, fieldparams.BlockRootsLength)
for i, r := range st.BlockRoots {
Expand Down Expand Up @@ -807,11 +808,11 @@ func InitializeFromProtoUnsafeElectra(st *ethpb.BeaconStateElectra) (state.Beaco
b.sharedFieldReferences[types.Slashings] = stateutil.NewRef(1)
b.sharedFieldReferences[types.PreviousEpochParticipationBits] = stateutil.NewRef(1)
b.sharedFieldReferences[types.CurrentEpochParticipationBits] = stateutil.NewRef(1)
b.sharedFieldReferences[types.LatestExecutionPayloadHeaderDeneb] = stateutil.NewRef(1) // New in Deneb.
b.sharedFieldReferences[types.HistoricalSummaries] = stateutil.NewRef(1) // New in Capella.
b.sharedFieldReferences[types.PendingBalanceDeposits] = stateutil.NewRef(1) // New in Electra.
b.sharedFieldReferences[types.PendingPartialWithdrawals] = stateutil.NewRef(1) // New in Electra.
b.sharedFieldReferences[types.PendingConsolidations] = stateutil.NewRef(1) // New in Electra.
b.sharedFieldReferences[types.LatestExecutionPayloadHeaderElectra] = stateutil.NewRef(1) // New in Electra.
b.sharedFieldReferences[types.HistoricalSummaries] = stateutil.NewRef(1) // New in Capella.
b.sharedFieldReferences[types.PendingBalanceDeposits] = stateutil.NewRef(1) // New in Electra.
b.sharedFieldReferences[types.PendingPartialWithdrawals] = stateutil.NewRef(1) // New in Electra.
b.sharedFieldReferences[types.PendingConsolidations] = stateutil.NewRef(1) // New in Electra.
if !features.Get().EnableExperimentalState {
b.sharedFieldReferences[types.BlockRoots] = stateutil.NewRef(1)
b.sharedFieldReferences[types.StateRoots] = stateutil.NewRef(1)
Expand Down
Loading

0 comments on commit 00b695f

Please sign in to comment.