Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ePBS to state #13926

Merged
merged 1 commit into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions beacon-chain/state/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go_library(
srcs = [
"error.go",
"interfaces.go",
"interfaces_epbs.go",
"prometheus.go",
],
importpath = "github.com/prysmaticlabs/prysm/v5/beacon-chain/state",
Expand Down
2 changes: 2 additions & 0 deletions beacon-chain/state/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ type ReadOnlyBeaconState interface {
ReadOnlySyncCommittee
ReadOnlyDeposits
ReadOnlyConsolidations
ReadOnlyEpbsFields
ToProtoUnsafe() interface{}
ToProto() interface{}
GenesisTime() uint64
Expand Down Expand Up @@ -93,6 +94,7 @@ type WriteOnlyBeaconState interface {
WriteOnlyConsolidations
WriteOnlyWithdrawals
WriteOnlyDeposits
WriteOnlyEpbsFields
SetGenesisTime(val uint64) error
SetGenesisValidatorsRoot(val []byte) error
SetSlot(val primitives.Slot) error
Expand Down
28 changes: 28 additions & 0 deletions beacon-chain/state/interfaces_epbs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package state

import (
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
)

type ReadOnlyEpbsFields interface {
PreviousInclusionListSlot() primitives.Slot
PreviousInclusionListProposer() primitives.ValidatorIndex
LatestInclusionListSlot() primitives.Slot
LatestInclusionListProposer() primitives.ValidatorIndex
IsParentBlockFull() bool
ExecutionPayloadHeader() *enginev1.ExecutionPayloadHeaderEPBS
LatestBlockHash() []byte
LatestFullSlot() primitives.Slot
LastWithdrawalsRoot() []byte
}

type WriteOnlyEpbsFields interface {
SetExecutionPayloadHeader(val *enginev1.ExecutionPayloadHeaderEPBS)
UpdatePreviousInclusionListData()
SetLatestInclusionListSlot(val primitives.Slot)
SetLatestInclusionListProposer(val primitives.ValidatorIndex)
SetLatestBlockHash(val []byte)
SetLatestFullSlot(val primitives.Slot)
SetLastWithdrawalsRoot(val []byte)
}
7 changes: 7 additions & 0 deletions beacon-chain/state/state-native/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ go_library(
"getters_checkpoint.go",
"getters_consolidation.go",
"getters_deposit_receipts.go",
"getters_epbs.go",
"getters_eth1.go",
"getters_misc.go",
"getters_participation.go",
"getters_payload_header.go",
"getters_payload_header_epbs.go",
"getters_randao.go",
"getters_state.go",
"getters_sync_committee.go",
Expand All @@ -33,6 +35,7 @@ go_library(
"setters_churn.go",
"setters_consolidation.go",
"setters_deposit_receipts.go",
"setters_epbs.go",
"setters_eth1.go",
"setters_misc.go",
"setters_participation.go",
Expand All @@ -45,6 +48,7 @@ go_library(
"spec_parameters.go",
"ssz.go",
"state_trie.go",
"state_trie_epbs.go",
"types.go",
"validator_index_cache.go",
],
Expand Down Expand Up @@ -95,6 +99,7 @@ go_test(
"getters_consolidation_test.go",
"getters_deposit_receipts_test.go",
"getters_participation_test.go",
"getters_setters_epbs_test.go",
"getters_test.go",
"getters_validator_test.go",
"getters_withdrawal_test.go",
Expand All @@ -116,6 +121,7 @@ go_test(
"setters_withdrawal_test.go",
"state_fuzz_test.go",
"state_test.go",
"state_trie_epbs_test.go",
"state_trie_test.go",
"types_test.go",
"validator_index_cache_test.go",
Expand Down Expand Up @@ -149,6 +155,7 @@ go_test(
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
"//testing/util:go_default_library",
"//testing/util/random:go_default_library",
"//time/slots:go_default_library",
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
"@com_github_golang_snappy//:go_default_library",
Expand Down
9 changes: 9 additions & 0 deletions beacon-chain/state/state-native/beacon_state_mainnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ type BeaconState struct {
latestExecutionPayloadHeaderElectra *enginev1.ExecutionPayloadHeaderElectra
nextWithdrawalIndex uint64
nextWithdrawalValidatorIndex primitives.ValidatorIndex
// ePBS fields
previousInclusionListProposer primitives.ValidatorIndex
previousInclusionListSlot primitives.Slot
latestInclusionListProposer primitives.ValidatorIndex
latestInclusionListSlot primitives.Slot
latestBlockHash [32]byte
latestFullSlot primitives.Slot
executionPayloadHeader *enginev1.ExecutionPayloadHeaderEPBS
lastWithdrawalsRoot [32]byte

// Electra fields
depositReceiptsStartIndex uint64
Expand Down
9 changes: 9 additions & 0 deletions beacon-chain/state/state-native/beacon_state_minimal.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ type BeaconState struct {
latestExecutionPayloadHeaderElectra *enginev1.ExecutionPayloadHeaderElectra
nextWithdrawalIndex uint64
nextWithdrawalValidatorIndex primitives.ValidatorIndex
// ePBS fields
previousInclusionListProposer primitives.ValidatorIndex
previousInclusionListSlot primitives.Slot
latestInclusionListProposer primitives.ValidatorIndex
latestInclusionListSlot primitives.Slot
latestBlockHash [32]byte
latestFullSlot primitives.Slot
executionPayloadHeader *enginev1.ExecutionPayloadHeaderEPBS
lastWithdrawalsRoot [32]byte

// Electra fields
depositReceiptsStartIndex uint64
Expand Down
83 changes: 83 additions & 0 deletions beacon-chain/state/state-native/getters_epbs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package state_native

import (
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
)

// ExecutionPayloadHeader retrieves a copy of the execution payload header.
// It returns an error if the operation is not supported for the beacon state's version.
func (b *BeaconState) ExecutionPayloadHeader() *enginev1.ExecutionPayloadHeaderEPBS {
b.lock.RLock()
defer b.lock.RUnlock()

return b.executionPayloadHeaderVal()
}

// IsParentBlockFull checks if the last committed payload header was fulfilled.
// Returns true if both the beacon block and payload were present.
// Call this function on a beacon state before processing the execution payload header.
func (b *BeaconState) IsParentBlockFull() bool {
b.lock.RLock()
defer b.lock.RUnlock()

headerBlockHash := bytesutil.ToBytes32(b.executionPayloadHeader.BlockHash)
return headerBlockHash == b.latestBlockHash
}

// LatestInclusionListProposer returns the proposer index from the latest inclusion list.
func (b *BeaconState) LatestInclusionListProposer() primitives.ValidatorIndex {
b.lock.RLock()
defer b.lock.RUnlock()

return b.latestInclusionListProposer
}

// LatestInclusionListSlot returns the slot from the latest inclusion list.
func (b *BeaconState) LatestInclusionListSlot() primitives.Slot {
b.lock.RLock()
defer b.lock.RUnlock()

return b.latestInclusionListSlot
}

// PreviousInclusionListProposer returns the proposer index from the previous inclusion list.
func (b *BeaconState) PreviousInclusionListProposer() primitives.ValidatorIndex {
b.lock.RLock()
defer b.lock.RUnlock()

return b.previousInclusionListProposer
}

// PreviousInclusionListSlot returns the slot from the previous inclusion list.
func (b *BeaconState) PreviousInclusionListSlot() primitives.Slot {
b.lock.RLock()
defer b.lock.RUnlock()

return b.previousInclusionListSlot
}

// LatestBlockHash returns the latest block hash.
func (b *BeaconState) LatestBlockHash() []byte {
b.lock.RLock()
defer b.lock.RUnlock()

return b.latestBlockHash[:]
}

// LatestFullSlot returns the slot of the latest full block.
func (b *BeaconState) LatestFullSlot() primitives.Slot {
b.lock.RLock()
defer b.lock.RUnlock()

return b.latestFullSlot
}

// LastWithdrawalsRoot returns the latest withdrawal root.
func (b *BeaconState) LastWithdrawalsRoot() []byte {
b.lock.RLock()
defer b.lock.RUnlock()

return b.lastWithdrawalsRoot[:]
}
10 changes: 10 additions & 0 deletions beacon-chain/state/state-native/getters_payload_header_epbs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package state_native

import (
enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
)

func (b *BeaconState) executionPayloadHeaderVal() *enginev1.ExecutionPayloadHeaderEPBS {
return eth.CopyExecutionPayloadHeaderEPBS(b.executionPayloadHeader)
}
104 changes: 104 additions & 0 deletions beacon-chain/state/state-native/getters_setters_epbs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package state_native

import (
"crypto/rand"
"testing"

"github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native/types"
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"github.com/prysmaticlabs/prysm/v5/testing/require"
"github.com/prysmaticlabs/prysm/v5/testing/util/random"
)

func Test_LatestExecutionPayloadHeader(t *testing.T) {
s := &BeaconState{version: version.EPBS}
_, err := s.LatestExecutionPayloadHeader()
require.ErrorContains(t, "unsupported version (epbs) for latest execution payload header", err)
}

func Test_SetLatestExecutionPayloadHeader(t *testing.T) {
s := &BeaconState{version: version.EPBS}
require.ErrorContains(t, "SetLatestExecutionPayloadHeader is not supported for epbs", s.SetLatestExecutionPayloadHeader(nil))
}

func Test_SetExecutionPayloadHeader(t *testing.T) {
s := &BeaconState{version: version.EPBS, dirtyFields: make(map[types.FieldIndex]bool)}
header := random.ExecutionPayloadHeader(t)
s.SetExecutionPayloadHeader(header)
require.Equal(t, true, s.dirtyFields[types.ExecutionPayloadHeader])

got := s.ExecutionPayloadHeader()
require.DeepEqual(t, got, header)
}

func Test_UpdatePreviousInclusionListData(t *testing.T) {
s := &BeaconState{version: version.EPBS, dirtyFields: make(map[types.FieldIndex]bool)}
p := s.PreviousInclusionListProposer()
require.Equal(t, primitives.ValidatorIndex(0), p)
ss := s.PreviousInclusionListSlot()
require.Equal(t, primitives.Slot(0), ss)

s.SetLatestInclusionListProposer(1)
s.SetLatestInclusionListSlot(2)
s.UpdatePreviousInclusionListData()
require.Equal(t, true, s.dirtyFields[types.PreviousInclusionListProposer])
require.Equal(t, true, s.dirtyFields[types.PreviousInclusionListSlot])

p = s.PreviousInclusionListProposer()
require.Equal(t, primitives.ValidatorIndex(1), p)
ss = s.PreviousInclusionListSlot()
require.Equal(t, primitives.Slot(2), ss)
}

func Test_SetLatestInclusionListProposer(t *testing.T) {
s := &BeaconState{version: version.EPBS, dirtyFields: make(map[types.FieldIndex]bool)}
s.SetLatestInclusionListProposer(1)
require.Equal(t, true, s.dirtyFields[types.LatestInclusionListProposer])

got := s.LatestInclusionListProposer()
require.Equal(t, primitives.ValidatorIndex(1), got)
}

func Test_SetLatestInclusionListSlot(t *testing.T) {
s := &BeaconState{version: version.EPBS, dirtyFields: make(map[types.FieldIndex]bool)}
s.SetLatestInclusionListSlot(2)
require.Equal(t, true, s.dirtyFields[types.LatestInclusionListSlot])

got := s.LatestInclusionListSlot()
require.Equal(t, primitives.Slot(2), got)
}

func Test_SetLatestBlockHash(t *testing.T) {
s := &BeaconState{version: version.EPBS, dirtyFields: make(map[types.FieldIndex]bool)}
b := make([]byte, fieldparams.RootLength)
_, err := rand.Read(b)
require.NoError(t, err)
s.SetLatestBlockHash(b)
require.Equal(t, true, s.dirtyFields[types.LatestBlockHash])

got := s.LatestBlockHash()
require.DeepEqual(t, got, b)
}

func Test_SetLatestFullSlot(t *testing.T) {
s := &BeaconState{version: version.EPBS, dirtyFields: make(map[types.FieldIndex]bool)}
s.SetLatestFullSlot(3)
require.Equal(t, true, s.dirtyFields[types.LatestFullSlot])

got := s.LatestFullSlot()
require.Equal(t, primitives.Slot(3), got)
}

func Test_SetLastWithdrawalsRoot(t *testing.T) {
s := &BeaconState{version: version.EPBS, dirtyFields: make(map[types.FieldIndex]bool)}
b := make([]byte, fieldparams.RootLength)
_, err := rand.Read(b)
require.NoError(t, err)
s.SetLastWithdrawalsRoot(b)
require.Equal(t, true, s.dirtyFields[types.LastWithdrawalsRoot])

got := s.LastWithdrawalsRoot()
require.DeepEqual(t, got, b)
}
Loading
Loading