mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 23:18:15 -05:00
Using the multi value slice for the beacon state (#12549)
* in progress... * in progress... * remove log * log root * Revert "Auxiliary commit to revert individual files from f12a609ea2a2f1e87e97321f3a717cd324b5ae97" This reverts commit 5ae35edb6477d8d0ea4e94b273efc6590484da85. * cleanup * remove log * remove whitespace * remove logs * more stuff * copy * always rebuild trie * revert * add state * init state * fix all * uintptr * move slice to new package * lock in `Detach` * remove constraint * reorder * blockroots and stateroots * fill roots in empty() * fix hasher * implement slice for balances and inactivity scores * detach in setters * Revert "implement slice for balances and inactivity scores" This reverts commit59eb9df8d7. # Conflicts: # beacon-chain/state/state-native/setters_validator.go * use counter to track states * typos * rename interface * balances * gauge * some improvements * first try with map * fix * inactivity scores in progress * fix test # Conflicts: # beacon-chain/state/state-native/helpers_test.go * test fixes * ToProto fix * copy roots * validators * build fixes * fix bug in `ToProto` * fix fuzz test * fix bug in slice getters * fix state equality checks * make tests pass * make tests pass * more test updates * Revert "Auxiliary commit to revert individual files from 34e7344bff08a589e6341bb1829e3cb74159e878" This reverts commit ecd64efa8917f37ca41460e0356ff007fe55dd9d. * Revert "make tests pass" This reverts commit0cf00f19ee. * Revert "make tests pass" This reverts commit521b65e1d2. * pass tests * deepequal identifiable types * Deflake `cloners_test.go` * feature flag for block roots * feature flag * remove recursive locks * reduce complexity of rootSelector * fix randao mixes root * some fixes * revisit tests * revert change to field trie helpers * initialize field map for tests * remove whitespace * initialize roots with proper length * more fixes * out of bounds message fix * optimize length calculation * remove call to Len in PubkeyAtIndex * don't log deposits * unit tests * unit tests * fix * comments * test fixes * id * remove Enumerator interface * review feedback * simplify field trie * bring back fieldtrie package * fix bazel file * use handle32ByteArrays for root computation * fix locks * metrics * bzl * simplify some things * use htr in state test * remove code from require package * gzl * more htr * Fuzzing of the multi-value slice * assert values * getter optimizations * use At when reading from validators * Nishant's review * restore safe copy * remove empty line * build fix * restore how we get root at index for deafult mode * more review comments * optimize default behavior * simplify Slice calls * test fix * remove unnecessary package * remove unused setter * make fieldMap unexported * some improvements in state package * call `Slice` instead of manually copying * unlock in ReadFromEveryValidator * Potuz's comments * lock the state when reading from all validators # Conflicts: # beacon-chain/state/state-native/getters_validator.go * add back preston's changes * add index --------- Co-authored-by: Potuz <potuz@prysmaticlabs.com> Co-authored-by: nisdas <nishdas93@gmail.com> Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
This commit is contained in:
@@ -16,7 +16,7 @@ func TestReportEpochMetrics_BadHeadState(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, h.SetValidators(nil))
|
||||
err = reportEpochMetrics(context.Background(), s, h)
|
||||
require.ErrorContains(t, "failed to initialize precompute: nil validators in state", err)
|
||||
require.ErrorContains(t, "failed to initialize precompute: state has nil validator slice", err)
|
||||
}
|
||||
|
||||
func TestReportEpochMetrics_BadAttestation(t *testing.T) {
|
||||
|
||||
@@ -31,7 +31,7 @@ func Test_BaseReward(t *testing.T) {
|
||||
valIdx: 2,
|
||||
st: genState(1),
|
||||
want: 0,
|
||||
errString: "index 2 out of range",
|
||||
errString: "validator index 2 does not exist",
|
||||
},
|
||||
{
|
||||
name: "active balance is 32eth",
|
||||
@@ -89,7 +89,7 @@ func Test_BaseRewardWithTotalBalance(t *testing.T) {
|
||||
valIdx: 2,
|
||||
activeBalance: 1,
|
||||
want: 0,
|
||||
errString: "index 2 out of range",
|
||||
errString: "validator index 2 does not exist",
|
||||
},
|
||||
{
|
||||
name: "active balance is 1",
|
||||
|
||||
@@ -82,7 +82,7 @@ func ProcessRandaoNoVerify(
|
||||
for i, x := range blockRandaoReveal {
|
||||
latestMixSlice[i] ^= x
|
||||
}
|
||||
if err := beaconState.UpdateRandaoMixesAtIndex(uint64(currentEpoch%latestMixesLength), latestMixSlice); err != nil {
|
||||
if err := beaconState.UpdateRandaoMixesAtIndex(uint64(currentEpoch%latestMixesLength), [32]byte(latestMixSlice)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return beaconState, nil
|
||||
|
||||
@@ -152,7 +152,7 @@ func TestProcessBLSToExecutionChange(t *testing.T) {
|
||||
}
|
||||
|
||||
_, err = blocks.ProcessBLSToExecutionChange(st, signed)
|
||||
require.ErrorContains(t, "out of range", err)
|
||||
require.ErrorContains(t, "out of bounds", err)
|
||||
})
|
||||
|
||||
t.Run("signature does not verify", func(t *testing.T) {
|
||||
|
||||
@@ -349,7 +349,7 @@ func ProcessRandaoMixesReset(state state.BeaconState) (state.BeaconState, error)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := state.UpdateRandaoMixesAtIndex(uint64(nextEpoch%randaoMixLength), mix); err != nil {
|
||||
if err := state.UpdateRandaoMixesAtIndex(uint64(nextEpoch%randaoMixLength), [32]byte(mix)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ func TestIsCurrentEpochSyncCommittee_DoesNotExist(t *testing.T) {
|
||||
require.NoError(t, state.SetNextSyncCommittee(syncCommittee))
|
||||
|
||||
ok, err := IsCurrentPeriodSyncCommittee(state, 12390192)
|
||||
require.ErrorContains(t, "index 12390192 out of range", err)
|
||||
require.ErrorContains(t, "validator index 12390192 does not exist", err)
|
||||
require.Equal(t, false, ok)
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ func TestIsNextEpochSyncCommittee_DoesNotExist(t *testing.T) {
|
||||
require.NoError(t, state.SetNextSyncCommittee(syncCommittee))
|
||||
|
||||
ok, err := IsNextPeriodSyncCommittee(state, 120391029)
|
||||
require.ErrorContains(t, "index 120391029 out of range", err)
|
||||
require.ErrorContains(t, "validator index 120391029 does not exist", err)
|
||||
require.Equal(t, false, ok)
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@ func TestCurrentEpochSyncSubcommitteeIndices_DoesNotExist(t *testing.T) {
|
||||
require.NoError(t, state.SetNextSyncCommittee(syncCommittee))
|
||||
|
||||
index, err := CurrentPeriodSyncSubcommitteeIndices(state, 129301923)
|
||||
require.ErrorContains(t, "index 129301923 out of range", err)
|
||||
require.ErrorContains(t, "validator index 129301923 does not exist", err)
|
||||
require.DeepEqual(t, []primitives.CommitteeIndex(nil), index)
|
||||
}
|
||||
|
||||
@@ -367,7 +367,7 @@ func TestNextEpochSyncSubcommitteeIndices_DoesNotExist(t *testing.T) {
|
||||
require.NoError(t, state.SetNextSyncCommittee(syncCommittee))
|
||||
|
||||
index, err := NextPeriodSyncSubcommitteeIndices(state, 21093019)
|
||||
require.ErrorContains(t, "index 21093019 out of range", err)
|
||||
require.ErrorContains(t, "validator index 21093019 does not exist", err)
|
||||
require.DeepEqual(t, []primitives.CommitteeIndex(nil), index)
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||
state_native "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stateutil"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/container/trie"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
@@ -221,6 +222,18 @@ func OptimizedGenesisBeaconState(genesisTime uint64, preState state.BeaconState,
|
||||
|
||||
// EmptyGenesisState returns an empty beacon state object.
|
||||
func EmptyGenesisState() (state.BeaconState, error) {
|
||||
blockRoots := make([][]byte, fieldparams.BlockRootsLength)
|
||||
for i := range blockRoots {
|
||||
blockRoots[i] = make([]byte, fieldparams.RootLength)
|
||||
}
|
||||
stateRoots := make([][]byte, fieldparams.StateRootsLength)
|
||||
for i := range stateRoots {
|
||||
stateRoots[i] = make([]byte, fieldparams.RootLength)
|
||||
}
|
||||
mixes := make([][]byte, fieldparams.RandaoMixesLength)
|
||||
for i := range mixes {
|
||||
mixes[i] = make([]byte, fieldparams.RootLength)
|
||||
}
|
||||
st := ðpb.BeaconState{
|
||||
// Misc fields.
|
||||
Slot: 0,
|
||||
@@ -229,6 +242,9 @@ func EmptyGenesisState() (state.BeaconState, error) {
|
||||
CurrentVersion: params.BeaconConfig().GenesisForkVersion,
|
||||
Epoch: 0,
|
||||
},
|
||||
BlockRoots: blockRoots,
|
||||
StateRoots: stateRoots,
|
||||
RandaoMixes: mixes,
|
||||
// Validator registry fields.
|
||||
Validators: []*ethpb.Validator{},
|
||||
Balances: []uint64{},
|
||||
|
||||
@@ -2,6 +2,7 @@ package beacon
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -15,7 +16,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/transition"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/core"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
|
||||
state_native "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native"
|
||||
consensus_types "github.com/prysmaticlabs/prysm/v4/consensus-types"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/crypto/bls"
|
||||
http2 "github.com/prysmaticlabs/prysm/v4/network/http"
|
||||
@@ -228,8 +229,8 @@ func (s *Server) SubmitVoluntaryExit(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
val, err := headState.ValidatorAtIndexReadOnly(exit.Exit.ValidatorIndex)
|
||||
if err != nil {
|
||||
if outOfRangeErr, ok := err.(*state_native.ValidatorIndexOutOfRangeError); ok {
|
||||
http2.HandleError(w, "Could not get exiting validator: "+outOfRangeErr.Error(), http.StatusBadRequest)
|
||||
if errors.Is(err, consensus_types.ErrOutOfBounds) {
|
||||
http2.HandleError(w, "Could not get validator: "+err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
http2.HandleError(w, "Could not get validator: "+err.Error(), http.StatusInternalServerError)
|
||||
|
||||
@@ -485,7 +485,7 @@ func TestSubmitVoluntaryExit(t *testing.T) {
|
||||
e := &http2.DefaultErrorJson{}
|
||||
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), e))
|
||||
assert.Equal(t, http.StatusBadRequest, e.Code)
|
||||
assert.Equal(t, true, strings.Contains(e.Message, "Could not get exiting validator"))
|
||||
assert.Equal(t, true, strings.Contains(e.Message, "Could not get validator"))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -108,8 +108,8 @@ func TestGetStateRoot(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetRandao(t *testing.T) {
|
||||
mixCurrent := bytesutil.PadTo([]byte("current"), 32)
|
||||
mixOld := bytesutil.PadTo([]byte("old"), 32)
|
||||
mixCurrent := bytesutil.ToBytes32([]byte("current"))
|
||||
mixOld := bytesutil.ToBytes32([]byte("old"))
|
||||
epochCurrent := primitives.Epoch(100000)
|
||||
epochOld := 100000 - params.BeaconConfig().EpochsPerHistoricalVector + 1
|
||||
|
||||
@@ -125,7 +125,7 @@ func TestGetRandao(t *testing.T) {
|
||||
headSt, err := util.NewBeaconState()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, headSt.SetSlot(params.BeaconConfig().SlotsPerEpoch))
|
||||
headRandao := bytesutil.PadTo([]byte("head"), 32)
|
||||
headRandao := bytesutil.ToBytes32([]byte("head"))
|
||||
require.NoError(t, headSt.UpdateRandaoMixesAtIndex(uint64(headEpoch), headRandao))
|
||||
|
||||
db := dbTest.SetupDB(t)
|
||||
@@ -143,17 +143,17 @@ func TestGetRandao(t *testing.T) {
|
||||
t.Run("no epoch requested", func(t *testing.T) {
|
||||
resp, err := server.GetRandao(ctx, ð2.RandaoRequest{StateId: []byte("head")})
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, mixCurrent, resp.Data.Randao)
|
||||
assert.DeepEqual(t, mixCurrent[:], resp.Data.Randao)
|
||||
})
|
||||
t.Run("current epoch requested", func(t *testing.T) {
|
||||
resp, err := server.GetRandao(ctx, ð2.RandaoRequest{StateId: []byte("head"), Epoch: &epochCurrent})
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, mixCurrent, resp.Data.Randao)
|
||||
assert.DeepEqual(t, mixCurrent[:], resp.Data.Randao)
|
||||
})
|
||||
t.Run("old epoch requested", func(t *testing.T) {
|
||||
resp, err := server.GetRandao(ctx, ð2.RandaoRequest{StateId: []byte("head"), Epoch: &epochOld})
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, mixOld, resp.Data.Randao)
|
||||
assert.DeepEqual(t, mixOld[:], resp.Data.Randao)
|
||||
})
|
||||
t.Run("head state below `EpochsPerHistoricalVector`", func(t *testing.T) {
|
||||
server.Stater = &testutil.MockStater{
|
||||
@@ -161,7 +161,7 @@ func TestGetRandao(t *testing.T) {
|
||||
}
|
||||
resp, err := server.GetRandao(ctx, ð2.RandaoRequest{StateId: []byte("head")})
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, headRandao, resp.Data.Randao)
|
||||
assert.DeepEqual(t, headRandao[:], resp.Data.Randao)
|
||||
})
|
||||
t.Run("epoch too old", func(t *testing.T) {
|
||||
epochTooOld := primitives.Epoch(100000 - st.RandaoMixesLength())
|
||||
|
||||
@@ -29,10 +29,10 @@ go_library(
|
||||
"//beacon-chain/rpc/eth/shared:go_default_library",
|
||||
"//beacon-chain/rpc/lookup:go_default_library",
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//beacon-chain/state/state-native:go_default_library",
|
||||
"//beacon-chain/sync:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//consensus-types/validator:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
|
||||
@@ -24,9 +24,9 @@ import (
|
||||
rpchelpers "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||
state_native "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
consensus_types "github.com/prysmaticlabs/prysm/v4/consensus-types"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
validator2 "github.com/prysmaticlabs/prysm/v4/consensus-types/validator"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
@@ -339,8 +339,8 @@ func (s *Server) SubmitBeaconCommitteeSubscription(w http.ResponseWriter, r *htt
|
||||
subscriptions[i] = consensusItem
|
||||
val, err := st.ValidatorAtIndexReadOnly(consensusItem.ValidatorIndex)
|
||||
if err != nil {
|
||||
if outOfRangeErr, ok := err.(*state_native.ValidatorIndexOutOfRangeError); ok {
|
||||
http2.HandleError(w, "Could not get validator: "+outOfRangeErr.Error(), http.StatusBadRequest)
|
||||
if errors.Is(err, consensus_types.ErrOutOfBounds) {
|
||||
http2.HandleError(w, "Could not get validator: "+err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
http2.HandleError(w, "Could not get validator: "+err.Error(), http.StatusInternalServerError)
|
||||
|
||||
@@ -7,12 +7,11 @@ go_library(
|
||||
"field_trie_helpers.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/fieldtrie",
|
||||
visibility = ["//beacon-chain:__subpackages__"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//beacon-chain/state/state-native/custom-types:go_default_library",
|
||||
"//beacon-chain/state/state-native/types:go_default_library",
|
||||
"//beacon-chain/state/stateutil:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//math:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
|
||||
@@ -31,11 +31,11 @@ type FieldTrie struct {
|
||||
// NewFieldTrie is the constructor for the field trie data structure. It creates the corresponding
|
||||
// trie according to the given parameters. Depending on whether the field is a basic/composite array
|
||||
// which is either fixed/variable length, it will appropriately determine the trie.
|
||||
func NewFieldTrie(field types.FieldIndex, dataType types.DataType, elements interface{}, length uint64) (*FieldTrie, error) {
|
||||
func NewFieldTrie(field types.FieldIndex, fieldInfo types.DataType, elements interface{}, length uint64) (*FieldTrie, error) {
|
||||
if elements == nil {
|
||||
return &FieldTrie{
|
||||
field: field,
|
||||
dataType: dataType,
|
||||
dataType: fieldInfo,
|
||||
reference: stateutil.NewRef(1),
|
||||
RWMutex: new(sync.RWMutex),
|
||||
length: length,
|
||||
@@ -48,10 +48,10 @@ func NewFieldTrie(field types.FieldIndex, dataType types.DataType, elements inte
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := validateElements(field, dataType, elements, length); err != nil {
|
||||
if err := validateElements(field, fieldInfo, elements, length); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch dataType {
|
||||
switch fieldInfo {
|
||||
case types.BasicArray:
|
||||
fl, err := stateutil.ReturnTrieLayer(fieldRoots, length)
|
||||
if err != nil {
|
||||
@@ -60,7 +60,7 @@ func NewFieldTrie(field types.FieldIndex, dataType types.DataType, elements inte
|
||||
return &FieldTrie{
|
||||
fieldLayers: fl,
|
||||
field: field,
|
||||
dataType: dataType,
|
||||
dataType: fieldInfo,
|
||||
reference: stateutil.NewRef(1),
|
||||
RWMutex: new(sync.RWMutex),
|
||||
length: length,
|
||||
@@ -70,14 +70,14 @@ func NewFieldTrie(field types.FieldIndex, dataType types.DataType, elements inte
|
||||
return &FieldTrie{
|
||||
fieldLayers: stateutil.ReturnTrieLayerVariable(fieldRoots, length),
|
||||
field: field,
|
||||
dataType: dataType,
|
||||
dataType: fieldInfo,
|
||||
reference: stateutil.NewRef(1),
|
||||
RWMutex: new(sync.RWMutex),
|
||||
length: length,
|
||||
numOfElems: reflect.Indirect(reflect.ValueOf(elements)).Len(),
|
||||
}, nil
|
||||
default:
|
||||
return nil, errors.Errorf("unrecognized data type in field map: %v", reflect.TypeOf(dataType).Name())
|
||||
return nil, errors.Errorf("unrecognized data type in field map: %v", reflect.TypeOf(fieldInfo).Name())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
customtypes "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/custom-types"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/types"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stateutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
pmath "github.com/prysmaticlabs/prysm/v4/math"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
)
|
||||
@@ -46,8 +45,8 @@ func (f *FieldTrie) validateIndices(idxs []uint64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateElements(field types.FieldIndex, dataType types.DataType, elements interface{}, length uint64) error {
|
||||
if dataType == types.CompressedArray {
|
||||
func validateElements(field types.FieldIndex, fieldInfo types.DataType, elements interface{}, length uint64) error {
|
||||
if fieldInfo == types.CompressedArray {
|
||||
comLength, err := field.ElemsInChunk()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -65,11 +64,11 @@ func validateElements(field types.FieldIndex, dataType types.DataType, elements
|
||||
func fieldConverters(field types.FieldIndex, indices []uint64, elements interface{}, convertAll bool) ([][32]byte, error) {
|
||||
switch field {
|
||||
case types.BlockRoots:
|
||||
return convertBlockRoots(indices, elements, convertAll)
|
||||
return convert32ByteArrays[customtypes.BlockRoots](indices, elements, convertAll)
|
||||
case types.StateRoots:
|
||||
return convertStateRoots(indices, elements, convertAll)
|
||||
return convert32ByteArrays[customtypes.StateRoots](indices, elements, convertAll)
|
||||
case types.RandaoMixes:
|
||||
return convertRandaoMixes(indices, elements, convertAll)
|
||||
return convert32ByteArrays[customtypes.RandaoMixes](indices, elements, convertAll)
|
||||
case types.Eth1DataVotes:
|
||||
return convertEth1DataVotes(indices, elements, convertAll)
|
||||
case types.Validators:
|
||||
@@ -83,37 +82,13 @@ func fieldConverters(field types.FieldIndex, indices []uint64, elements interfac
|
||||
}
|
||||
}
|
||||
|
||||
func convertBlockRoots(indices []uint64, elements interface{}, convertAll bool) ([][32]byte, error) {
|
||||
switch val := elements.(type) {
|
||||
case [][]byte:
|
||||
return handleByteArrays(val, indices, convertAll)
|
||||
case *customtypes.BlockRoots:
|
||||
return handle32ByteArrays(val[:], indices, convertAll)
|
||||
default:
|
||||
return nil, errors.Errorf("Incorrect type used for block roots")
|
||||
}
|
||||
}
|
||||
|
||||
func convertStateRoots(indices []uint64, elements interface{}, convertAll bool) ([][32]byte, error) {
|
||||
switch val := elements.(type) {
|
||||
case [][]byte:
|
||||
return handleByteArrays(val, indices, convertAll)
|
||||
case *customtypes.StateRoots:
|
||||
return handle32ByteArrays(val[:], indices, convertAll)
|
||||
default:
|
||||
return nil, errors.Errorf("Incorrect type used for state roots")
|
||||
}
|
||||
}
|
||||
|
||||
func convertRandaoMixes(indices []uint64, elements interface{}, convertAll bool) ([][32]byte, error) {
|
||||
switch val := elements.(type) {
|
||||
case [][]byte:
|
||||
return handleByteArrays(val, indices, convertAll)
|
||||
case *customtypes.RandaoMixes:
|
||||
return handle32ByteArrays(val[:], indices, convertAll)
|
||||
default:
|
||||
return nil, errors.Errorf("Incorrect type used for randao mixes")
|
||||
func convert32ByteArrays[T ~[][32]byte](indices []uint64, elements interface{}, convertAll bool) ([][32]byte, error) {
|
||||
val, ok := elements.(T)
|
||||
if !ok {
|
||||
var t T
|
||||
return nil, errors.Errorf("Wanted type of %T but got %T", t, elements)
|
||||
}
|
||||
return handle32ByteArrays(val, indices, convertAll)
|
||||
}
|
||||
|
||||
func convertEth1DataVotes(indices []uint64, elements interface{}, convertAll bool) ([][32]byte, error) {
|
||||
@@ -148,34 +123,6 @@ func convertBalances(indices []uint64, elements interface{}, convertAll bool) ([
|
||||
return handleBalanceSlice(val, indices, convertAll)
|
||||
}
|
||||
|
||||
// handleByteArrays computes and returns byte arrays in a slice of root format.
|
||||
func handleByteArrays(val [][]byte, indices []uint64, convertAll bool) ([][32]byte, error) {
|
||||
length := len(indices)
|
||||
if convertAll {
|
||||
length = len(val)
|
||||
}
|
||||
roots := make([][32]byte, 0, length)
|
||||
rootCreator := func(input []byte) {
|
||||
newRoot := bytesutil.ToBytes32(input)
|
||||
roots = append(roots, newRoot)
|
||||
}
|
||||
if convertAll {
|
||||
for i := range val {
|
||||
rootCreator(val[i])
|
||||
}
|
||||
return roots, nil
|
||||
}
|
||||
if len(val) > 0 {
|
||||
for _, idx := range indices {
|
||||
if idx > uint64(len(val))-1 {
|
||||
return nil, fmt.Errorf("index %d greater than number of byte arrays %d", idx, len(val))
|
||||
}
|
||||
rootCreator(val[idx])
|
||||
}
|
||||
}
|
||||
return roots, nil
|
||||
}
|
||||
|
||||
// handle32ByteArrays computes and returns 32 byte arrays in a slice of root format.
|
||||
func handle32ByteArrays(val [][32]byte, indices []uint64, convertAll bool) ([][32]byte, error) {
|
||||
length := len(indices)
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/fieldtrie"
|
||||
customtypes "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/custom-types"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/types"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stateutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
@@ -16,11 +17,15 @@ import (
|
||||
|
||||
func TestFieldTrie_NewTrie(t *testing.T) {
|
||||
newState, _ := util.DeterministicGenesisState(t, 40)
|
||||
roots := newState.BlockRoots()
|
||||
blockRoots := make([][32]byte, len(roots))
|
||||
for i, r := range roots {
|
||||
blockRoots[i] = [32]byte(r)
|
||||
}
|
||||
|
||||
// 5 represents the enum value of state roots
|
||||
trie, err := fieldtrie.NewFieldTrie(types.FieldIndex(5), types.BasicArray, newState.StateRoots(), uint64(params.BeaconConfig().SlotsPerHistoricalRoot))
|
||||
trie, err := fieldtrie.NewFieldTrie(types.BlockRoots, types.BasicArray, customtypes.BlockRoots(blockRoots), uint64(params.BeaconConfig().SlotsPerHistoricalRoot))
|
||||
require.NoError(t, err)
|
||||
root, err := stateutil.RootsArrayHashTreeRoot(newState.StateRoots(), uint64(params.BeaconConfig().SlotsPerHistoricalRoot))
|
||||
root, err := stateutil.RootsArrayHashTreeRoot(newState.BlockRoots(), uint64(params.BeaconConfig().SlotsPerHistoricalRoot))
|
||||
require.NoError(t, err)
|
||||
newRoot, err := trie.TrieRoot()
|
||||
require.NoError(t, err)
|
||||
@@ -28,7 +33,7 @@ func TestFieldTrie_NewTrie(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFieldTrie_NewTrie_NilElements(t *testing.T) {
|
||||
trie, err := fieldtrie.NewFieldTrie(types.FieldIndex(5), types.BasicArray, nil, 8234)
|
||||
trie, err := fieldtrie.NewFieldTrie(types.BlockRoots, types.BasicArray, nil, 8234)
|
||||
require.NoError(t, err)
|
||||
_, err = trie.TrieRoot()
|
||||
require.ErrorIs(t, err, fieldtrie.ErrEmptyFieldTrie)
|
||||
@@ -36,8 +41,7 @@ func TestFieldTrie_NewTrie_NilElements(t *testing.T) {
|
||||
|
||||
func TestFieldTrie_RecomputeTrie(t *testing.T) {
|
||||
newState, _ := util.DeterministicGenesisState(t, 32)
|
||||
// 10 represents the enum value of validators
|
||||
trie, err := fieldtrie.NewFieldTrie(types.FieldIndex(11), types.CompositeArray, newState.Validators(), params.BeaconConfig().ValidatorRegistryLimit)
|
||||
trie, err := fieldtrie.NewFieldTrie(types.Validators, types.CompositeArray, newState.Validators(), params.BeaconConfig().ValidatorRegistryLimit)
|
||||
require.NoError(t, err)
|
||||
|
||||
oldroot, err := trie.TrieRoot()
|
||||
@@ -68,7 +72,7 @@ func TestFieldTrie_RecomputeTrie(t *testing.T) {
|
||||
|
||||
func TestFieldTrie_RecomputeTrie_CompressedArray(t *testing.T) {
|
||||
newState, _ := util.DeterministicGenesisState(t, 32)
|
||||
trie, err := fieldtrie.NewFieldTrie(types.FieldIndex(12), types.CompressedArray, newState.Balances(), stateutil.ValidatorLimitForBalancesChunks())
|
||||
trie, err := fieldtrie.NewFieldTrie(types.Balances, types.CompressedArray, newState.Balances(), stateutil.ValidatorLimitForBalancesChunks())
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, trie.Length(), stateutil.ValidatorLimitForBalancesChunks())
|
||||
changedIdx := []uint64{4, 8}
|
||||
@@ -85,14 +89,19 @@ func TestFieldTrie_RecomputeTrie_CompressedArray(t *testing.T) {
|
||||
|
||||
func TestNewFieldTrie_UnknownType(t *testing.T) {
|
||||
newState, _ := util.DeterministicGenesisState(t, 32)
|
||||
_, err := fieldtrie.NewFieldTrie(types.FieldIndex(12), 4, newState.Balances(), 32)
|
||||
_, err := fieldtrie.NewFieldTrie(types.Balances, 4, newState.Balances(), 32)
|
||||
require.ErrorContains(t, "unrecognized data type", err)
|
||||
}
|
||||
|
||||
func TestFieldTrie_CopyTrieImmutable(t *testing.T) {
|
||||
newState, _ := util.DeterministicGenesisState(t, 32)
|
||||
// 12 represents the enum value of randao mixes.
|
||||
trie, err := fieldtrie.NewFieldTrie(types.FieldIndex(13), types.BasicArray, newState.RandaoMixes(), uint64(params.BeaconConfig().EpochsPerHistoricalVector))
|
||||
mixes := newState.RandaoMixes()
|
||||
randaoMixes := make([][32]byte, len(mixes))
|
||||
for i, r := range mixes {
|
||||
randaoMixes[i] = [32]byte(r)
|
||||
}
|
||||
|
||||
trie, err := fieldtrie.NewFieldTrie(types.RandaoMixes, types.BasicArray, customtypes.RandaoMixes(randaoMixes), uint64(params.BeaconConfig().EpochsPerHistoricalVector))
|
||||
require.NoError(t, err)
|
||||
|
||||
newTrie := trie.CopyTrie()
|
||||
@@ -100,10 +109,15 @@ func TestFieldTrie_CopyTrieImmutable(t *testing.T) {
|
||||
changedIdx := []uint64{2, 29}
|
||||
|
||||
changedVals := [][32]byte{{'A', 'B'}, {'C', 'D'}}
|
||||
require.NoError(t, newState.UpdateRandaoMixesAtIndex(changedIdx[0], changedVals[0][:]))
|
||||
require.NoError(t, newState.UpdateRandaoMixesAtIndex(changedIdx[1], changedVals[1][:]))
|
||||
require.NoError(t, newState.UpdateRandaoMixesAtIndex(changedIdx[0], changedVals[0]))
|
||||
require.NoError(t, newState.UpdateRandaoMixesAtIndex(changedIdx[1], changedVals[1]))
|
||||
|
||||
root, err := trie.RecomputeTrie(changedIdx, newState.RandaoMixes())
|
||||
mixes = newState.RandaoMixes()
|
||||
randaoMixes = make([][32]byte, len(mixes))
|
||||
for i, r := range mixes {
|
||||
randaoMixes[i] = [32]byte(r)
|
||||
}
|
||||
root, err := trie.RecomputeTrie(changedIdx, customtypes.RandaoMixes(randaoMixes))
|
||||
require.NoError(t, err)
|
||||
newRoot, err := newTrie.TrieRoot()
|
||||
require.NoError(t, err)
|
||||
@@ -113,7 +127,7 @@ func TestFieldTrie_CopyTrieImmutable(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFieldTrie_CopyAndTransferEmpty(t *testing.T) {
|
||||
trie, err := fieldtrie.NewFieldTrie(types.FieldIndex(13), types.BasicArray, nil, uint64(params.BeaconConfig().EpochsPerHistoricalVector))
|
||||
trie, err := fieldtrie.NewFieldTrie(types.RandaoMixes, types.BasicArray, nil, uint64(params.BeaconConfig().EpochsPerHistoricalVector))
|
||||
require.NoError(t, err)
|
||||
|
||||
require.DeepEqual(t, trie, trie.CopyTrie())
|
||||
@@ -123,7 +137,7 @@ func TestFieldTrie_CopyAndTransferEmpty(t *testing.T) {
|
||||
func TestFieldTrie_TransferTrie(t *testing.T) {
|
||||
newState, _ := util.DeterministicGenesisState(t, 32)
|
||||
maxLength := (params.BeaconConfig().ValidatorRegistryLimit*8 + 31) / 32
|
||||
trie, err := fieldtrie.NewFieldTrie(types.FieldIndex(12), types.CompressedArray, newState.Balances(), maxLength)
|
||||
trie, err := fieldtrie.NewFieldTrie(types.Balances, types.CompressedArray, newState.Balances(), maxLength)
|
||||
require.NoError(t, err)
|
||||
oldRoot, err := trie.TrieRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -103,22 +103,12 @@ func TestFieldTrie_NativeState_fieldConvertersNative(t *testing.T) {
|
||||
errMsg string
|
||||
expectedLength int
|
||||
}{
|
||||
{
|
||||
name: "BlockRoots [][]bytes",
|
||||
args: &args{
|
||||
field: types.FieldIndex(5),
|
||||
indices: []uint64{},
|
||||
elements: [][]byte{[]byte("dfsadfsadf")},
|
||||
convertAll: true,
|
||||
},
|
||||
wantHex: []string{"0x6466736164667361646600000000000000000000000000000000000000000000"},
|
||||
},
|
||||
{
|
||||
name: "BlockRoots customtypes.BlockRoots",
|
||||
args: &args{
|
||||
field: types.FieldIndex(5),
|
||||
indices: []uint64{},
|
||||
elements: &customtypes.BlockRoots{},
|
||||
elements: customtypes.BlockRoots{},
|
||||
convertAll: true,
|
||||
},
|
||||
wantHex: []string{"0x0000000000000000000000000000000000000000000000000000000000000000"},
|
||||
@@ -133,34 +123,14 @@ func TestFieldTrie_NativeState_fieldConvertersNative(t *testing.T) {
|
||||
convertAll: true,
|
||||
},
|
||||
wantHex: nil,
|
||||
errMsg: "Incorrect type used for block roots",
|
||||
},
|
||||
{
|
||||
name: "BlockRoots [][]bytes",
|
||||
args: &args{
|
||||
field: types.FieldIndex(5),
|
||||
indices: []uint64{},
|
||||
elements: [][]byte{[]byte("dfsadfsadf")},
|
||||
convertAll: true,
|
||||
},
|
||||
wantHex: []string{"0x6466736164667361646600000000000000000000000000000000000000000000"},
|
||||
},
|
||||
{
|
||||
name: "StateRoots [][]bytes",
|
||||
args: &args{
|
||||
field: types.FieldIndex(6),
|
||||
indices: []uint64{},
|
||||
elements: [][]byte{[]byte("dfsadfsadf")},
|
||||
convertAll: true,
|
||||
},
|
||||
wantHex: []string{"0x6466736164667361646600000000000000000000000000000000000000000000"},
|
||||
errMsg: "Wanted type of customtypes.BlockRoots",
|
||||
},
|
||||
{
|
||||
name: "StateRoots customtypes.StateRoots",
|
||||
args: &args{
|
||||
field: types.FieldIndex(6),
|
||||
indices: []uint64{},
|
||||
elements: &customtypes.StateRoots{},
|
||||
elements: customtypes.StateRoots{},
|
||||
convertAll: true,
|
||||
},
|
||||
wantHex: []string{"0x0000000000000000000000000000000000000000000000000000000000000000"},
|
||||
@@ -175,45 +145,25 @@ func TestFieldTrie_NativeState_fieldConvertersNative(t *testing.T) {
|
||||
convertAll: true,
|
||||
},
|
||||
wantHex: nil,
|
||||
errMsg: "Incorrect type used for state roots",
|
||||
},
|
||||
{
|
||||
name: "StateRoots [][]bytes convert all false",
|
||||
args: &args{
|
||||
field: types.FieldIndex(6),
|
||||
indices: []uint64{},
|
||||
elements: [][]byte{[]byte("dfsadfsadf")},
|
||||
convertAll: false,
|
||||
},
|
||||
wantHex: []string{"0x6466736164667361646600000000000000000000000000000000000000000000"},
|
||||
errMsg: "Wanted type of customtypes.StateRoots",
|
||||
},
|
||||
{
|
||||
name: "StateRoots customtypes.StateRoots convert all false",
|
||||
args: &args{
|
||||
field: types.FieldIndex(6),
|
||||
indices: []uint64{},
|
||||
elements: &customtypes.StateRoots{},
|
||||
elements: customtypes.StateRoots{},
|
||||
convertAll: false,
|
||||
},
|
||||
wantHex: []string{"0x0000000000000000000000000000000000000000000000000000000000000000"},
|
||||
expectedLength: 8192,
|
||||
},
|
||||
{
|
||||
name: "RandaoMixes [][]bytes",
|
||||
args: &args{
|
||||
field: types.FieldIndex(13),
|
||||
indices: []uint64{},
|
||||
elements: [][]byte{[]byte("dfsadfsadf")},
|
||||
convertAll: true,
|
||||
},
|
||||
wantHex: []string{"0x6466736164667361646600000000000000000000000000000000000000000000"},
|
||||
},
|
||||
{
|
||||
name: "RandaoMixes customtypes.RandaoMixes",
|
||||
args: &args{
|
||||
field: types.FieldIndex(13),
|
||||
indices: []uint64{},
|
||||
elements: &customtypes.RandaoMixes{},
|
||||
elements: customtypes.RandaoMixes{},
|
||||
convertAll: true,
|
||||
},
|
||||
wantHex: []string{"0x0000000000000000000000000000000000000000000000000000000000000000"},
|
||||
@@ -228,7 +178,7 @@ func TestFieldTrie_NativeState_fieldConvertersNative(t *testing.T) {
|
||||
convertAll: true,
|
||||
},
|
||||
wantHex: nil,
|
||||
errMsg: "Incorrect type used for randao mixes",
|
||||
errMsg: "Wanted type of customtypes.RandaoMixes",
|
||||
},
|
||||
{
|
||||
name: "Eth1DataVotes type not found",
|
||||
|
||||
@@ -237,7 +237,7 @@ type WriteOnlyBalances interface {
|
||||
// WriteOnlyRandaoMixes defines a struct which only has write access to randao mixes methods.
|
||||
type WriteOnlyRandaoMixes interface {
|
||||
SetRandaoMixes(val [][]byte) error
|
||||
UpdateRandaoMixesAtIndex(idx uint64, val []byte) error
|
||||
UpdateRandaoMixesAtIndex(idx uint64, val [32]byte) error
|
||||
}
|
||||
|
||||
// WriteOnlyCheckpoint defines a struct which only has write access to check point methods.
|
||||
|
||||
@@ -18,6 +18,7 @@ go_library(
|
||||
"getters_validator.go",
|
||||
"getters_withdrawal.go",
|
||||
"hasher.go",
|
||||
"multi_value_slices.go",
|
||||
"proofs.go",
|
||||
"readonly_validator.go",
|
||||
"setters_attestation.go",
|
||||
@@ -49,11 +50,14 @@ go_library(
|
||||
"//beacon-chain/state/state-native/custom-types:go_default_library",
|
||||
"//beacon-chain/state/state-native/types:go_default_library",
|
||||
"//beacon-chain/state/stateutil:go_default_library",
|
||||
"//config/features:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types:go_default_library",
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//container/multi-value-slice:go_default_library",
|
||||
"//container/slice:go_default_library",
|
||||
"//crypto/hash:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
@@ -64,6 +68,8 @@ go_library(
|
||||
"//runtime/version:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
|
||||
"@com_github_prysmaticlabs_fastssz//:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
||||
"@io_opencensus_go//trace:go_default_library",
|
||||
@@ -82,6 +88,7 @@ go_test(
|
||||
"getters_validator_test.go",
|
||||
"getters_withdrawal_test.go",
|
||||
"hasher_test.go",
|
||||
"mvslice_fuzz_test.go",
|
||||
"proofs_test.go",
|
||||
"readonly_validator_test.go",
|
||||
"references_test.go",
|
||||
@@ -96,6 +103,7 @@ go_test(
|
||||
"state_trie_test.go",
|
||||
"types_test.go",
|
||||
],
|
||||
data = glob(["testdata/**"]),
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//beacon-chain/core/transition:go_default_library",
|
||||
@@ -103,6 +111,7 @@ go_test(
|
||||
"//beacon-chain/state/state-native/types:go_default_library",
|
||||
"//beacon-chain/state/stateutil:go_default_library",
|
||||
"//beacon-chain/state/testing:go_default_library",
|
||||
"//config/features:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
customtypes "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/custom-types"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/types"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stateutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
@@ -25,16 +26,21 @@ type BeaconState struct {
|
||||
slot primitives.Slot
|
||||
fork *ethpb.Fork
|
||||
latestBlockHeader *ethpb.BeaconBlockHeader
|
||||
blockRoots *customtypes.BlockRoots
|
||||
stateRoots *customtypes.StateRoots
|
||||
blockRoots customtypes.BlockRoots
|
||||
blockRootsMultiValue *MultiValueBlockRoots
|
||||
stateRoots customtypes.StateRoots
|
||||
stateRootsMultiValue *MultiValueStateRoots
|
||||
historicalRoots customtypes.HistoricalRoots
|
||||
historicalSummaries []*ethpb.HistoricalSummary
|
||||
eth1Data *ethpb.Eth1Data
|
||||
eth1DataVotes []*ethpb.Eth1Data
|
||||
eth1DepositIndex uint64
|
||||
validators []*ethpb.Validator
|
||||
validatorsMultiValue *MultiValueValidators
|
||||
balances []uint64
|
||||
randaoMixes *customtypes.RandaoMixes
|
||||
balancesMultiValue *MultiValueBalances
|
||||
randaoMixes customtypes.RandaoMixes
|
||||
randaoMixesMultiValue *MultiValueRandaoMixes
|
||||
slashings []uint64
|
||||
previousEpochAttestations []*ethpb.PendingAttestation
|
||||
currentEpochAttestations []*ethpb.PendingAttestation
|
||||
@@ -45,6 +51,7 @@ type BeaconState struct {
|
||||
currentJustifiedCheckpoint *ethpb.Checkpoint
|
||||
finalizedCheckpoint *ethpb.Checkpoint
|
||||
inactivityScores []uint64
|
||||
inactivityScoresMultiValue *MultiValueInactivityScores
|
||||
currentSyncCommittee *ethpb.SyncCommittee
|
||||
nextSyncCommittee *ethpb.SyncCommittee
|
||||
latestExecutionPayloadHeader *enginev1.ExecutionPayloadHeader
|
||||
@@ -53,6 +60,7 @@ type BeaconState struct {
|
||||
nextWithdrawalIndex uint64
|
||||
nextWithdrawalValidatorIndex primitives.ValidatorIndex
|
||||
|
||||
id uint64
|
||||
lock sync.RWMutex
|
||||
dirtyFields map[types.FieldIndex]bool
|
||||
dirtyIndices map[types.FieldIndex][]uint64
|
||||
@@ -70,8 +78,8 @@ type beaconStateMarshalable struct {
|
||||
Slot primitives.Slot `json:"slot" yaml:"slot"`
|
||||
Fork *ethpb.Fork `json:"fork" yaml:"fork"`
|
||||
LatestBlockHeader *ethpb.BeaconBlockHeader `json:"latest_block_header" yaml:"latest_block_header"`
|
||||
BlockRoots *customtypes.BlockRoots `json:"block_roots" yaml:"block_roots"`
|
||||
StateRoots *customtypes.StateRoots `json:"state_roots" yaml:"state_roots"`
|
||||
BlockRoots customtypes.BlockRoots `json:"block_roots" yaml:"block_roots"`
|
||||
StateRoots customtypes.StateRoots `json:"state_roots" yaml:"state_roots"`
|
||||
HistoricalRoots customtypes.HistoricalRoots `json:"historical_roots" yaml:"historical_roots"`
|
||||
HistoricalSummaries []*ethpb.HistoricalSummary `json:"historical_summaries" yaml:"historical_summaries"`
|
||||
Eth1Data *ethpb.Eth1Data `json:"eth_1_data" yaml:"eth_1_data"`
|
||||
@@ -79,7 +87,7 @@ type beaconStateMarshalable struct {
|
||||
Eth1DepositIndex uint64 `json:"eth_1_deposit_index" yaml:"eth_1_deposit_index"`
|
||||
Validators []*ethpb.Validator `json:"validators" yaml:"validators"`
|
||||
Balances []uint64 `json:"balances" yaml:"balances"`
|
||||
RandaoMixes *customtypes.RandaoMixes `json:"randao_mixes" yaml:"randao_mixes"`
|
||||
RandaoMixes customtypes.RandaoMixes `json:"randao_mixes" yaml:"randao_mixes"`
|
||||
Slashings []uint64 `json:"slashings" yaml:"slashings"`
|
||||
PreviousEpochAttestations []*ethpb.PendingAttestation `json:"previous_epoch_attestations" yaml:"previous_epoch_attestations"`
|
||||
CurrentEpochAttestations []*ethpb.PendingAttestation `json:"current_epoch_attestations" yaml:"current_epoch_attestations"`
|
||||
@@ -99,6 +107,29 @@ type beaconStateMarshalable struct {
|
||||
}
|
||||
|
||||
func (b *BeaconState) MarshalJSON() ([]byte, error) {
|
||||
var bRoots customtypes.BlockRoots
|
||||
var sRoots customtypes.StateRoots
|
||||
var mixes customtypes.RandaoMixes
|
||||
var balances []uint64
|
||||
var inactivityScores []uint64
|
||||
var vals []*ethpb.Validator
|
||||
|
||||
if features.Get().EnableExperimentalState {
|
||||
bRoots = b.blockRootsMultiValue.Value(b)
|
||||
sRoots = b.stateRootsMultiValue.Value(b)
|
||||
mixes = b.randaoMixesMultiValue.Value(b)
|
||||
balances = b.balancesMultiValue.Value(b)
|
||||
inactivityScores = b.inactivityScoresMultiValue.Value(b)
|
||||
vals = b.validatorsMultiValue.Value(b)
|
||||
} else {
|
||||
bRoots = b.blockRoots
|
||||
sRoots = b.stateRoots
|
||||
mixes = b.randaoMixes
|
||||
balances = b.balances
|
||||
inactivityScores = b.inactivityScores
|
||||
vals = b.validators
|
||||
}
|
||||
|
||||
marshalable := &beaconStateMarshalable{
|
||||
Version: b.version,
|
||||
GenesisTime: b.genesisTime,
|
||||
@@ -106,16 +137,16 @@ func (b *BeaconState) MarshalJSON() ([]byte, error) {
|
||||
Slot: b.slot,
|
||||
Fork: b.fork,
|
||||
LatestBlockHeader: b.latestBlockHeader,
|
||||
BlockRoots: b.blockRoots,
|
||||
StateRoots: b.stateRoots,
|
||||
BlockRoots: bRoots,
|
||||
StateRoots: sRoots,
|
||||
HistoricalRoots: b.historicalRoots,
|
||||
HistoricalSummaries: b.historicalSummaries,
|
||||
Eth1Data: b.eth1Data,
|
||||
Eth1DataVotes: b.eth1DataVotes,
|
||||
Eth1DepositIndex: b.eth1DepositIndex,
|
||||
Validators: b.validators,
|
||||
Balances: b.balances,
|
||||
RandaoMixes: b.randaoMixes,
|
||||
Validators: vals,
|
||||
Balances: balances,
|
||||
RandaoMixes: mixes,
|
||||
Slashings: b.slashings,
|
||||
PreviousEpochAttestations: b.previousEpochAttestations,
|
||||
CurrentEpochAttestations: b.currentEpochAttestations,
|
||||
@@ -125,7 +156,7 @@ func (b *BeaconState) MarshalJSON() ([]byte, error) {
|
||||
PreviousJustifiedCheckpoint: b.previousJustifiedCheckpoint,
|
||||
CurrentJustifiedCheckpoint: b.currentJustifiedCheckpoint,
|
||||
FinalizedCheckpoint: b.finalizedCheckpoint,
|
||||
InactivityScores: b.inactivityScores,
|
||||
InactivityScores: inactivityScores,
|
||||
CurrentSyncCommittee: b.currentSyncCommittee,
|
||||
NextSyncCommittee: b.nextSyncCommittee,
|
||||
LatestExecutionPayloadHeader: b.latestExecutionPayloadHeader,
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
customtypes "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/custom-types"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/types"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stateutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
@@ -25,16 +26,21 @@ type BeaconState struct {
|
||||
slot primitives.Slot
|
||||
fork *ethpb.Fork
|
||||
latestBlockHeader *ethpb.BeaconBlockHeader
|
||||
blockRoots *customtypes.BlockRoots
|
||||
stateRoots *customtypes.StateRoots
|
||||
blockRoots customtypes.BlockRoots
|
||||
blockRootsMultiValue *MultiValueBlockRoots
|
||||
stateRoots customtypes.StateRoots
|
||||
stateRootsMultiValue *MultiValueStateRoots
|
||||
historicalRoots customtypes.HistoricalRoots
|
||||
historicalSummaries []*ethpb.HistoricalSummary
|
||||
eth1Data *ethpb.Eth1Data
|
||||
eth1DataVotes []*ethpb.Eth1Data
|
||||
eth1DepositIndex uint64
|
||||
validators []*ethpb.Validator
|
||||
validatorsMultiValue *MultiValueValidators
|
||||
balances []uint64
|
||||
randaoMixes *customtypes.RandaoMixes
|
||||
balancesMultiValue *MultiValueBalances
|
||||
randaoMixes customtypes.RandaoMixes
|
||||
randaoMixesMultiValue *MultiValueRandaoMixes
|
||||
slashings []uint64
|
||||
previousEpochAttestations []*ethpb.PendingAttestation
|
||||
currentEpochAttestations []*ethpb.PendingAttestation
|
||||
@@ -45,6 +51,7 @@ type BeaconState struct {
|
||||
currentJustifiedCheckpoint *ethpb.Checkpoint
|
||||
finalizedCheckpoint *ethpb.Checkpoint
|
||||
inactivityScores []uint64
|
||||
inactivityScoresMultiValue *MultiValueInactivityScores
|
||||
currentSyncCommittee *ethpb.SyncCommittee
|
||||
nextSyncCommittee *ethpb.SyncCommittee
|
||||
latestExecutionPayloadHeader *enginev1.ExecutionPayloadHeader
|
||||
@@ -53,6 +60,7 @@ type BeaconState struct {
|
||||
nextWithdrawalIndex uint64
|
||||
nextWithdrawalValidatorIndex primitives.ValidatorIndex
|
||||
|
||||
id uint64
|
||||
lock sync.RWMutex
|
||||
dirtyFields map[types.FieldIndex]bool
|
||||
dirtyIndices map[types.FieldIndex][]uint64
|
||||
@@ -70,8 +78,8 @@ type beaconStateMarshalable struct {
|
||||
Slot primitives.Slot `json:"slot" yaml:"slot"`
|
||||
Fork *ethpb.Fork `json:"fork" yaml:"fork"`
|
||||
LatestBlockHeader *ethpb.BeaconBlockHeader `json:"latest_block_header" yaml:"latest_block_header"`
|
||||
BlockRoots *customtypes.BlockRoots `json:"block_roots" yaml:"block_roots"`
|
||||
StateRoots *customtypes.StateRoots `json:"state_roots" yaml:"state_roots"`
|
||||
BlockRoots customtypes.BlockRoots `json:"block_roots" yaml:"block_roots"`
|
||||
StateRoots customtypes.StateRoots `json:"state_roots" yaml:"state_roots"`
|
||||
HistoricalRoots customtypes.HistoricalRoots `json:"historical_roots" yaml:"historical_roots"`
|
||||
HistoricalSummaries []*ethpb.HistoricalSummary `json:"historical_summaries" yaml:"historical_summaries"`
|
||||
Eth1Data *ethpb.Eth1Data `json:"eth_1_data" yaml:"eth_1_data"`
|
||||
@@ -79,7 +87,7 @@ type beaconStateMarshalable struct {
|
||||
Eth1DepositIndex uint64 `json:"eth_1_deposit_index" yaml:"eth_1_deposit_index"`
|
||||
Validators []*ethpb.Validator `json:"validators" yaml:"validators"`
|
||||
Balances []uint64 `json:"balances" yaml:"balances"`
|
||||
RandaoMixes *customtypes.RandaoMixes `json:"randao_mixes" yaml:"randao_mixes"`
|
||||
RandaoMixes customtypes.RandaoMixes `json:"randao_mixes" yaml:"randao_mixes"`
|
||||
Slashings []uint64 `json:"slashings" yaml:"slashings"`
|
||||
PreviousEpochAttestations []*ethpb.PendingAttestation `json:"previous_epoch_attestations" yaml:"previous_epoch_attestations"`
|
||||
CurrentEpochAttestations []*ethpb.PendingAttestation `json:"current_epoch_attestations" yaml:"current_epoch_attestations"`
|
||||
@@ -99,6 +107,29 @@ type beaconStateMarshalable struct {
|
||||
}
|
||||
|
||||
func (b *BeaconState) MarshalJSON() ([]byte, error) {
|
||||
var bRoots customtypes.BlockRoots
|
||||
var sRoots customtypes.StateRoots
|
||||
var mixes customtypes.RandaoMixes
|
||||
var balances []uint64
|
||||
var inactivityScores []uint64
|
||||
var vals []*ethpb.Validator
|
||||
|
||||
if features.Get().EnableExperimentalState {
|
||||
bRoots = b.blockRootsMultiValue.Value(b)
|
||||
sRoots = b.stateRootsMultiValue.Value(b)
|
||||
mixes = b.randaoMixesMultiValue.Value(b)
|
||||
balances = b.balancesMultiValue.Value(b)
|
||||
inactivityScores = b.inactivityScoresMultiValue.Value(b)
|
||||
vals = b.validatorsMultiValue.Value(b)
|
||||
} else {
|
||||
bRoots = b.blockRoots
|
||||
sRoots = b.stateRoots
|
||||
mixes = b.randaoMixes
|
||||
balances = b.balances
|
||||
inactivityScores = b.inactivityScores
|
||||
vals = b.validators
|
||||
}
|
||||
|
||||
marshalable := &beaconStateMarshalable{
|
||||
Version: b.version,
|
||||
GenesisTime: b.genesisTime,
|
||||
@@ -106,16 +137,16 @@ func (b *BeaconState) MarshalJSON() ([]byte, error) {
|
||||
Slot: b.slot,
|
||||
Fork: b.fork,
|
||||
LatestBlockHeader: b.latestBlockHeader,
|
||||
BlockRoots: b.blockRoots,
|
||||
StateRoots: b.stateRoots,
|
||||
BlockRoots: bRoots,
|
||||
StateRoots: sRoots,
|
||||
HistoricalRoots: b.historicalRoots,
|
||||
HistoricalSummaries: b.historicalSummaries,
|
||||
Eth1Data: b.eth1Data,
|
||||
Eth1DataVotes: b.eth1DataVotes,
|
||||
Eth1DepositIndex: b.eth1DepositIndex,
|
||||
Validators: b.validators,
|
||||
Balances: b.balances,
|
||||
RandaoMixes: b.randaoMixes,
|
||||
Validators: vals,
|
||||
Balances: balances,
|
||||
RandaoMixes: mixes,
|
||||
Slashings: b.slashings,
|
||||
PreviousEpochAttestations: b.previousEpochAttestations,
|
||||
CurrentEpochAttestations: b.currentEpochAttestations,
|
||||
@@ -125,7 +156,7 @@ func (b *BeaconState) MarshalJSON() ([]byte, error) {
|
||||
PreviousJustifiedCheckpoint: b.previousJustifiedCheckpoint,
|
||||
CurrentJustifiedCheckpoint: b.currentJustifiedCheckpoint,
|
||||
FinalizedCheckpoint: b.finalizedCheckpoint,
|
||||
InactivityScores: b.inactivityScores,
|
||||
InactivityScores: inactivityScores,
|
||||
CurrentSyncCommittee: b.currentSyncCommittee,
|
||||
NextSyncCommittee: b.nextSyncCommittee,
|
||||
LatestExecutionPayloadHeader: b.latestExecutionPayloadHeader,
|
||||
|
||||
@@ -7,12 +7,12 @@ import (
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
)
|
||||
|
||||
var _ fssz.HashRoot = (BlockRoots)([fieldparams.BlockRootsLength][32]byte{})
|
||||
var _ fssz.HashRoot = (BlockRoots)([][32]byte{})
|
||||
var _ fssz.Marshaler = (*BlockRoots)(nil)
|
||||
var _ fssz.Unmarshaler = (*BlockRoots)(nil)
|
||||
|
||||
// BlockRoots represents block roots of the beacon state.
|
||||
type BlockRoots [fieldparams.BlockRootsLength][32]byte
|
||||
type BlockRoots [][32]byte
|
||||
|
||||
// HashTreeRoot returns calculated hash root.
|
||||
func (r BlockRoots) HashTreeRoot() ([32]byte, error) {
|
||||
@@ -35,7 +35,7 @@ func (r *BlockRoots) UnmarshalSSZ(buf []byte) error {
|
||||
return fmt.Errorf("expected buffer of length %d received %d", r.SizeSSZ(), len(buf))
|
||||
}
|
||||
|
||||
var roots BlockRoots
|
||||
roots := BlockRoots(make([][32]byte, fieldparams.BlockRootsLength))
|
||||
for i := range roots {
|
||||
copy(roots[i][:], buf[i*32:(i+1)*32])
|
||||
}
|
||||
@@ -44,7 +44,7 @@ func (r *BlockRoots) UnmarshalSSZ(buf []byte) error {
|
||||
}
|
||||
|
||||
// MarshalSSZTo marshals BlockRoots with the provided byte slice.
|
||||
func (r *BlockRoots) MarshalSSZTo(dst []byte) ([]byte, error) {
|
||||
func (r BlockRoots) MarshalSSZTo(dst []byte) ([]byte, error) {
|
||||
marshalled, err := r.MarshalSSZ()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -53,7 +53,7 @@ func (r *BlockRoots) MarshalSSZTo(dst []byte) ([]byte, error) {
|
||||
}
|
||||
|
||||
// MarshalSSZ marshals BlockRoots into a serialized object.
|
||||
func (r *BlockRoots) MarshalSSZ() ([]byte, error) {
|
||||
func (r BlockRoots) MarshalSSZ() ([]byte, error) {
|
||||
marshalled := make([]byte, fieldparams.BlockRootsLength*32)
|
||||
for i, r32 := range r {
|
||||
for j, rr := range r32 {
|
||||
@@ -64,12 +64,13 @@ func (r *BlockRoots) MarshalSSZ() ([]byte, error) {
|
||||
}
|
||||
|
||||
// SizeSSZ returns the size of the serialized object.
|
||||
func (_ *BlockRoots) SizeSSZ() int {
|
||||
func (_ BlockRoots) SizeSSZ() int {
|
||||
return fieldparams.BlockRootsLength * 32
|
||||
}
|
||||
|
||||
// Slice converts a customtypes.BlockRoots object into a 2D byte slice.
|
||||
func (r *BlockRoots) Slice() [][]byte {
|
||||
// Each item in the slice is a copy of the original item.
|
||||
func (r BlockRoots) Slice() [][]byte {
|
||||
if r == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -8,14 +8,6 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
)
|
||||
|
||||
func TestBlockRoots_Casting(t *testing.T) {
|
||||
var b [fieldparams.BlockRootsLength][32]byte
|
||||
d := BlockRoots(b)
|
||||
if !reflect.DeepEqual([fieldparams.BlockRootsLength][32]byte(d), b) {
|
||||
t.Errorf("Unequal: %v = %v", d, b)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBlockRoots_UnmarshalSSZ(t *testing.T) {
|
||||
t.Run("Ok", func(t *testing.T) {
|
||||
d := BlockRoots{}
|
||||
@@ -70,7 +62,7 @@ func TestBlockRoots_MarshalSSZTo(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBlockRoots_MarshalSSZ(t *testing.T) {
|
||||
d := BlockRoots{}
|
||||
d := BlockRoots(make([][32]byte, fieldparams.BlockRootsLength))
|
||||
d[0] = [32]byte{'f', 'o', 'o'}
|
||||
d[1] = [32]byte{'b', 'a', 'r'}
|
||||
b, err := d.MarshalSSZ()
|
||||
@@ -94,7 +86,7 @@ func TestBlockRoots_SizeSSZ(t *testing.T) {
|
||||
|
||||
func TestBlockRoots_Slice(t *testing.T) {
|
||||
a, b, c := [32]byte{'a'}, [32]byte{'b'}, [32]byte{'c'}
|
||||
roots := BlockRoots{}
|
||||
roots := BlockRoots(make([][32]byte, fieldparams.BlockRootsLength))
|
||||
roots[1] = a
|
||||
roots[10] = b
|
||||
roots[100] = c
|
||||
|
||||
@@ -43,7 +43,7 @@ func (r *HistoricalRoots) UnmarshalSSZ(buf []byte) error {
|
||||
}
|
||||
|
||||
// MarshalSSZTo marshals HistoricalRoots with the provided byte slice.
|
||||
func (r *HistoricalRoots) MarshalSSZTo(dst []byte) ([]byte, error) {
|
||||
func (r HistoricalRoots) MarshalSSZTo(dst []byte) ([]byte, error) {
|
||||
marshalled, err := r.MarshalSSZ()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -52,9 +52,9 @@ func (r *HistoricalRoots) MarshalSSZTo(dst []byte) ([]byte, error) {
|
||||
}
|
||||
|
||||
// MarshalSSZ marshals HistoricalRoots into a serialized object.
|
||||
func (r *HistoricalRoots) MarshalSSZ() ([]byte, error) {
|
||||
marshalled := make([]byte, len(*r)*32)
|
||||
for i, r32 := range *r {
|
||||
func (r HistoricalRoots) MarshalSSZ() ([]byte, error) {
|
||||
marshalled := make([]byte, len(r)*32)
|
||||
for i, r32 := range r {
|
||||
for j, rr := range r32 {
|
||||
marshalled[i*32+j] = rr
|
||||
}
|
||||
@@ -63,17 +63,17 @@ func (r *HistoricalRoots) MarshalSSZ() ([]byte, error) {
|
||||
}
|
||||
|
||||
// SizeSSZ returns the size of the serialized object.
|
||||
func (r *HistoricalRoots) SizeSSZ() int {
|
||||
return len(*r) * 32
|
||||
func (r HistoricalRoots) SizeSSZ() int {
|
||||
return len(r) * 32
|
||||
}
|
||||
|
||||
// Slice converts a customtypes.HistoricalRoots object into a 2D byte slice.
|
||||
func (r *HistoricalRoots) Slice() [][]byte {
|
||||
func (r HistoricalRoots) Slice() [][]byte {
|
||||
if r == nil {
|
||||
return nil
|
||||
}
|
||||
hRoots := make([][]byte, len(*r))
|
||||
for i, root := range *r {
|
||||
hRoots := make([][]byte, len(r))
|
||||
for i, root := range r {
|
||||
tmp := root
|
||||
hRoots[i] = tmp[:]
|
||||
}
|
||||
|
||||
@@ -7,12 +7,12 @@ import (
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
)
|
||||
|
||||
var _ fssz.HashRoot = (RandaoMixes)([fieldparams.RandaoMixesLength][32]byte{})
|
||||
var _ fssz.HashRoot = (RandaoMixes)([][32]byte{})
|
||||
var _ fssz.Marshaler = (*RandaoMixes)(nil)
|
||||
var _ fssz.Unmarshaler = (*RandaoMixes)(nil)
|
||||
|
||||
// RandaoMixes represents RANDAO mixes of the beacon state.
|
||||
type RandaoMixes [fieldparams.RandaoMixesLength][32]byte
|
||||
type RandaoMixes [][32]byte
|
||||
|
||||
// HashTreeRoot returns calculated hash root.
|
||||
func (r RandaoMixes) HashTreeRoot() ([32]byte, error) {
|
||||
@@ -35,7 +35,7 @@ func (r *RandaoMixes) UnmarshalSSZ(buf []byte) error {
|
||||
return fmt.Errorf("expected buffer of length %d received %d", r.SizeSSZ(), len(buf))
|
||||
}
|
||||
|
||||
var roots RandaoMixes
|
||||
roots := RandaoMixes(make([][32]byte, fieldparams.RandaoMixesLength))
|
||||
for i := range roots {
|
||||
copy(roots[i][:], buf[i*32:(i+1)*32])
|
||||
}
|
||||
@@ -44,7 +44,7 @@ func (r *RandaoMixes) UnmarshalSSZ(buf []byte) error {
|
||||
}
|
||||
|
||||
// MarshalSSZTo marshals RandaoMixes with the provided byte slice.
|
||||
func (r *RandaoMixes) MarshalSSZTo(dst []byte) ([]byte, error) {
|
||||
func (r RandaoMixes) MarshalSSZTo(dst []byte) ([]byte, error) {
|
||||
marshalled, err := r.MarshalSSZ()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -53,7 +53,7 @@ func (r *RandaoMixes) MarshalSSZTo(dst []byte) ([]byte, error) {
|
||||
}
|
||||
|
||||
// MarshalSSZ marshals RandaoMixes into a serialized object.
|
||||
func (r *RandaoMixes) MarshalSSZ() ([]byte, error) {
|
||||
func (r RandaoMixes) MarshalSSZ() ([]byte, error) {
|
||||
marshalled := make([]byte, fieldparams.RandaoMixesLength*32)
|
||||
for i, r32 := range r {
|
||||
for j, rr := range r32 {
|
||||
@@ -64,12 +64,13 @@ func (r *RandaoMixes) MarshalSSZ() ([]byte, error) {
|
||||
}
|
||||
|
||||
// SizeSSZ returns the size of the serialized object.
|
||||
func (_ *RandaoMixes) SizeSSZ() int {
|
||||
func (_ RandaoMixes) SizeSSZ() int {
|
||||
return fieldparams.RandaoMixesLength * 32
|
||||
}
|
||||
|
||||
// Slice converts a customtypes.RandaoMixes object into a 2D byte slice.
|
||||
func (r *RandaoMixes) Slice() [][]byte {
|
||||
// Each item in the slice is a copy of the original item.
|
||||
func (r RandaoMixes) Slice() [][]byte {
|
||||
if r == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -8,14 +8,6 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
)
|
||||
|
||||
func TestRandaoMixes_Casting(t *testing.T) {
|
||||
var b [fieldparams.RandaoMixesLength][32]byte
|
||||
d := RandaoMixes(b)
|
||||
if !reflect.DeepEqual([fieldparams.RandaoMixesLength][32]byte(d), b) {
|
||||
t.Errorf("Unequal: %v = %v", d, b)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRandaoMixes_UnmarshalSSZ(t *testing.T) {
|
||||
t.Run("Ok", func(t *testing.T) {
|
||||
d := RandaoMixes{}
|
||||
@@ -70,7 +62,7 @@ func TestRandaoMixes_MarshalSSZTo(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRandaoMixes_MarshalSSZ(t *testing.T) {
|
||||
d := RandaoMixes{}
|
||||
d := RandaoMixes(make([][32]byte, fieldparams.RandaoMixesLength))
|
||||
d[0] = [32]byte{'f', 'o', 'o'}
|
||||
d[1] = [32]byte{'b', 'a', 'r'}
|
||||
b, err := d.MarshalSSZ()
|
||||
@@ -94,7 +86,7 @@ func TestRandaoMixes_SizeSSZ(t *testing.T) {
|
||||
|
||||
func TestRandaoMixes_Slice(t *testing.T) {
|
||||
a, b, c := [32]byte{'a'}, [32]byte{'b'}, [32]byte{'c'}
|
||||
roots := RandaoMixes{}
|
||||
roots := RandaoMixes(make([][32]byte, fieldparams.RandaoMixesLength))
|
||||
roots[1] = a
|
||||
roots[10] = b
|
||||
roots[100] = c
|
||||
|
||||
@@ -7,12 +7,12 @@ import (
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
)
|
||||
|
||||
var _ fssz.HashRoot = (StateRoots)([fieldparams.StateRootsLength][32]byte{})
|
||||
var _ fssz.HashRoot = (StateRoots)([][32]byte{})
|
||||
var _ fssz.Marshaler = (*StateRoots)(nil)
|
||||
var _ fssz.Unmarshaler = (*StateRoots)(nil)
|
||||
|
||||
// StateRoots represents block roots of the beacon state.
|
||||
type StateRoots [fieldparams.StateRootsLength][32]byte
|
||||
type StateRoots [][32]byte
|
||||
|
||||
// HashTreeRoot returns calculated hash root.
|
||||
func (r StateRoots) HashTreeRoot() ([32]byte, error) {
|
||||
@@ -35,7 +35,7 @@ func (r *StateRoots) UnmarshalSSZ(buf []byte) error {
|
||||
return fmt.Errorf("expected buffer of length %d received %d", r.SizeSSZ(), len(buf))
|
||||
}
|
||||
|
||||
var roots StateRoots
|
||||
roots := StateRoots(make([][32]byte, fieldparams.StateRootsLength))
|
||||
for i := range roots {
|
||||
copy(roots[i][:], buf[i*32:(i+1)*32])
|
||||
}
|
||||
@@ -44,7 +44,7 @@ func (r *StateRoots) UnmarshalSSZ(buf []byte) error {
|
||||
}
|
||||
|
||||
// MarshalSSZTo marshals StateRoots with the provided byte slice.
|
||||
func (r *StateRoots) MarshalSSZTo(dst []byte) ([]byte, error) {
|
||||
func (r StateRoots) MarshalSSZTo(dst []byte) ([]byte, error) {
|
||||
marshalled, err := r.MarshalSSZ()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -53,7 +53,7 @@ func (r *StateRoots) MarshalSSZTo(dst []byte) ([]byte, error) {
|
||||
}
|
||||
|
||||
// MarshalSSZ marshals StateRoots into a serialized object.
|
||||
func (r *StateRoots) MarshalSSZ() ([]byte, error) {
|
||||
func (r StateRoots) MarshalSSZ() ([]byte, error) {
|
||||
marshalled := make([]byte, fieldparams.StateRootsLength*32)
|
||||
for i, r32 := range r {
|
||||
for j, rr := range r32 {
|
||||
@@ -64,12 +64,13 @@ func (r *StateRoots) MarshalSSZ() ([]byte, error) {
|
||||
}
|
||||
|
||||
// SizeSSZ returns the size of the serialized object.
|
||||
func (_ *StateRoots) SizeSSZ() int {
|
||||
func (_ StateRoots) SizeSSZ() int {
|
||||
return fieldparams.StateRootsLength * 32
|
||||
}
|
||||
|
||||
// Slice converts a customtypes.StateRoots object into a 2D byte slice.
|
||||
func (r *StateRoots) Slice() [][]byte {
|
||||
// Each item in the slice is a copy of the original item.
|
||||
func (r StateRoots) Slice() [][]byte {
|
||||
if r == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -8,14 +8,6 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
)
|
||||
|
||||
func TestStateRoots_Casting(t *testing.T) {
|
||||
var b [fieldparams.StateRootsLength][32]byte
|
||||
d := StateRoots(b)
|
||||
if !reflect.DeepEqual([fieldparams.StateRootsLength][32]byte(d), b) {
|
||||
t.Errorf("Unequal: %v = %v", d, b)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStateRoots_UnmarshalSSZ(t *testing.T) {
|
||||
t.Run("Ok", func(t *testing.T) {
|
||||
d := StateRoots{}
|
||||
@@ -70,7 +62,7 @@ func TestStateRoots_MarshalSSZTo(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStateRoots_MarshalSSZ(t *testing.T) {
|
||||
d := StateRoots{}
|
||||
d := StateRoots(make([][32]byte, fieldparams.StateRootsLength))
|
||||
d[0] = [32]byte{'f', 'o', 'o'}
|
||||
d[1] = [32]byte{'b', 'a', 'r'}
|
||||
b, err := d.MarshalSSZ()
|
||||
@@ -94,7 +86,7 @@ func TestStateRoots_SizeSSZ(t *testing.T) {
|
||||
|
||||
func TestStateRoots_Slice(t *testing.T) {
|
||||
a, b, c := [32]byte{'a'}, [32]byte{'b'}, [32]byte{'c'}
|
||||
roots := StateRoots{}
|
||||
roots := StateRoots(make([][32]byte, fieldparams.StateRootsLength))
|
||||
roots[1] = a
|
||||
roots[10] = b
|
||||
roots[100] = c
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package state_native
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
customtypes "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/custom-types"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
consensus_types "github.com/prysmaticlabs/prysm/v4/consensus-types"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
@@ -45,26 +47,46 @@ func (b *BeaconState) latestBlockHeaderVal() *ethpb.BeaconBlockHeader {
|
||||
|
||||
// BlockRoots kept track of in the beacon state.
|
||||
func (b *BeaconState) BlockRoots() [][]byte {
|
||||
if b.blockRoots == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
return b.blockRoots.Slice()
|
||||
roots := b.blockRootsVal()
|
||||
if roots == nil {
|
||||
return nil
|
||||
}
|
||||
return roots.Slice()
|
||||
}
|
||||
|
||||
func (b *BeaconState) blockRootsVal() customtypes.BlockRoots {
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.blockRootsMultiValue == nil {
|
||||
return nil
|
||||
}
|
||||
return b.blockRootsMultiValue.Value(b)
|
||||
}
|
||||
return b.blockRoots
|
||||
}
|
||||
|
||||
// BlockRootAtIndex retrieves a specific block root based on an
|
||||
// input index value.
|
||||
func (b *BeaconState) BlockRootAtIndex(idx uint64) ([]byte, error) {
|
||||
if b.blockRoots == nil {
|
||||
return []byte{}, nil
|
||||
}
|
||||
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.blockRootsMultiValue == nil {
|
||||
return []byte{}, nil
|
||||
}
|
||||
r, err := b.blockRootsMultiValue.At(b, idx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r[:], nil
|
||||
}
|
||||
|
||||
if b.blockRoots == nil {
|
||||
return []byte{}, nil
|
||||
}
|
||||
r, err := b.blockRootAtIndex(idx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -77,7 +99,7 @@ func (b *BeaconState) BlockRootAtIndex(idx uint64) ([]byte, error) {
|
||||
// This assumes that a lock is already held on BeaconState.
|
||||
func (b *BeaconState) blockRootAtIndex(idx uint64) ([32]byte, error) {
|
||||
if uint64(len(b.blockRoots)) <= idx {
|
||||
return [32]byte{}, fmt.Errorf("index %d out of range", idx)
|
||||
return [32]byte{}, errors.Wrapf(consensus_types.ErrOutOfBounds, "block root index %d does not exist", idx)
|
||||
}
|
||||
return b.blockRoots[idx], nil
|
||||
}
|
||||
|
||||
@@ -6,6 +6,11 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v4/runtime/version"
|
||||
)
|
||||
|
||||
// Id is the identifier of the beacon state.
|
||||
func (b *BeaconState) Id() uint64 {
|
||||
return b.id
|
||||
}
|
||||
|
||||
// GenesisTime of the beacon state as a uint64.
|
||||
func (b *BeaconState) GenesisTime() uint64 {
|
||||
b.lock.RLock()
|
||||
@@ -79,16 +84,6 @@ func (b *BeaconState) HistoricalRoots() ([][]byte, error) {
|
||||
return b.historicalRoots.Slice(), nil
|
||||
}
|
||||
|
||||
// balancesLength returns the length of the balances slice.
|
||||
// This assumes that a lock is already held on BeaconState.
|
||||
func (b *BeaconState) balancesLength() int {
|
||||
if b.balances == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return len(b.balances)
|
||||
}
|
||||
|
||||
// HistoricalSummaries of the beacon state.
|
||||
func (b *BeaconState) HistoricalSummaries() ([]*ethpb.HistoricalSummary, error) {
|
||||
if b.version < version.Capella {
|
||||
|
||||
@@ -3,6 +3,7 @@ package state_native
|
||||
import (
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/core/time"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stateutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
"github.com/prysmaticlabs/prysm/v4/runtime/version"
|
||||
)
|
||||
|
||||
@@ -56,7 +57,11 @@ func (b *BeaconState) UnrealizedCheckpointBalances() (uint64, uint64, uint64, er
|
||||
return 0, 0, 0, ErrNilParticipation
|
||||
}
|
||||
|
||||
return stateutil.UnrealizedCheckpointBalances(cp, pp, b.validators, currentEpoch)
|
||||
if features.Get().EnableExperimentalState {
|
||||
return stateutil.UnrealizedCheckpointBalances(cp, pp, b.validatorsVal(), currentEpoch)
|
||||
} else {
|
||||
return stateutil.UnrealizedCheckpointBalances(cp, pp, b.validators, currentEpoch)
|
||||
}
|
||||
}
|
||||
|
||||
// currentEpochParticipationVal corresponding to participation bits on the beacon chain.
|
||||
|
||||
@@ -1,31 +1,54 @@
|
||||
package state_native
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
customtypes "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/custom-types"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
consensus_types "github.com/prysmaticlabs/prysm/v4/consensus-types"
|
||||
)
|
||||
|
||||
// RandaoMixes of block proposers on the beacon chain.
|
||||
func (b *BeaconState) RandaoMixes() [][]byte {
|
||||
if b.randaoMixes == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
return b.randaoMixes.Slice()
|
||||
mixes := b.randaoMixesVal()
|
||||
if mixes == nil {
|
||||
return nil
|
||||
}
|
||||
return mixes.Slice()
|
||||
}
|
||||
|
||||
func (b *BeaconState) randaoMixesVal() customtypes.RandaoMixes {
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.randaoMixesMultiValue == nil {
|
||||
return nil
|
||||
}
|
||||
return b.randaoMixesMultiValue.Value(b)
|
||||
}
|
||||
return b.randaoMixes
|
||||
}
|
||||
|
||||
// RandaoMixAtIndex retrieves a specific block root based on an
|
||||
// input index value.
|
||||
func (b *BeaconState) RandaoMixAtIndex(idx uint64) ([]byte, error) {
|
||||
if b.randaoMixes == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.randaoMixesMultiValue == nil {
|
||||
return nil, nil
|
||||
}
|
||||
r, err := b.randaoMixesMultiValue.At(b, idx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r[:], nil
|
||||
}
|
||||
|
||||
if b.randaoMixes == nil {
|
||||
return nil, nil
|
||||
}
|
||||
m, err := b.randaoMixAtIndex(idx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -38,7 +61,7 @@ func (b *BeaconState) RandaoMixAtIndex(idx uint64) ([]byte, error) {
|
||||
// This assumes that a lock is already held on BeaconState.
|
||||
func (b *BeaconState) randaoMixAtIndex(idx uint64) ([32]byte, error) {
|
||||
if uint64(len(b.randaoMixes)) <= idx {
|
||||
return [32]byte{}, fmt.Errorf("index %d out of range", idx)
|
||||
return [32]byte{}, errors.Wrapf(consensus_types.ErrOutOfBounds, "randao mix index %d does not exist", idx)
|
||||
}
|
||||
|
||||
return b.randaoMixes[idx], nil
|
||||
@@ -46,22 +69,17 @@ func (b *BeaconState) randaoMixAtIndex(idx uint64) ([32]byte, error) {
|
||||
|
||||
// RandaoMixesLength returns the length of the randao mixes slice.
|
||||
func (b *BeaconState) RandaoMixesLength() int {
|
||||
if b.randaoMixes == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
return b.randaoMixesLength()
|
||||
}
|
||||
|
||||
// randaoMixesLength returns the length of the randao mixes slice.
|
||||
// This assumes that a lock is already held on BeaconState.
|
||||
func (b *BeaconState) randaoMixesLength() int {
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.randaoMixesMultiValue == nil {
|
||||
return 0
|
||||
}
|
||||
return b.randaoMixesMultiValue.Len(b)
|
||||
}
|
||||
if b.randaoMixes == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return len(b.randaoMixes)
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package state_native
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
customtypes "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/custom-types"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
consensus_types "github.com/prysmaticlabs/prysm/v4/consensus-types"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/runtime/version"
|
||||
)
|
||||
@@ -16,6 +17,18 @@ func (b *BeaconState) ToProtoUnsafe() interface{} {
|
||||
}
|
||||
|
||||
gvrCopy := b.genesisValidatorsRoot
|
||||
br := b.blockRootsVal().Slice()
|
||||
sr := b.stateRootsVal().Slice()
|
||||
rm := b.randaoMixesVal().Slice()
|
||||
var vals []*ethpb.Validator
|
||||
var bals []uint64
|
||||
if features.Get().EnableExperimentalState {
|
||||
vals = b.validatorsVal()
|
||||
bals = b.balancesVal()
|
||||
} else {
|
||||
vals = b.validators
|
||||
bals = b.balances
|
||||
}
|
||||
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
@@ -25,15 +38,15 @@ func (b *BeaconState) ToProtoUnsafe() interface{} {
|
||||
Slot: b.slot,
|
||||
Fork: b.fork,
|
||||
LatestBlockHeader: b.latestBlockHeader,
|
||||
BlockRoots: b.blockRoots.Slice(),
|
||||
StateRoots: b.stateRoots.Slice(),
|
||||
BlockRoots: br,
|
||||
StateRoots: sr,
|
||||
HistoricalRoots: b.historicalRoots.Slice(),
|
||||
Eth1Data: b.eth1Data,
|
||||
Eth1DataVotes: b.eth1DataVotes,
|
||||
Eth1DepositIndex: b.eth1DepositIndex,
|
||||
Validators: b.validators,
|
||||
Balances: b.balances,
|
||||
RandaoMixes: b.randaoMixes.Slice(),
|
||||
Validators: vals,
|
||||
Balances: bals,
|
||||
RandaoMixes: rm,
|
||||
Slashings: b.slashings,
|
||||
PreviousEpochAttestations: b.previousEpochAttestations,
|
||||
CurrentEpochAttestations: b.currentEpochAttestations,
|
||||
@@ -49,15 +62,15 @@ func (b *BeaconState) ToProtoUnsafe() interface{} {
|
||||
Slot: b.slot,
|
||||
Fork: b.fork,
|
||||
LatestBlockHeader: b.latestBlockHeader,
|
||||
BlockRoots: b.blockRoots.Slice(),
|
||||
StateRoots: b.stateRoots.Slice(),
|
||||
BlockRoots: br,
|
||||
StateRoots: sr,
|
||||
HistoricalRoots: b.historicalRoots.Slice(),
|
||||
Eth1Data: b.eth1Data,
|
||||
Eth1DataVotes: b.eth1DataVotes,
|
||||
Eth1DepositIndex: b.eth1DepositIndex,
|
||||
Validators: b.validators,
|
||||
Balances: b.balances,
|
||||
RandaoMixes: b.randaoMixes.Slice(),
|
||||
Validators: vals,
|
||||
Balances: bals,
|
||||
RandaoMixes: rm,
|
||||
Slashings: b.slashings,
|
||||
PreviousEpochParticipation: b.previousEpochParticipation,
|
||||
CurrentEpochParticipation: b.currentEpochParticipation,
|
||||
@@ -65,7 +78,7 @@ func (b *BeaconState) ToProtoUnsafe() interface{} {
|
||||
PreviousJustifiedCheckpoint: b.previousJustifiedCheckpoint,
|
||||
CurrentJustifiedCheckpoint: b.currentJustifiedCheckpoint,
|
||||
FinalizedCheckpoint: b.finalizedCheckpoint,
|
||||
InactivityScores: b.inactivityScores,
|
||||
InactivityScores: b.inactivityScoresVal(),
|
||||
CurrentSyncCommittee: b.currentSyncCommittee,
|
||||
NextSyncCommittee: b.nextSyncCommittee,
|
||||
}
|
||||
@@ -76,15 +89,15 @@ func (b *BeaconState) ToProtoUnsafe() interface{} {
|
||||
Slot: b.slot,
|
||||
Fork: b.fork,
|
||||
LatestBlockHeader: b.latestBlockHeader,
|
||||
BlockRoots: b.blockRoots.Slice(),
|
||||
StateRoots: b.stateRoots.Slice(),
|
||||
BlockRoots: br,
|
||||
StateRoots: sr,
|
||||
HistoricalRoots: b.historicalRoots.Slice(),
|
||||
Eth1Data: b.eth1Data,
|
||||
Eth1DataVotes: b.eth1DataVotes,
|
||||
Eth1DepositIndex: b.eth1DepositIndex,
|
||||
Validators: b.validators,
|
||||
Balances: b.balances,
|
||||
RandaoMixes: b.randaoMixes.Slice(),
|
||||
Validators: vals,
|
||||
Balances: bals,
|
||||
RandaoMixes: rm,
|
||||
Slashings: b.slashings,
|
||||
PreviousEpochParticipation: b.previousEpochParticipation,
|
||||
CurrentEpochParticipation: b.currentEpochParticipation,
|
||||
@@ -92,7 +105,7 @@ func (b *BeaconState) ToProtoUnsafe() interface{} {
|
||||
PreviousJustifiedCheckpoint: b.previousJustifiedCheckpoint,
|
||||
CurrentJustifiedCheckpoint: b.currentJustifiedCheckpoint,
|
||||
FinalizedCheckpoint: b.finalizedCheckpoint,
|
||||
InactivityScores: b.inactivityScores,
|
||||
InactivityScores: b.inactivityScoresVal(),
|
||||
CurrentSyncCommittee: b.currentSyncCommittee,
|
||||
NextSyncCommittee: b.nextSyncCommittee,
|
||||
LatestExecutionPayloadHeader: b.latestExecutionPayloadHeader,
|
||||
@@ -104,15 +117,15 @@ func (b *BeaconState) ToProtoUnsafe() interface{} {
|
||||
Slot: b.slot,
|
||||
Fork: b.fork,
|
||||
LatestBlockHeader: b.latestBlockHeader,
|
||||
BlockRoots: b.blockRoots.Slice(),
|
||||
StateRoots: b.stateRoots.Slice(),
|
||||
BlockRoots: br,
|
||||
StateRoots: sr,
|
||||
HistoricalRoots: b.historicalRoots.Slice(),
|
||||
Eth1Data: b.eth1Data,
|
||||
Eth1DataVotes: b.eth1DataVotes,
|
||||
Eth1DepositIndex: b.eth1DepositIndex,
|
||||
Validators: b.validators,
|
||||
Balances: b.balances,
|
||||
RandaoMixes: b.randaoMixes.Slice(),
|
||||
Validators: vals,
|
||||
Balances: bals,
|
||||
RandaoMixes: rm,
|
||||
Slashings: b.slashings,
|
||||
PreviousEpochParticipation: b.previousEpochParticipation,
|
||||
CurrentEpochParticipation: b.currentEpochParticipation,
|
||||
@@ -120,7 +133,7 @@ func (b *BeaconState) ToProtoUnsafe() interface{} {
|
||||
PreviousJustifiedCheckpoint: b.previousJustifiedCheckpoint,
|
||||
CurrentJustifiedCheckpoint: b.currentJustifiedCheckpoint,
|
||||
FinalizedCheckpoint: b.finalizedCheckpoint,
|
||||
InactivityScores: b.inactivityScores,
|
||||
InactivityScores: b.inactivityScoresVal(),
|
||||
CurrentSyncCommittee: b.currentSyncCommittee,
|
||||
NextSyncCommittee: b.nextSyncCommittee,
|
||||
LatestExecutionPayloadHeader: b.latestExecutionPayloadHeaderCapella,
|
||||
@@ -135,15 +148,15 @@ func (b *BeaconState) ToProtoUnsafe() interface{} {
|
||||
Slot: b.slot,
|
||||
Fork: b.fork,
|
||||
LatestBlockHeader: b.latestBlockHeader,
|
||||
BlockRoots: b.blockRoots.Slice(),
|
||||
StateRoots: b.stateRoots.Slice(),
|
||||
BlockRoots: br,
|
||||
StateRoots: sr,
|
||||
HistoricalRoots: b.historicalRoots.Slice(),
|
||||
Eth1Data: b.eth1Data,
|
||||
Eth1DataVotes: b.eth1DataVotes,
|
||||
Eth1DepositIndex: b.eth1DepositIndex,
|
||||
Validators: b.validators,
|
||||
Balances: b.balances,
|
||||
RandaoMixes: b.randaoMixes.Slice(),
|
||||
Validators: vals,
|
||||
Balances: bals,
|
||||
RandaoMixes: rm,
|
||||
Slashings: b.slashings,
|
||||
PreviousEpochParticipation: b.previousEpochParticipation,
|
||||
CurrentEpochParticipation: b.currentEpochParticipation,
|
||||
@@ -174,6 +187,14 @@ func (b *BeaconState) ToProto() interface{} {
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
gvrCopy := b.genesisValidatorsRoot
|
||||
br := b.blockRootsVal().Slice()
|
||||
sr := b.stateRootsVal().Slice()
|
||||
rm := b.randaoMixesVal().Slice()
|
||||
|
||||
var inactivityScores []uint64
|
||||
if b.version > version.Phase0 {
|
||||
inactivityScores = b.inactivityScoresVal()
|
||||
}
|
||||
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
@@ -183,15 +204,15 @@ func (b *BeaconState) ToProto() interface{} {
|
||||
Slot: b.slot,
|
||||
Fork: b.forkVal(),
|
||||
LatestBlockHeader: b.latestBlockHeaderVal(),
|
||||
BlockRoots: b.blockRoots.Slice(),
|
||||
StateRoots: b.stateRoots.Slice(),
|
||||
BlockRoots: br,
|
||||
StateRoots: sr,
|
||||
HistoricalRoots: b.historicalRoots.Slice(),
|
||||
Eth1Data: b.eth1DataVal(),
|
||||
Eth1DataVotes: b.eth1DataVotesVal(),
|
||||
Eth1DepositIndex: b.eth1DepositIndex,
|
||||
Validators: b.validatorsVal(),
|
||||
Balances: b.balancesVal(),
|
||||
RandaoMixes: b.randaoMixes.Slice(),
|
||||
RandaoMixes: rm,
|
||||
Slashings: b.slashingsVal(),
|
||||
PreviousEpochAttestations: b.previousEpochAttestationsVal(),
|
||||
CurrentEpochAttestations: b.currentEpochAttestationsVal(),
|
||||
@@ -207,15 +228,15 @@ func (b *BeaconState) ToProto() interface{} {
|
||||
Slot: b.slot,
|
||||
Fork: b.forkVal(),
|
||||
LatestBlockHeader: b.latestBlockHeaderVal(),
|
||||
BlockRoots: b.blockRoots.Slice(),
|
||||
StateRoots: b.stateRoots.Slice(),
|
||||
BlockRoots: br,
|
||||
StateRoots: sr,
|
||||
HistoricalRoots: b.historicalRoots.Slice(),
|
||||
Eth1Data: b.eth1DataVal(),
|
||||
Eth1DataVotes: b.eth1DataVotesVal(),
|
||||
Eth1DepositIndex: b.eth1DepositIndex,
|
||||
Validators: b.validatorsVal(),
|
||||
Balances: b.balancesVal(),
|
||||
RandaoMixes: b.randaoMixes.Slice(),
|
||||
RandaoMixes: rm,
|
||||
Slashings: b.slashingsVal(),
|
||||
PreviousEpochParticipation: b.previousEpochParticipationVal(),
|
||||
CurrentEpochParticipation: b.currentEpochParticipationVal(),
|
||||
@@ -223,7 +244,7 @@ func (b *BeaconState) ToProto() interface{} {
|
||||
PreviousJustifiedCheckpoint: b.previousJustifiedCheckpointVal(),
|
||||
CurrentJustifiedCheckpoint: b.currentJustifiedCheckpointVal(),
|
||||
FinalizedCheckpoint: b.finalizedCheckpointVal(),
|
||||
InactivityScores: b.inactivityScoresVal(),
|
||||
InactivityScores: inactivityScores,
|
||||
CurrentSyncCommittee: b.currentSyncCommitteeVal(),
|
||||
NextSyncCommittee: b.nextSyncCommitteeVal(),
|
||||
}
|
||||
@@ -234,15 +255,15 @@ func (b *BeaconState) ToProto() interface{} {
|
||||
Slot: b.slot,
|
||||
Fork: b.forkVal(),
|
||||
LatestBlockHeader: b.latestBlockHeaderVal(),
|
||||
BlockRoots: b.blockRoots.Slice(),
|
||||
StateRoots: b.stateRoots.Slice(),
|
||||
BlockRoots: br,
|
||||
StateRoots: sr,
|
||||
HistoricalRoots: b.historicalRoots.Slice(),
|
||||
Eth1Data: b.eth1DataVal(),
|
||||
Eth1DataVotes: b.eth1DataVotesVal(),
|
||||
Eth1DepositIndex: b.eth1DepositIndex,
|
||||
Validators: b.validatorsVal(),
|
||||
Balances: b.balancesVal(),
|
||||
RandaoMixes: b.randaoMixes.Slice(),
|
||||
RandaoMixes: rm,
|
||||
Slashings: b.slashingsVal(),
|
||||
PreviousEpochParticipation: b.previousEpochParticipationVal(),
|
||||
CurrentEpochParticipation: b.currentEpochParticipationVal(),
|
||||
@@ -250,7 +271,7 @@ func (b *BeaconState) ToProto() interface{} {
|
||||
PreviousJustifiedCheckpoint: b.previousJustifiedCheckpointVal(),
|
||||
CurrentJustifiedCheckpoint: b.currentJustifiedCheckpointVal(),
|
||||
FinalizedCheckpoint: b.finalizedCheckpointVal(),
|
||||
InactivityScores: b.inactivityScoresVal(),
|
||||
InactivityScores: inactivityScores,
|
||||
CurrentSyncCommittee: b.currentSyncCommitteeVal(),
|
||||
NextSyncCommittee: b.nextSyncCommitteeVal(),
|
||||
LatestExecutionPayloadHeader: b.latestExecutionPayloadHeaderVal(),
|
||||
@@ -262,15 +283,15 @@ func (b *BeaconState) ToProto() interface{} {
|
||||
Slot: b.slot,
|
||||
Fork: b.forkVal(),
|
||||
LatestBlockHeader: b.latestBlockHeaderVal(),
|
||||
BlockRoots: b.blockRoots.Slice(),
|
||||
StateRoots: b.stateRoots.Slice(),
|
||||
BlockRoots: br,
|
||||
StateRoots: sr,
|
||||
HistoricalRoots: b.historicalRoots.Slice(),
|
||||
Eth1Data: b.eth1DataVal(),
|
||||
Eth1DataVotes: b.eth1DataVotesVal(),
|
||||
Eth1DepositIndex: b.eth1DepositIndex,
|
||||
Validators: b.validatorsVal(),
|
||||
Balances: b.balancesVal(),
|
||||
RandaoMixes: b.randaoMixes.Slice(),
|
||||
RandaoMixes: rm,
|
||||
Slashings: b.slashingsVal(),
|
||||
PreviousEpochParticipation: b.previousEpochParticipationVal(),
|
||||
CurrentEpochParticipation: b.currentEpochParticipationVal(),
|
||||
@@ -278,7 +299,7 @@ func (b *BeaconState) ToProto() interface{} {
|
||||
PreviousJustifiedCheckpoint: b.previousJustifiedCheckpointVal(),
|
||||
CurrentJustifiedCheckpoint: b.currentJustifiedCheckpointVal(),
|
||||
FinalizedCheckpoint: b.finalizedCheckpointVal(),
|
||||
InactivityScores: b.inactivityScoresVal(),
|
||||
InactivityScores: inactivityScores,
|
||||
CurrentSyncCommittee: b.currentSyncCommitteeVal(),
|
||||
NextSyncCommittee: b.nextSyncCommitteeVal(),
|
||||
LatestExecutionPayloadHeader: b.latestExecutionPayloadHeaderCapellaVal(),
|
||||
@@ -293,15 +314,15 @@ func (b *BeaconState) ToProto() interface{} {
|
||||
Slot: b.slot,
|
||||
Fork: b.forkVal(),
|
||||
LatestBlockHeader: b.latestBlockHeaderVal(),
|
||||
BlockRoots: b.blockRoots.Slice(),
|
||||
StateRoots: b.stateRoots.Slice(),
|
||||
BlockRoots: br,
|
||||
StateRoots: sr,
|
||||
HistoricalRoots: b.historicalRoots.Slice(),
|
||||
Eth1Data: b.eth1DataVal(),
|
||||
Eth1DataVotes: b.eth1DataVotesVal(),
|
||||
Eth1DepositIndex: b.eth1DepositIndex,
|
||||
Validators: b.validatorsVal(),
|
||||
Balances: b.balancesVal(),
|
||||
RandaoMixes: b.randaoMixes.Slice(),
|
||||
RandaoMixes: rm,
|
||||
Slashings: b.slashingsVal(),
|
||||
PreviousEpochParticipation: b.previousEpochParticipationVal(),
|
||||
CurrentEpochParticipation: b.currentEpochParticipationVal(),
|
||||
@@ -324,26 +345,46 @@ func (b *BeaconState) ToProto() interface{} {
|
||||
|
||||
// StateRoots kept track of in the beacon state.
|
||||
func (b *BeaconState) StateRoots() [][]byte {
|
||||
if b.stateRoots == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
return b.stateRoots.Slice()
|
||||
roots := b.stateRootsVal()
|
||||
if roots == nil {
|
||||
return nil
|
||||
}
|
||||
return roots.Slice()
|
||||
}
|
||||
|
||||
func (b *BeaconState) stateRootsVal() customtypes.StateRoots {
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.stateRootsMultiValue == nil {
|
||||
return nil
|
||||
}
|
||||
return b.stateRootsMultiValue.Value(b)
|
||||
}
|
||||
return b.stateRoots
|
||||
}
|
||||
|
||||
// StateRootAtIndex retrieves a specific state root based on an
|
||||
// input index value.
|
||||
func (b *BeaconState) StateRootAtIndex(idx uint64) ([]byte, error) {
|
||||
if b.stateRoots == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.stateRootsMultiValue == nil {
|
||||
return nil, nil
|
||||
}
|
||||
r, err := b.stateRootsMultiValue.At(b, idx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r[:], nil
|
||||
}
|
||||
|
||||
if b.stateRoots == nil {
|
||||
return nil, nil
|
||||
}
|
||||
r, err := b.stateRootAtIndex(idx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -354,9 +395,11 @@ func (b *BeaconState) StateRootAtIndex(idx uint64) ([]byte, error) {
|
||||
// stateRootAtIndex retrieves a specific state root based on an
|
||||
// input index value.
|
||||
// This assumes that a lock is already held on BeaconState.
|
||||
//
|
||||
// WARNING: This function does not work with the multi-value slice feature.
|
||||
func (b *BeaconState) stateRootAtIndex(idx uint64) ([32]byte, error) {
|
||||
if uint64(len(b.stateRoots)) <= idx {
|
||||
return [32]byte{}, fmt.Errorf("index %d out of range", idx)
|
||||
return [32]byte{}, errors.Wrapf(consensus_types.ErrOutOfBounds, "state root index %d does not exist", idx)
|
||||
}
|
||||
return b.stateRoots[idx], nil
|
||||
}
|
||||
|
||||
@@ -1,57 +1,42 @@
|
||||
package state_native
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
consensus_types "github.com/prysmaticlabs/prysm/v4/consensus-types"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/runtime/version"
|
||||
)
|
||||
|
||||
// ValidatorIndexOutOfRangeError represents an error scenario where a validator does not exist
|
||||
// at a given index in the validator's array.
|
||||
type ValidatorIndexOutOfRangeError struct {
|
||||
message string
|
||||
}
|
||||
|
||||
// NewValidatorIndexOutOfRangeError creates a new error instance.
|
||||
func NewValidatorIndexOutOfRangeError(index primitives.ValidatorIndex) ValidatorIndexOutOfRangeError {
|
||||
return ValidatorIndexOutOfRangeError{
|
||||
message: fmt.Sprintf("index %d out of range", index),
|
||||
}
|
||||
}
|
||||
|
||||
// Error returns the underlying error message.
|
||||
func (e *ValidatorIndexOutOfRangeError) Error() string {
|
||||
return e.message
|
||||
}
|
||||
|
||||
// Validators participating in consensus on the beacon chain.
|
||||
func (b *BeaconState) Validators() []*ethpb.Validator {
|
||||
if b.validators == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
return b.validatorsVal()
|
||||
}
|
||||
|
||||
// validatorsVal participating in consensus on the beacon chain.
|
||||
// This assumes that a lock is already held on BeaconState.
|
||||
func (b *BeaconState) validatorsVal() []*ethpb.Validator {
|
||||
if b.validators == nil {
|
||||
return nil
|
||||
var v []*ethpb.Validator
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.validatorsMultiValue == nil {
|
||||
return nil
|
||||
}
|
||||
v = b.validatorsMultiValue.Value(b)
|
||||
} else {
|
||||
if b.validators == nil {
|
||||
return nil
|
||||
}
|
||||
v = b.validators
|
||||
}
|
||||
|
||||
res := make([]*ethpb.Validator, len(b.validators))
|
||||
res := make([]*ethpb.Validator, len(v))
|
||||
for i := 0; i < len(res); i++ {
|
||||
val := b.validators[i]
|
||||
val := v[i]
|
||||
if val == nil {
|
||||
continue
|
||||
}
|
||||
@@ -80,19 +65,42 @@ func (b *BeaconState) validatorsReferences() []*ethpb.Validator {
|
||||
return res
|
||||
}
|
||||
|
||||
func (b *BeaconState) validatorsLen() int {
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.validatorsMultiValue == nil {
|
||||
return 0
|
||||
}
|
||||
return b.validatorsMultiValue.Len(b)
|
||||
}
|
||||
return len(b.validators)
|
||||
}
|
||||
|
||||
// ValidatorAtIndex is the validator at the provided index.
|
||||
func (b *BeaconState) ValidatorAtIndex(idx primitives.ValidatorIndex) (*ethpb.Validator, error) {
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
return b.validatorAtIndex(idx)
|
||||
}
|
||||
|
||||
func (b *BeaconState) validatorAtIndex(idx primitives.ValidatorIndex) (*ethpb.Validator, error) {
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.validatorsMultiValue == nil {
|
||||
return ðpb.Validator{}, nil
|
||||
}
|
||||
v, err := b.validatorsMultiValue.At(b, uint64(idx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ethpb.CopyValidator(v), nil
|
||||
}
|
||||
|
||||
if b.validators == nil {
|
||||
return ðpb.Validator{}, nil
|
||||
}
|
||||
if uint64(len(b.validators)) <= uint64(idx) {
|
||||
e := NewValidatorIndexOutOfRangeError(idx)
|
||||
return nil, &e
|
||||
return nil, errors.Wrapf(consensus_types.ErrOutOfBounds, "validator index %d does not exist", idx)
|
||||
}
|
||||
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
val := b.validators[idx]
|
||||
return ethpb.CopyValidator(val), nil
|
||||
}
|
||||
@@ -100,18 +108,28 @@ func (b *BeaconState) ValidatorAtIndex(idx primitives.ValidatorIndex) (*ethpb.Va
|
||||
// ValidatorAtIndexReadOnly is the validator at the provided index. This method
|
||||
// doesn't clone the validator.
|
||||
func (b *BeaconState) ValidatorAtIndexReadOnly(idx primitives.ValidatorIndex) (state.ReadOnlyValidator, error) {
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.validatorsMultiValue == nil {
|
||||
return nil, state.ErrNilValidatorsInState
|
||||
}
|
||||
v, err := b.validatorsMultiValue.At(b, uint64(idx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewValidator(v)
|
||||
}
|
||||
|
||||
if b.validators == nil {
|
||||
return nil, state.ErrNilValidatorsInState
|
||||
}
|
||||
if uint64(len(b.validators)) <= uint64(idx) {
|
||||
e := NewValidatorIndexOutOfRangeError(idx)
|
||||
return nil, &e
|
||||
return nil, errors.Wrapf(consensus_types.ErrOutOfBounds, "validator index %d does not exist", idx)
|
||||
}
|
||||
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
return NewValidator(b.validators[idx])
|
||||
val := b.validators[idx]
|
||||
return NewValidator(val)
|
||||
}
|
||||
|
||||
// ValidatorIndexByPubkey returns a given validator by its 48-byte public key.
|
||||
@@ -121,7 +139,13 @@ func (b *BeaconState) ValidatorIndexByPubkey(key [fieldparams.BLSPubkeyLength]by
|
||||
}
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
numOfVals := len(b.validators)
|
||||
|
||||
var numOfVals int
|
||||
if features.Get().EnableExperimentalState {
|
||||
numOfVals = b.validatorsMultiValue.Len(b)
|
||||
} else {
|
||||
numOfVals = len(b.validators)
|
||||
}
|
||||
|
||||
idx, ok := b.valMapHandler.Get(key)
|
||||
if ok && primitives.ValidatorIndex(numOfVals) <= idx {
|
||||
@@ -133,16 +157,27 @@ func (b *BeaconState) ValidatorIndexByPubkey(key [fieldparams.BLSPubkeyLength]by
|
||||
// PubkeyAtIndex returns the pubkey at the given
|
||||
// validator index.
|
||||
func (b *BeaconState) PubkeyAtIndex(idx primitives.ValidatorIndex) [fieldparams.BLSPubkeyLength]byte {
|
||||
if uint64(idx) >= uint64(len(b.validators)) {
|
||||
return [fieldparams.BLSPubkeyLength]byte{}
|
||||
}
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
if b.validators[idx] == nil {
|
||||
var v *ethpb.Validator
|
||||
if features.Get().EnableExperimentalState {
|
||||
var err error
|
||||
v, err = b.validatorsMultiValue.At(b, uint64(idx))
|
||||
if err != nil {
|
||||
return [fieldparams.BLSPubkeyLength]byte{}
|
||||
}
|
||||
} else {
|
||||
if uint64(idx) >= uint64(len(b.validators)) {
|
||||
return [fieldparams.BLSPubkeyLength]byte{}
|
||||
}
|
||||
v = b.validators[idx]
|
||||
}
|
||||
|
||||
if v == nil {
|
||||
return [fieldparams.BLSPubkeyLength]byte{}
|
||||
}
|
||||
return bytesutil.ToBytes48(b.validators[idx].PublicKey)
|
||||
return bytesutil.ToBytes48(v.PublicKey)
|
||||
}
|
||||
|
||||
// NumValidators returns the size of the validator registry.
|
||||
@@ -150,26 +185,54 @@ func (b *BeaconState) NumValidators() int {
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
return len(b.validators)
|
||||
return b.validatorsLen()
|
||||
}
|
||||
|
||||
// ReadFromEveryValidator reads values from every validator and applies it to the provided function.
|
||||
//
|
||||
// WARNING: This method is potentially unsafe, as it exposes the actual validator registry.
|
||||
func (b *BeaconState) ReadFromEveryValidator(f func(idx int, val state.ReadOnlyValidator) error) error {
|
||||
if b.validators == nil {
|
||||
return errors.New("nil validators in state")
|
||||
}
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
if features.Get().EnableExperimentalState {
|
||||
return b.readFromEveryValidatorMVSlice(f)
|
||||
}
|
||||
|
||||
if b.validators == nil {
|
||||
return state.ErrNilValidatorsInState
|
||||
}
|
||||
|
||||
validators := b.validators
|
||||
b.lock.RUnlock()
|
||||
|
||||
for i, v := range validators {
|
||||
v, err := NewValidator(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := f(i, v); err != nil {
|
||||
if err = f(i, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WARNING: This function works only for the multi-value slice feature.
|
||||
func (b *BeaconState) readFromEveryValidatorMVSlice(f func(idx int, val state.ReadOnlyValidator) error) error {
|
||||
if b.validatorsMultiValue == nil {
|
||||
return state.ErrNilValidatorsInState
|
||||
}
|
||||
l := b.validatorsMultiValue.Len(b)
|
||||
for i := 0; i < l; i++ {
|
||||
v, err := b.validatorsMultiValue.At(b, uint64(i))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rov, err := NewValidator(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = f(i, rov); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -178,23 +241,22 @@ func (b *BeaconState) ReadFromEveryValidator(f func(idx int, val state.ReadOnlyV
|
||||
|
||||
// Balances of validators participating in consensus on the beacon chain.
|
||||
func (b *BeaconState) Balances() []uint64 {
|
||||
if b.balances == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
return b.balancesVal()
|
||||
}
|
||||
|
||||
// balancesVal of validators participating in consensus on the beacon chain.
|
||||
// This assumes that a lock is already held on BeaconState.
|
||||
func (b *BeaconState) balancesVal() []uint64 {
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.balancesMultiValue == nil {
|
||||
return nil
|
||||
}
|
||||
return b.balancesMultiValue.Value(b)
|
||||
}
|
||||
if b.balances == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
res := make([]uint64, len(b.balances))
|
||||
copy(res, b.balances)
|
||||
return res
|
||||
@@ -202,29 +264,40 @@ func (b *BeaconState) balancesVal() []uint64 {
|
||||
|
||||
// BalanceAtIndex of validator with the provided index.
|
||||
func (b *BeaconState) BalanceAtIndex(idx primitives.ValidatorIndex) (uint64, error) {
|
||||
if b.balances == nil {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
return b.balanceAtIndex(idx)
|
||||
}
|
||||
|
||||
func (b *BeaconState) balanceAtIndex(idx primitives.ValidatorIndex) (uint64, error) {
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.balancesMultiValue == nil {
|
||||
return 0, nil
|
||||
}
|
||||
return b.balancesMultiValue.At(b, uint64(idx))
|
||||
}
|
||||
if b.balances == nil {
|
||||
return 0, nil
|
||||
}
|
||||
if uint64(len(b.balances)) <= uint64(idx) {
|
||||
return 0, fmt.Errorf("index of %d does not exist", idx)
|
||||
return 0, errors.Wrapf(consensus_types.ErrOutOfBounds, "balance index %d does not exist", idx)
|
||||
}
|
||||
return b.balances[idx], nil
|
||||
}
|
||||
|
||||
// BalancesLength returns the length of the balances slice.
|
||||
func (b *BeaconState) BalancesLength() int {
|
||||
if b.balances == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
return b.balancesLength()
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.balancesMultiValue == nil {
|
||||
return 0
|
||||
}
|
||||
return b.balancesMultiValue.Len(b)
|
||||
}
|
||||
return len(b.balances)
|
||||
}
|
||||
|
||||
// Slashings of validators on the beacon chain.
|
||||
@@ -257,23 +330,22 @@ func (b *BeaconState) InactivityScores() ([]uint64, error) {
|
||||
return nil, errNotSupported("InactivityScores", b.version)
|
||||
}
|
||||
|
||||
if b.inactivityScores == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
b.lock.RLock()
|
||||
defer b.lock.RUnlock()
|
||||
|
||||
return b.inactivityScoresVal(), nil
|
||||
}
|
||||
|
||||
// inactivityScoresVal of validators participating in consensus on the beacon chain.
|
||||
// This assumes that a lock is already held on BeaconState.
|
||||
func (b *BeaconState) inactivityScoresVal() []uint64 {
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.inactivityScoresMultiValue == nil {
|
||||
return nil
|
||||
}
|
||||
return b.inactivityScoresMultiValue.Value(b)
|
||||
}
|
||||
if b.inactivityScores == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
res := make([]uint64, len(b.inactivityScores))
|
||||
copy(res, b.inactivityScores)
|
||||
return res
|
||||
|
||||
@@ -52,11 +52,6 @@ func TestBeaconState_ValidatorAtIndexReadOnly_HandlesNilSlice_Deneb(t *testing.T
|
||||
})
|
||||
}
|
||||
|
||||
func TestValidatorIndexOutOfRangeError(t *testing.T) {
|
||||
err := statenative.NewValidatorIndexOutOfRangeError(1)
|
||||
require.Equal(t, err.Error(), "index 1 out of range")
|
||||
}
|
||||
|
||||
func TestValidatorIndexes(t *testing.T) {
|
||||
dState, _ := util.DeterministicGenesisState(t, 10)
|
||||
byteValue := dState.PubkeyAtIndex(1)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package state_native
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
@@ -54,10 +55,17 @@ func (b *BeaconState) ExpectedWithdrawals() ([]*enginev1.Withdrawal, error) {
|
||||
withdrawalIndex := b.nextWithdrawalIndex
|
||||
epoch := slots.ToEpoch(b.slot)
|
||||
|
||||
bound := mathutil.Min(uint64(len(b.validators)), params.BeaconConfig().MaxValidatorsPerWithdrawalsSweep)
|
||||
validatorsLen := b.validatorsLen()
|
||||
bound := mathutil.Min(uint64(validatorsLen), params.BeaconConfig().MaxValidatorsPerWithdrawalsSweep)
|
||||
for i := uint64(0); i < bound; i++ {
|
||||
val := b.validators[validatorIndex]
|
||||
balance := b.balances[validatorIndex]
|
||||
val, err := b.validatorAtIndex(validatorIndex)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not retrieve validator at index %d", validatorIndex)
|
||||
}
|
||||
balance, err := b.balanceAtIndex(validatorIndex)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not retrieve balance at index %d", validatorIndex)
|
||||
}
|
||||
if balance > 0 && isFullyWithdrawableValidator(val, epoch) {
|
||||
withdrawals = append(withdrawals, &enginev1.Withdrawal{
|
||||
Index: withdrawalIndex,
|
||||
@@ -79,7 +87,7 @@ func (b *BeaconState) ExpectedWithdrawals() ([]*enginev1.Withdrawal, error) {
|
||||
break
|
||||
}
|
||||
validatorIndex += 1
|
||||
if uint64(validatorIndex) == uint64(len(b.validators)) {
|
||||
if uint64(validatorIndex) == uint64(validatorsLen) {
|
||||
validatorIndex = 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,22 +65,14 @@ func ComputeFieldRootsWithHasher(ctx context.Context, state *BeaconState) ([][]b
|
||||
fieldRoots[types.LatestBlockHeader.RealPosition()] = headerHashTreeRoot[:]
|
||||
|
||||
// BlockRoots array root.
|
||||
bRoots := make([][]byte, len(state.blockRoots))
|
||||
for i := range bRoots {
|
||||
bRoots[i] = state.blockRoots[i][:]
|
||||
}
|
||||
blockRootsRoot, err := stateutil.ArraysRoot(bRoots, fieldparams.BlockRootsLength)
|
||||
blockRootsRoot, err := stateutil.ArraysRoot(state.blockRootsVal().Slice(), fieldparams.BlockRootsLength)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not compute block roots merkleization")
|
||||
}
|
||||
fieldRoots[types.BlockRoots.RealPosition()] = blockRootsRoot[:]
|
||||
|
||||
// StateRoots array root.
|
||||
sRoots := make([][]byte, len(state.stateRoots))
|
||||
for i := range sRoots {
|
||||
sRoots[i] = state.stateRoots[i][:]
|
||||
}
|
||||
stateRootsRoot, err := stateutil.ArraysRoot(sRoots, fieldparams.StateRootsLength)
|
||||
stateRootsRoot, err := stateutil.ArraysRoot(state.stateRootsVal().Slice(), fieldparams.StateRootsLength)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not compute state roots merkleization")
|
||||
}
|
||||
@@ -118,25 +110,21 @@ func ComputeFieldRootsWithHasher(ctx context.Context, state *BeaconState) ([][]b
|
||||
fieldRoots[types.Eth1DepositIndex.RealPosition()] = eth1DepositBuf[:]
|
||||
|
||||
// Validators slice root.
|
||||
validatorsRoot, err := stateutil.ValidatorRegistryRoot(state.validators)
|
||||
validatorsRoot, err := stateutil.ValidatorRegistryRoot(state.validatorsVal())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not compute validator registry merkleization")
|
||||
}
|
||||
fieldRoots[types.Validators.RealPosition()] = validatorsRoot[:]
|
||||
|
||||
// Balances slice root.
|
||||
balancesRoot, err := stateutil.Uint64ListRootWithRegistryLimit(state.balances)
|
||||
balancesRoot, err := stateutil.Uint64ListRootWithRegistryLimit(state.balancesVal())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not compute validator balances merkleization")
|
||||
}
|
||||
fieldRoots[types.Balances.RealPosition()] = balancesRoot[:]
|
||||
|
||||
// RandaoMixes array root.
|
||||
mixes := make([][]byte, len(state.randaoMixes))
|
||||
for i := range mixes {
|
||||
mixes[i] = state.randaoMixes[i][:]
|
||||
}
|
||||
randaoRootsRoot, err := stateutil.ArraysRoot(mixes, fieldparams.RandaoMixesLength)
|
||||
randaoRootsRoot, err := stateutil.ArraysRoot(state.randaoMixesVal().Slice(), fieldparams.RandaoMixesLength)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not compute randao roots merkleization")
|
||||
}
|
||||
@@ -208,7 +196,7 @@ func ComputeFieldRootsWithHasher(ctx context.Context, state *BeaconState) ([][]b
|
||||
|
||||
if state.version >= version.Altair {
|
||||
// Inactivity scores root.
|
||||
inactivityScoresRoot, err := stateutil.Uint64ListRootWithRegistryLimit(state.inactivityScores)
|
||||
inactivityScoresRoot, err := stateutil.Uint64ListRootWithRegistryLimit(state.inactivityScoresVal())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not compute inactivityScoreRoot")
|
||||
}
|
||||
|
||||
145
beacon-chain/state/state-native/multi_value_slices.go
Normal file
145
beacon-chain/state/state-native/multi_value_slices.go
Normal file
@@ -0,0 +1,145 @@
|
||||
package state_native
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
multi_value_slice "github.com/prysmaticlabs/prysm/v4/container/multi-value-slice"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
var (
|
||||
multiValueRandaoMixesCountGauge = promauto.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "multi_value_randao_mixes_count",
|
||||
})
|
||||
multiValueBlockRootsCountGauge = promauto.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "multi_value_block_roots_count",
|
||||
})
|
||||
multiValueStateRootsCountGauge = promauto.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "multi_value_state_roots_count",
|
||||
})
|
||||
multiValueBalancesCountGauge = promauto.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "multi_value_balances_count",
|
||||
})
|
||||
multiValueValidatorsCountGauge = promauto.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "multi_value_validators_count",
|
||||
})
|
||||
multiValueInactivityScoresCountGauge = promauto.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "multi_value_inactivity_scores_count",
|
||||
})
|
||||
)
|
||||
|
||||
// MultiValueRandaoMixes is a multi-value slice of randao mixes.
|
||||
type MultiValueRandaoMixes = multi_value_slice.Slice[[32]byte, *BeaconState]
|
||||
|
||||
// NewMultiValueRandaoMixes creates a new slice whose shared items will be populated with copies of input values.
|
||||
func NewMultiValueRandaoMixes(mixes [][]byte) *MultiValueRandaoMixes {
|
||||
items := make([][32]byte, fieldparams.RandaoMixesLength)
|
||||
for i, v := range mixes {
|
||||
items[i] = [32]byte(bytesutil.PadTo(v, 32))
|
||||
}
|
||||
mv := &MultiValueRandaoMixes{}
|
||||
mv.Init(items)
|
||||
multiValueRandaoMixesCountGauge.Inc()
|
||||
runtime.SetFinalizer(mv, randaoMixesFinalizer)
|
||||
return mv
|
||||
}
|
||||
|
||||
// MultiValueBlockRoots is a multi-value slice of block roots.
|
||||
type MultiValueBlockRoots = multi_value_slice.Slice[[32]byte, *BeaconState]
|
||||
|
||||
// NewMultiValueBlockRoots creates a new slice whose shared items will be populated with copies of input values.
|
||||
func NewMultiValueBlockRoots(roots [][]byte) *MultiValueBlockRoots {
|
||||
items := make([][32]byte, fieldparams.BlockRootsLength)
|
||||
for i, v := range roots {
|
||||
items[i] = [32]byte(bytesutil.PadTo(v, 32))
|
||||
}
|
||||
mv := &MultiValueBlockRoots{}
|
||||
mv.Init(items)
|
||||
multiValueBlockRootsCountGauge.Inc()
|
||||
runtime.SetFinalizer(mv, blockRootsFinalizer)
|
||||
return mv
|
||||
}
|
||||
|
||||
// MultiValueStateRoots is a multi-value slice of state roots.
|
||||
type MultiValueStateRoots = multi_value_slice.Slice[[32]byte, *BeaconState]
|
||||
|
||||
// NewMultiValueStateRoots creates a new slice whose shared items will be populated with copies of input values.
|
||||
func NewMultiValueStateRoots(roots [][]byte) *MultiValueStateRoots {
|
||||
items := make([][32]byte, fieldparams.StateRootsLength)
|
||||
for i, v := range roots {
|
||||
items[i] = [32]byte(bytesutil.PadTo(v, 32))
|
||||
}
|
||||
mv := &MultiValueStateRoots{}
|
||||
mv.Init(items)
|
||||
multiValueStateRootsCountGauge.Inc()
|
||||
runtime.SetFinalizer(mv, stateRootsFinalizer)
|
||||
return mv
|
||||
}
|
||||
|
||||
// MultiValueBalances is a multi-value slice of balances.
|
||||
type MultiValueBalances = multi_value_slice.Slice[uint64, *BeaconState]
|
||||
|
||||
// NewMultiValueBalances creates a new slice whose shared items will be populated with copies of input values.
|
||||
func NewMultiValueBalances(balances []uint64) *MultiValueBalances {
|
||||
items := make([]uint64, len(balances))
|
||||
copy(items, balances)
|
||||
mv := &MultiValueBalances{}
|
||||
mv.Init(items)
|
||||
multiValueBalancesCountGauge.Inc()
|
||||
runtime.SetFinalizer(mv, balancesFinalizer)
|
||||
return mv
|
||||
}
|
||||
|
||||
// MultiValueInactivityScores is a multi-value slice of inactivity scores.
|
||||
type MultiValueInactivityScores = multi_value_slice.Slice[uint64, *BeaconState]
|
||||
|
||||
// NewMultiValueInactivityScores creates a new slice whose shared items will be populated with copies of input values.
|
||||
func NewMultiValueInactivityScores(scores []uint64) *MultiValueInactivityScores {
|
||||
items := make([]uint64, len(scores))
|
||||
copy(items, scores)
|
||||
mv := &MultiValueInactivityScores{}
|
||||
mv.Init(items)
|
||||
multiValueInactivityScoresCountGauge.Inc()
|
||||
runtime.SetFinalizer(mv, inactivityScoresFinalizer)
|
||||
return mv
|
||||
}
|
||||
|
||||
// MultiValueValidators is a multi-value slice of validator references.
|
||||
type MultiValueValidators = multi_value_slice.Slice[*ethpb.Validator, *BeaconState]
|
||||
|
||||
// NewMultiValueValidators creates a new slice whose shared items will be populated with input values.
|
||||
func NewMultiValueValidators(vals []*ethpb.Validator) *MultiValueValidators {
|
||||
mv := &MultiValueValidators{}
|
||||
mv.Init(vals)
|
||||
multiValueValidatorsCountGauge.Inc()
|
||||
runtime.SetFinalizer(mv, validatorsFinalizer)
|
||||
return mv
|
||||
}
|
||||
|
||||
func randaoMixesFinalizer(m *MultiValueRandaoMixes) {
|
||||
multiValueRandaoMixesCountGauge.Dec()
|
||||
}
|
||||
|
||||
func blockRootsFinalizer(m *MultiValueBlockRoots) {
|
||||
multiValueBlockRootsCountGauge.Dec()
|
||||
}
|
||||
|
||||
func stateRootsFinalizer(m *MultiValueStateRoots) {
|
||||
multiValueStateRootsCountGauge.Dec()
|
||||
}
|
||||
|
||||
func balancesFinalizer(m *MultiValueBalances) {
|
||||
multiValueBalancesCountGauge.Dec()
|
||||
}
|
||||
|
||||
func validatorsFinalizer(m *MultiValueValidators) {
|
||||
multiValueValidatorsCountGauge.Dec()
|
||||
}
|
||||
|
||||
func inactivityScoresFinalizer(m *MultiValueInactivityScores) {
|
||||
multiValueInactivityScoresCountGauge.Dec()
|
||||
}
|
||||
71
beacon-chain/state/state-native/mvslice_fuzz_test.go
Normal file
71
beacon-chain/state/state-native/mvslice_fuzz_test.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package state_native
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
)
|
||||
|
||||
func FuzzMultiValueBalances(f *testing.F) {
|
||||
resetFn := features.InitWithReset(&features.Flags{
|
||||
EnableExperimentalState: true,
|
||||
})
|
||||
defer resetFn()
|
||||
|
||||
bals := make([]uint64, 65536)
|
||||
firstState, err := InitializeFromProtoPhase0(ðpb.BeaconState{Balances: bals})
|
||||
require.NoError(f, err)
|
||||
|
||||
f.Fuzz(func(t *testing.T, index uint16, value uint64) {
|
||||
secondState := firstState
|
||||
// there's a 25% chance we will copy the state
|
||||
copyState := index%4 == 0
|
||||
if copyState {
|
||||
secondState = firstState.Copy()
|
||||
}
|
||||
if index%2 == 0 {
|
||||
// update existing balance
|
||||
|
||||
oldValue, err := firstState.BalanceAtIndex(primitives.ValidatorIndex(index))
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, secondState.UpdateBalancesAtIndex(primitives.ValidatorIndex(index), value))
|
||||
|
||||
firstValue, err := firstState.BalanceAtIndex(primitives.ValidatorIndex(index))
|
||||
require.NoError(t, err)
|
||||
secondValue, err := secondState.BalanceAtIndex(primitives.ValidatorIndex(index))
|
||||
require.NoError(t, err)
|
||||
if copyState {
|
||||
require.Equal(t, oldValue, firstValue)
|
||||
require.Equal(t, value, secondValue)
|
||||
} else {
|
||||
require.Equal(t, value, firstValue)
|
||||
require.Equal(t, value, secondValue)
|
||||
}
|
||||
} else {
|
||||
// append new balance
|
||||
|
||||
firstLength := firstState.BalancesLength()
|
||||
|
||||
require.NoError(t, secondState.AppendBalance(value))
|
||||
|
||||
if copyState {
|
||||
require.Equal(t, firstLength, secondState.BalancesLength())
|
||||
v, err := firstState.BalanceAtIndex(primitives.ValidatorIndex(firstLength - 1))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, value, v)
|
||||
v, err = secondState.BalanceAtIndex(primitives.ValidatorIndex(secondState.BalancesLength() - 1))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, value, v)
|
||||
} else {
|
||||
require.Equal(t, firstLength+1, secondState.BalancesLength())
|
||||
v, err := secondState.BalanceAtIndex(primitives.ValidatorIndex(secondState.BalancesLength() - 1))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, value, v)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -38,7 +38,7 @@ func TestStateReferenceSharing_Finalizer_Phase0(t *testing.T) {
|
||||
b, ok := copied.(*BeaconState)
|
||||
require.Equal(t, true, ok)
|
||||
assert.Equal(t, uint(2), b.sharedFieldReferences[types.RandaoMixes].Refs(), "Expected 2 shared references to RANDAO mixes")
|
||||
require.NoError(t, b.UpdateRandaoMixesAtIndex(0, []byte("bar")))
|
||||
require.NoError(t, b.UpdateRandaoMixesAtIndex(0, bytesutil.ToBytes32([]byte("bar"))))
|
||||
if b.sharedFieldReferences[types.RandaoMixes].Refs() != 1 || a.sharedFieldReferences[types.RandaoMixes].Refs() != 1 {
|
||||
t.Error("Expected 1 shared reference to RANDAO mix for both a and b")
|
||||
}
|
||||
@@ -67,7 +67,7 @@ func TestStateReferenceSharing_Finalizer_Altair(t *testing.T) {
|
||||
b, ok := copied.(*BeaconState)
|
||||
require.Equal(t, true, ok)
|
||||
assert.Equal(t, uint(2), b.sharedFieldReferences[types.RandaoMixes].Refs(), "Expected 2 shared references to RANDAO mixes")
|
||||
require.NoError(t, b.UpdateRandaoMixesAtIndex(0, []byte("bar")))
|
||||
require.NoError(t, b.UpdateRandaoMixesAtIndex(0, bytesutil.ToBytes32([]byte("bar"))))
|
||||
if b.sharedFieldReferences[types.RandaoMixes].Refs() != 1 || a.sharedFieldReferences[types.RandaoMixes].Refs() != 1 {
|
||||
t.Error("Expected 1 shared reference to RANDAO mix for both a and b")
|
||||
}
|
||||
@@ -96,7 +96,7 @@ func TestStateReferenceSharing_Finalizer_Bellatrix(t *testing.T) {
|
||||
b, ok := copied.(*BeaconState)
|
||||
require.Equal(t, true, ok)
|
||||
assert.Equal(t, uint(2), b.sharedFieldReferences[types.RandaoMixes].Refs(), "Expected 2 shared references to RANDAO mixes")
|
||||
require.NoError(t, b.UpdateRandaoMixesAtIndex(0, []byte("bar")))
|
||||
require.NoError(t, b.UpdateRandaoMixesAtIndex(0, bytesutil.ToBytes32([]byte("bar"))))
|
||||
if b.sharedFieldReferences[types.RandaoMixes].Refs() != 1 || a.sharedFieldReferences[types.RandaoMixes].Refs() != 1 {
|
||||
t.Error("Expected 1 shared reference to RANDAO mix for both a and b")
|
||||
}
|
||||
@@ -125,7 +125,7 @@ func TestStateReferenceSharing_Finalizer_Capella(t *testing.T) {
|
||||
b, ok := copied.(*BeaconState)
|
||||
require.Equal(t, true, ok)
|
||||
assert.Equal(t, uint(2), b.sharedFieldReferences[types.RandaoMixes].Refs(), "Expected 2 shared references to RANDAO mixes")
|
||||
require.NoError(t, b.UpdateRandaoMixesAtIndex(0, []byte("bar")))
|
||||
require.NoError(t, b.UpdateRandaoMixesAtIndex(0, bytesutil.ToBytes32([]byte("bar"))))
|
||||
if b.sharedFieldReferences[types.RandaoMixes].Refs() != 1 || a.sharedFieldReferences[types.RandaoMixes].Refs() != 1 {
|
||||
t.Error("Expected 1 shared reference to RANDAO mix for both a and b")
|
||||
}
|
||||
@@ -154,7 +154,7 @@ func TestStateReferenceSharing_Finalizer_Deneb(t *testing.T) {
|
||||
b, ok := copied.(*BeaconState)
|
||||
require.Equal(t, true, ok)
|
||||
assert.Equal(t, uint(2), b.sharedFieldReferences[types.RandaoMixes].Refs(), "Expected 2 shared references to RANDAO mixes")
|
||||
require.NoError(t, b.UpdateRandaoMixesAtIndex(0, []byte("bar")))
|
||||
require.NoError(t, b.UpdateRandaoMixesAtIndex(0, bytesutil.ToBytes32([]byte("bar"))))
|
||||
if b.sharedFieldReferences[types.RandaoMixes].Refs() != 1 || a.sharedFieldReferences[types.RandaoMixes].Refs() != 1 {
|
||||
t.Error("Expected 1 shared reference to RANDAO mix for both a and b")
|
||||
}
|
||||
@@ -482,7 +482,7 @@ func TestStateReferenceCopy_NoUnexpectedRandaoMutation_Phase0(t *testing.T) {
|
||||
assertValFound(t, mixesB, val1[:])
|
||||
|
||||
// Mutator should only affect calling state: a.
|
||||
require.NoError(t, a.UpdateRandaoMixesAtIndex(0, val2[:]))
|
||||
require.NoError(t, a.UpdateRandaoMixesAtIndex(0, val2))
|
||||
|
||||
// Assert no shared state mutation occurred only on state a (copy on write).
|
||||
assertValFound(t, a.RandaoMixes(), val2[:])
|
||||
@@ -526,7 +526,7 @@ func TestStateReferenceCopy_NoUnexpectedRandaoMutation_Altair(t *testing.T) {
|
||||
assertValFound(t, mixesB, val1[:])
|
||||
|
||||
// Mutator should only affect calling state: a.
|
||||
require.NoError(t, a.UpdateRandaoMixesAtIndex(0, val2[:]))
|
||||
require.NoError(t, a.UpdateRandaoMixesAtIndex(0, val2))
|
||||
|
||||
// Assert no shared state mutation occurred only on state a (copy on write).
|
||||
assertValFound(t, a.RandaoMixes(), val2[:])
|
||||
@@ -570,7 +570,7 @@ func TestStateReferenceCopy_NoUnexpectedRandaoMutation_Bellatrix(t *testing.T) {
|
||||
assertValFound(t, mixesB, val1[:])
|
||||
|
||||
// Mutator should only affect calling state: a.
|
||||
require.NoError(t, a.UpdateRandaoMixesAtIndex(0, val2[:]))
|
||||
require.NoError(t, a.UpdateRandaoMixesAtIndex(0, val2))
|
||||
|
||||
// Assert no shared state mutation occurred only on state a (copy on write).
|
||||
assertValFound(t, a.RandaoMixes(), val2[:])
|
||||
@@ -614,7 +614,7 @@ func TestStateReferenceCopy_NoUnexpectedRandaoMutation_Capella(t *testing.T) {
|
||||
assertValFound(t, mixesB, val1[:])
|
||||
|
||||
// Mutator should only affect calling state: a.
|
||||
require.NoError(t, a.UpdateRandaoMixesAtIndex(0, val2[:]))
|
||||
require.NoError(t, a.UpdateRandaoMixesAtIndex(0, val2))
|
||||
|
||||
// Assert no shared state mutation occurred only on state a (copy on write).
|
||||
assertValFound(t, a.RandaoMixes(), val2[:])
|
||||
@@ -658,7 +658,7 @@ func TestStateReferenceCopy_NoUnexpectedRandaoMutation_Deneb(t *testing.T) {
|
||||
assertValFound(t, mixesB, val1[:])
|
||||
|
||||
// Mutator should only affect calling state: a.
|
||||
require.NoError(t, a.UpdateRandaoMixesAtIndex(0, val2[:]))
|
||||
require.NoError(t, a.UpdateRandaoMixesAtIndex(0, val2))
|
||||
|
||||
// Assert no shared state mutation occurred only on state a (copy on write).
|
||||
assertValFound(t, a.RandaoMixes(), val2[:])
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package state_native
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
customtypes "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/custom-types"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/types"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stateutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
consensus_types "github.com/prysmaticlabs/prysm/v4/consensus-types"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
@@ -26,15 +26,22 @@ func (b *BeaconState) SetBlockRoots(val [][]byte) error {
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
|
||||
b.sharedFieldReferences[types.BlockRoots].MinusRef()
|
||||
b.sharedFieldReferences[types.BlockRoots] = stateutil.NewRef(1)
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.blockRootsMultiValue != nil {
|
||||
b.blockRootsMultiValue.Detach(b)
|
||||
}
|
||||
b.blockRootsMultiValue = NewMultiValueBlockRoots(val)
|
||||
} else {
|
||||
b.sharedFieldReferences[types.BlockRoots].MinusRef()
|
||||
b.sharedFieldReferences[types.BlockRoots] = stateutil.NewRef(1)
|
||||
|
||||
var rootsArr [fieldparams.BlockRootsLength][32]byte
|
||||
for i := 0; i < len(rootsArr); i++ {
|
||||
copy(rootsArr[i][:], val[i])
|
||||
rootsArr := make([][32]byte, fieldparams.BlockRootsLength)
|
||||
for i := 0; i < len(rootsArr); i++ {
|
||||
copy(rootsArr[i][:], val[i])
|
||||
}
|
||||
b.blockRoots = rootsArr
|
||||
}
|
||||
roots := customtypes.BlockRoots(rootsArr)
|
||||
b.blockRoots = &roots
|
||||
|
||||
b.markFieldAsDirty(types.BlockRoots)
|
||||
b.rebuildTrie[types.BlockRoots] = true
|
||||
return nil
|
||||
@@ -43,24 +50,29 @@ func (b *BeaconState) SetBlockRoots(val [][]byte) error {
|
||||
// UpdateBlockRootAtIndex for the beacon state. Updates the block root
|
||||
// at a specific index to a new value.
|
||||
func (b *BeaconState) UpdateBlockRootAtIndex(idx uint64, blockRoot [32]byte) error {
|
||||
if uint64(len(b.blockRoots)) <= idx {
|
||||
return fmt.Errorf("invalid index provided %d", idx)
|
||||
}
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
|
||||
r := b.blockRoots
|
||||
if ref := b.sharedFieldReferences[types.BlockRoots]; ref.Refs() > 1 {
|
||||
// Copy elements in underlying array by reference.
|
||||
roots := *b.blockRoots
|
||||
rootsCopy := roots
|
||||
r = &rootsCopy
|
||||
ref.MinusRef()
|
||||
b.sharedFieldReferences[types.BlockRoots] = stateutil.NewRef(1)
|
||||
}
|
||||
if features.Get().EnableExperimentalState {
|
||||
if err := b.blockRootsMultiValue.UpdateAt(b, idx, blockRoot); err != nil {
|
||||
return errors.Wrap(err, "could not update block roots")
|
||||
}
|
||||
} else {
|
||||
if uint64(len(b.blockRoots)) <= idx {
|
||||
return errors.Wrapf(consensus_types.ErrOutOfBounds, "block root index %d does not exist", idx)
|
||||
}
|
||||
|
||||
r[idx] = blockRoot
|
||||
b.blockRoots = r
|
||||
r := b.blockRoots
|
||||
if ref := b.sharedFieldReferences[types.BlockRoots]; ref.Refs() > 1 {
|
||||
// Copy elements in underlying array by reference.
|
||||
r = make([][32]byte, len(b.blockRoots))
|
||||
copy(r, b.blockRoots)
|
||||
ref.MinusRef()
|
||||
b.sharedFieldReferences[types.BlockRoots] = stateutil.NewRef(1)
|
||||
}
|
||||
r[idx] = blockRoot
|
||||
b.blockRoots = r
|
||||
}
|
||||
|
||||
b.markFieldAsDirty(types.BlockRoots)
|
||||
b.addDirtyIndices(types.BlockRoots, []uint64{idx})
|
||||
|
||||
@@ -2,11 +2,11 @@ package state_native
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
customtypes "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/custom-types"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/types"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stateutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
consensus_types "github.com/prysmaticlabs/prysm/v4/consensus-types"
|
||||
)
|
||||
|
||||
// SetRandaoMixes for the beacon state. Updates the entire
|
||||
@@ -15,15 +15,22 @@ func (b *BeaconState) SetRandaoMixes(val [][]byte) error {
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
|
||||
b.sharedFieldReferences[types.RandaoMixes].MinusRef()
|
||||
b.sharedFieldReferences[types.RandaoMixes] = stateutil.NewRef(1)
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.randaoMixesMultiValue != nil {
|
||||
b.randaoMixesMultiValue.Detach(b)
|
||||
}
|
||||
b.randaoMixesMultiValue = NewMultiValueRandaoMixes(val)
|
||||
} else {
|
||||
b.sharedFieldReferences[types.RandaoMixes].MinusRef()
|
||||
b.sharedFieldReferences[types.RandaoMixes] = stateutil.NewRef(1)
|
||||
|
||||
var mixesArr [fieldparams.RandaoMixesLength][32]byte
|
||||
for i := 0; i < len(mixesArr); i++ {
|
||||
copy(mixesArr[i][:], val[i])
|
||||
rootsArr := make([][32]byte, fieldparams.RandaoMixesLength)
|
||||
for i := 0; i < len(rootsArr); i++ {
|
||||
copy(rootsArr[i][:], val[i])
|
||||
}
|
||||
b.randaoMixes = rootsArr
|
||||
}
|
||||
mixes := customtypes.RandaoMixes(mixesArr)
|
||||
b.randaoMixes = &mixes
|
||||
|
||||
b.markFieldAsDirty(types.RandaoMixes)
|
||||
b.rebuildTrie[types.RandaoMixes] = true
|
||||
return nil
|
||||
@@ -31,27 +38,36 @@ func (b *BeaconState) SetRandaoMixes(val [][]byte) error {
|
||||
|
||||
// UpdateRandaoMixesAtIndex for the beacon state. Updates the randao mixes
|
||||
// at a specific index to a new value.
|
||||
func (b *BeaconState) UpdateRandaoMixesAtIndex(idx uint64, val []byte) error {
|
||||
if uint64(len(b.randaoMixes)) <= idx {
|
||||
return errors.Errorf("invalid index provided %d", idx)
|
||||
func (b *BeaconState) UpdateRandaoMixesAtIndex(idx uint64, val [32]byte) error {
|
||||
if features.Get().EnableExperimentalState {
|
||||
if err := b.randaoMixesMultiValue.UpdateAt(b, idx, val); err != nil {
|
||||
return errors.Wrap(err, "could not update randao mixes")
|
||||
}
|
||||
} else {
|
||||
if uint64(len(b.randaoMixes)) <= idx {
|
||||
return errors.Wrapf(consensus_types.ErrOutOfBounds, "randao mix index %d does not exist", idx)
|
||||
}
|
||||
|
||||
b.lock.Lock()
|
||||
|
||||
m := b.randaoMixes
|
||||
if ref := b.sharedFieldReferences[types.RandaoMixes]; ref.Refs() > 1 {
|
||||
// Copy elements in underlying array by reference.
|
||||
m = make([][32]byte, len(b.randaoMixes))
|
||||
copy(m, b.randaoMixes)
|
||||
ref.MinusRef()
|
||||
b.sharedFieldReferences[types.RandaoMixes] = stateutil.NewRef(1)
|
||||
}
|
||||
m[idx] = val
|
||||
b.randaoMixes = m
|
||||
|
||||
b.lock.Unlock()
|
||||
}
|
||||
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
|
||||
mixes := b.randaoMixes
|
||||
if refs := b.sharedFieldReferences[types.RandaoMixes].Refs(); refs > 1 {
|
||||
// Copy elements in underlying array by reference.
|
||||
m := *b.randaoMixes
|
||||
mCopy := m
|
||||
mixes = &mCopy
|
||||
b.sharedFieldReferences[types.RandaoMixes].MinusRef()
|
||||
b.sharedFieldReferences[types.RandaoMixes] = stateutil.NewRef(1)
|
||||
}
|
||||
|
||||
mixes[idx] = bytesutil.ToBytes32(val)
|
||||
b.randaoMixes = mixes
|
||||
b.markFieldAsDirty(types.RandaoMixes)
|
||||
b.addDirtyIndices(types.RandaoMixes, []uint64{idx})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2,10 +2,11 @@ package state_native
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
customtypes "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/custom-types"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/types"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stateutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
consensus_types "github.com/prysmaticlabs/prysm/v4/consensus-types"
|
||||
)
|
||||
|
||||
// SetStateRoots for the beacon state. Updates the state roots
|
||||
@@ -14,15 +15,22 @@ func (b *BeaconState) SetStateRoots(val [][]byte) error {
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
|
||||
b.sharedFieldReferences[types.StateRoots].MinusRef()
|
||||
b.sharedFieldReferences[types.StateRoots] = stateutil.NewRef(1)
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.stateRootsMultiValue != nil {
|
||||
b.stateRootsMultiValue.Detach(b)
|
||||
}
|
||||
b.stateRootsMultiValue = NewMultiValueStateRoots(val)
|
||||
} else {
|
||||
b.sharedFieldReferences[types.StateRoots].MinusRef()
|
||||
b.sharedFieldReferences[types.StateRoots] = stateutil.NewRef(1)
|
||||
|
||||
var rootsArr [fieldparams.StateRootsLength][32]byte
|
||||
for i := 0; i < len(rootsArr); i++ {
|
||||
copy(rootsArr[i][:], val[i])
|
||||
rootsArr := make([][32]byte, fieldparams.StateRootsLength)
|
||||
for i := 0; i < len(rootsArr); i++ {
|
||||
copy(rootsArr[i][:], val[i])
|
||||
}
|
||||
b.stateRoots = rootsArr
|
||||
}
|
||||
roots := customtypes.StateRoots(rootsArr)
|
||||
b.stateRoots = &roots
|
||||
|
||||
b.markFieldAsDirty(types.StateRoots)
|
||||
b.rebuildTrie[types.StateRoots] = true
|
||||
return nil
|
||||
@@ -31,30 +39,34 @@ func (b *BeaconState) SetStateRoots(val [][]byte) error {
|
||||
// UpdateStateRootAtIndex for the beacon state. Updates the state root
|
||||
// at a specific index to a new value.
|
||||
func (b *BeaconState) UpdateStateRootAtIndex(idx uint64, stateRoot [32]byte) error {
|
||||
b.lock.RLock()
|
||||
if uint64(len(b.stateRoots)) <= idx {
|
||||
b.lock.RUnlock()
|
||||
return errors.Errorf("invalid index provided %d", idx)
|
||||
if features.Get().EnableExperimentalState {
|
||||
if err := b.stateRootsMultiValue.UpdateAt(b, idx, stateRoot); err != nil {
|
||||
return errors.Wrap(err, "could not update state roots")
|
||||
}
|
||||
} else {
|
||||
if uint64(len(b.stateRoots)) <= idx {
|
||||
return errors.Wrapf(consensus_types.ErrOutOfBounds, "state root index %d does not exist", idx)
|
||||
}
|
||||
|
||||
b.lock.Lock()
|
||||
|
||||
r := b.stateRoots
|
||||
if ref := b.sharedFieldReferences[types.StateRoots]; ref.Refs() > 1 {
|
||||
// Copy elements in underlying array by reference.
|
||||
r = make([][32]byte, len(b.stateRoots))
|
||||
copy(r, b.stateRoots)
|
||||
ref.MinusRef()
|
||||
b.sharedFieldReferences[types.StateRoots] = stateutil.NewRef(1)
|
||||
}
|
||||
r[idx] = stateRoot
|
||||
b.stateRoots = r
|
||||
|
||||
b.lock.Unlock()
|
||||
}
|
||||
b.lock.RUnlock()
|
||||
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
|
||||
// Check if we hold the only reference to the shared state roots slice.
|
||||
r := b.stateRoots
|
||||
if ref := b.sharedFieldReferences[types.StateRoots]; ref.Refs() > 1 {
|
||||
// Copy elements in underlying array by reference.
|
||||
roots := *b.stateRoots
|
||||
rootsCopy := roots
|
||||
r = &rootsCopy
|
||||
ref.MinusRef()
|
||||
b.sharedFieldReferences[types.StateRoots] = stateutil.NewRef(1)
|
||||
}
|
||||
|
||||
r[idx] = stateRoot
|
||||
b.stateRoots = r
|
||||
|
||||
b.markFieldAsDirty(types.StateRoots)
|
||||
b.addDirtyIndices(types.StateRoots, []uint64{idx})
|
||||
return nil
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/types"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stateutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
consensus_types "github.com/prysmaticlabs/prysm/v4/consensus-types"
|
||||
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
||||
@@ -16,69 +18,119 @@ func (b *BeaconState) SetValidators(val []*ethpb.Validator) error {
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
|
||||
b.validators = val
|
||||
b.sharedFieldReferences[types.Validators].MinusRef()
|
||||
b.sharedFieldReferences[types.Validators] = stateutil.NewRef(1)
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.validatorsMultiValue != nil {
|
||||
b.validatorsMultiValue.Detach(b)
|
||||
}
|
||||
b.validatorsMultiValue = NewMultiValueValidators(val)
|
||||
} else {
|
||||
b.validators = val
|
||||
b.sharedFieldReferences[types.Validators].MinusRef()
|
||||
b.sharedFieldReferences[types.Validators] = stateutil.NewRef(1)
|
||||
}
|
||||
|
||||
b.markFieldAsDirty(types.Validators)
|
||||
b.rebuildTrie[types.Validators] = true
|
||||
b.valMapHandler = stateutil.NewValMapHandler(b.validators)
|
||||
b.valMapHandler = stateutil.NewValMapHandler(val)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ApplyToEveryValidator applies the provided callback function to each validator in the
|
||||
// validator registry.
|
||||
func (b *BeaconState) ApplyToEveryValidator(f func(idx int, val *ethpb.Validator) (bool, *ethpb.Validator, error)) error {
|
||||
b.lock.Lock()
|
||||
v := b.validators
|
||||
if ref := b.sharedFieldReferences[types.Validators]; ref.Refs() > 1 {
|
||||
v = b.validatorsReferences()
|
||||
ref.MinusRef()
|
||||
b.sharedFieldReferences[types.Validators] = stateutil.NewRef(1)
|
||||
}
|
||||
b.lock.Unlock()
|
||||
var changedVals []uint64
|
||||
for i, val := range v {
|
||||
changed, newVal, err := f(i, val)
|
||||
if err != nil {
|
||||
return err
|
||||
if features.Get().EnableExperimentalState {
|
||||
b.lock.Lock()
|
||||
|
||||
l := b.validatorsMultiValue.Len(b)
|
||||
for i := 0; i < l; i++ {
|
||||
v, err := b.validatorsMultiValue.At(b, uint64(i))
|
||||
if err != nil {
|
||||
b.lock.Unlock()
|
||||
return err
|
||||
}
|
||||
changed, newVal, err := f(i, v)
|
||||
if err != nil {
|
||||
b.lock.Unlock()
|
||||
return err
|
||||
}
|
||||
if changed {
|
||||
changedVals = append(changedVals, uint64(i))
|
||||
if err = b.validatorsMultiValue.UpdateAt(b, uint64(i), newVal); err != nil {
|
||||
b.lock.Unlock()
|
||||
return errors.Wrapf(err, "could not update validator at index %d", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
if changed {
|
||||
changedVals = append(changedVals, uint64(i))
|
||||
v[i] = newVal
|
||||
|
||||
b.lock.Unlock()
|
||||
} else {
|
||||
b.lock.Lock()
|
||||
|
||||
v := b.validators
|
||||
if ref := b.sharedFieldReferences[types.Validators]; ref.Refs() > 1 {
|
||||
v = b.validatorsReferences()
|
||||
ref.MinusRef()
|
||||
b.sharedFieldReferences[types.Validators] = stateutil.NewRef(1)
|
||||
}
|
||||
|
||||
b.lock.Unlock()
|
||||
|
||||
for i, val := range v {
|
||||
changed, newVal, err := f(i, val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if changed {
|
||||
changedVals = append(changedVals, uint64(i))
|
||||
v[i] = newVal
|
||||
}
|
||||
}
|
||||
|
||||
b.lock.Lock()
|
||||
b.validators = v
|
||||
b.lock.Unlock()
|
||||
}
|
||||
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
|
||||
b.validators = v
|
||||
b.markFieldAsDirty(types.Validators)
|
||||
b.addDirtyIndices(types.Validators, changedVals)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateValidatorAtIndex for the beacon state. Updates the validator
|
||||
// at a specific index to a new value.
|
||||
func (b *BeaconState) UpdateValidatorAtIndex(idx primitives.ValidatorIndex, val *ethpb.Validator) error {
|
||||
if uint64(len(b.validators)) <= uint64(idx) {
|
||||
return errors.Errorf("invalid index provided %d", idx)
|
||||
if features.Get().EnableExperimentalState {
|
||||
if err := b.validatorsMultiValue.UpdateAt(b, uint64(idx), val); err != nil {
|
||||
return errors.Wrap(err, "could not update validator")
|
||||
}
|
||||
} else {
|
||||
if uint64(len(b.validators)) <= uint64(idx) {
|
||||
return errors.Wrapf(consensus_types.ErrOutOfBounds, "validator index %d does not exist", idx)
|
||||
}
|
||||
|
||||
b.lock.Lock()
|
||||
|
||||
v := b.validators
|
||||
if ref := b.sharedFieldReferences[types.Validators]; ref.Refs() > 1 {
|
||||
v = b.validatorsReferences()
|
||||
ref.MinusRef()
|
||||
b.sharedFieldReferences[types.Validators] = stateutil.NewRef(1)
|
||||
}
|
||||
v[idx] = val
|
||||
b.validators = v
|
||||
|
||||
b.lock.Unlock()
|
||||
}
|
||||
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
|
||||
v := b.validators
|
||||
if ref := b.sharedFieldReferences[types.Validators]; ref.Refs() > 1 {
|
||||
v = b.validatorsReferences()
|
||||
ref.MinusRef()
|
||||
b.sharedFieldReferences[types.Validators] = stateutil.NewRef(1)
|
||||
}
|
||||
|
||||
v[idx] = val
|
||||
b.validators = v
|
||||
b.markFieldAsDirty(types.Validators)
|
||||
b.addDirtyIndices(types.Validators, []uint64{uint64(idx)})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -88,10 +140,17 @@ func (b *BeaconState) SetBalances(val []uint64) error {
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
|
||||
b.sharedFieldReferences[types.Balances].MinusRef()
|
||||
b.sharedFieldReferences[types.Balances] = stateutil.NewRef(1)
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.balancesMultiValue != nil {
|
||||
b.balancesMultiValue.Detach(b)
|
||||
}
|
||||
b.balancesMultiValue = NewMultiValueBalances(val)
|
||||
} else {
|
||||
b.sharedFieldReferences[types.Balances].MinusRef()
|
||||
b.sharedFieldReferences[types.Balances] = stateutil.NewRef(1)
|
||||
b.balances = val
|
||||
}
|
||||
|
||||
b.balances = val
|
||||
b.markFieldAsDirty(types.Balances)
|
||||
b.rebuildTrie[types.Balances] = true
|
||||
return nil
|
||||
@@ -100,21 +159,32 @@ func (b *BeaconState) SetBalances(val []uint64) error {
|
||||
// UpdateBalancesAtIndex for the beacon state. This method updates the balance
|
||||
// at a specific index to a new value.
|
||||
func (b *BeaconState) UpdateBalancesAtIndex(idx primitives.ValidatorIndex, val uint64) error {
|
||||
if uint64(len(b.balances)) <= uint64(idx) {
|
||||
return errors.Errorf("invalid index provided %d", idx)
|
||||
if features.Get().EnableExperimentalState {
|
||||
if err := b.balancesMultiValue.UpdateAt(b, uint64(idx), val); err != nil {
|
||||
return errors.Wrap(err, "could not update balances")
|
||||
}
|
||||
} else {
|
||||
if uint64(len(b.balances)) <= uint64(idx) {
|
||||
return errors.Wrapf(consensus_types.ErrOutOfBounds, "balance index %d does not exist", idx)
|
||||
}
|
||||
|
||||
b.lock.Lock()
|
||||
|
||||
bals := b.balances
|
||||
if b.sharedFieldReferences[types.Balances].Refs() > 1 {
|
||||
bals = b.balancesVal()
|
||||
b.sharedFieldReferences[types.Balances].MinusRef()
|
||||
b.sharedFieldReferences[types.Balances] = stateutil.NewRef(1)
|
||||
}
|
||||
bals[idx] = val
|
||||
b.balances = bals
|
||||
|
||||
b.lock.Unlock()
|
||||
}
|
||||
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
|
||||
bals := b.balances
|
||||
if b.sharedFieldReferences[types.Balances].Refs() > 1 {
|
||||
bals = b.balancesVal()
|
||||
b.sharedFieldReferences[types.Balances].MinusRef()
|
||||
b.sharedFieldReferences[types.Balances] = stateutil.NewRef(1)
|
||||
}
|
||||
|
||||
bals[idx] = val
|
||||
b.balances = bals
|
||||
b.markFieldAsDirty(types.Balances)
|
||||
b.addDirtyIndices(types.Balances, []uint64{uint64(idx)})
|
||||
return nil
|
||||
@@ -161,22 +231,30 @@ func (b *BeaconState) UpdateSlashingsAtIndex(idx, val uint64) error {
|
||||
// AppendValidator for the beacon state. Appends the new value
|
||||
// to the end of list.
|
||||
func (b *BeaconState) AppendValidator(val *ethpb.Validator) error {
|
||||
var valIdx primitives.ValidatorIndex
|
||||
if features.Get().EnableExperimentalState {
|
||||
b.validatorsMultiValue.Append(b, val)
|
||||
valIdx = primitives.ValidatorIndex(b.validatorsMultiValue.Len(b) - 1)
|
||||
} else {
|
||||
b.lock.Lock()
|
||||
|
||||
vals := b.validators
|
||||
if b.sharedFieldReferences[types.Validators].Refs() > 1 {
|
||||
vals = b.validatorsReferences()
|
||||
b.sharedFieldReferences[types.Validators].MinusRef()
|
||||
b.sharedFieldReferences[types.Validators] = stateutil.NewRef(1)
|
||||
}
|
||||
|
||||
b.validators = append(vals, val)
|
||||
valIdx = primitives.ValidatorIndex(len(b.validators) - 1)
|
||||
|
||||
b.lock.Unlock()
|
||||
}
|
||||
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
|
||||
vals := b.validators
|
||||
if b.sharedFieldReferences[types.Validators].Refs() > 1 {
|
||||
vals = b.validatorsReferences()
|
||||
b.sharedFieldReferences[types.Validators].MinusRef()
|
||||
b.sharedFieldReferences[types.Validators] = stateutil.NewRef(1)
|
||||
}
|
||||
|
||||
// append validator to slice
|
||||
b.validators = append(vals, val)
|
||||
valIdx := primitives.ValidatorIndex(len(b.validators) - 1)
|
||||
|
||||
b.valMapHandler.Set(bytesutil.ToBytes48(val.PublicKey), valIdx)
|
||||
|
||||
b.markFieldAsDirty(types.Validators)
|
||||
b.addDirtyIndices(types.Validators, []uint64{uint64(valIdx)})
|
||||
return nil
|
||||
@@ -185,42 +263,61 @@ func (b *BeaconState) AppendValidator(val *ethpb.Validator) error {
|
||||
// AppendBalance for the beacon state. Appends the new value
|
||||
// to the end of list.
|
||||
func (b *BeaconState) AppendBalance(bal uint64) error {
|
||||
var balIdx uint64
|
||||
if features.Get().EnableExperimentalState {
|
||||
b.balancesMultiValue.Append(b, bal)
|
||||
balIdx = uint64(b.balancesMultiValue.Len(b) - 1)
|
||||
} else {
|
||||
b.lock.Lock()
|
||||
|
||||
bals := b.balances
|
||||
if b.sharedFieldReferences[types.Balances].Refs() > 1 {
|
||||
bals = make([]uint64, 0, len(b.balances)+1)
|
||||
bals = append(bals, b.balances...)
|
||||
b.sharedFieldReferences[types.Balances].MinusRef()
|
||||
b.sharedFieldReferences[types.Balances] = stateutil.NewRef(1)
|
||||
}
|
||||
|
||||
b.balances = append(bals, bal)
|
||||
balIdx = uint64(len(b.balances) - 1)
|
||||
|
||||
b.lock.Unlock()
|
||||
}
|
||||
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
|
||||
bals := b.balances
|
||||
if b.sharedFieldReferences[types.Balances].Refs() > 1 {
|
||||
bals = make([]uint64, 0, len(b.balances)+1)
|
||||
bals = append(bals, b.balances...)
|
||||
b.sharedFieldReferences[types.Balances].MinusRef()
|
||||
b.sharedFieldReferences[types.Balances] = stateutil.NewRef(1)
|
||||
}
|
||||
|
||||
b.balances = append(bals, bal)
|
||||
balIdx := len(b.balances) - 1
|
||||
b.markFieldAsDirty(types.Balances)
|
||||
b.addDirtyIndices(types.Balances, []uint64{uint64(balIdx)})
|
||||
b.addDirtyIndices(types.Balances, []uint64{balIdx})
|
||||
return nil
|
||||
}
|
||||
|
||||
// AppendInactivityScore for the beacon state.
|
||||
func (b *BeaconState) AppendInactivityScore(s uint64) error {
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
|
||||
if b.version == version.Phase0 {
|
||||
return errNotSupported("AppendInactivityScore", b.version)
|
||||
}
|
||||
|
||||
scores := b.inactivityScores
|
||||
if b.sharedFieldReferences[types.InactivityScores].Refs() > 1 {
|
||||
scores = make([]uint64, 0, len(b.inactivityScores)+1)
|
||||
scores = append(scores, b.inactivityScores...)
|
||||
b.sharedFieldReferences[types.InactivityScores].MinusRef()
|
||||
b.sharedFieldReferences[types.InactivityScores] = stateutil.NewRef(1)
|
||||
if features.Get().EnableExperimentalState {
|
||||
b.inactivityScoresMultiValue.Append(b, s)
|
||||
} else {
|
||||
b.lock.Lock()
|
||||
|
||||
scores := b.inactivityScores
|
||||
if b.sharedFieldReferences[types.InactivityScores].Refs() > 1 {
|
||||
scores = make([]uint64, 0, len(b.inactivityScores)+1)
|
||||
scores = append(scores, b.inactivityScores...)
|
||||
b.sharedFieldReferences[types.InactivityScores].MinusRef()
|
||||
b.sharedFieldReferences[types.InactivityScores] = stateutil.NewRef(1)
|
||||
}
|
||||
b.inactivityScores = append(scores, s)
|
||||
|
||||
b.lock.Unlock()
|
||||
}
|
||||
|
||||
b.inactivityScores = append(scores, s)
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
|
||||
b.markFieldAsDirty(types.InactivityScores)
|
||||
return nil
|
||||
}
|
||||
@@ -235,10 +332,17 @@ func (b *BeaconState) SetInactivityScores(val []uint64) error {
|
||||
return errNotSupported("SetInactivityScores", b.version)
|
||||
}
|
||||
|
||||
b.sharedFieldReferences[types.InactivityScores].MinusRef()
|
||||
b.sharedFieldReferences[types.InactivityScores] = stateutil.NewRef(1)
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.inactivityScoresMultiValue != nil {
|
||||
b.inactivityScoresMultiValue.Detach(b)
|
||||
}
|
||||
b.inactivityScoresMultiValue = NewMultiValueInactivityScores(val)
|
||||
} else {
|
||||
b.sharedFieldReferences[types.InactivityScores].MinusRef()
|
||||
b.sharedFieldReferences[types.InactivityScores] = stateutil.NewRef(1)
|
||||
b.inactivityScores = val
|
||||
}
|
||||
|
||||
b.inactivityScores = val
|
||||
b.markFieldAsDirty(types.InactivityScores)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
customtypes "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/custom-types"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/types"
|
||||
"github.com/prysmaticlabs/prysm/v4/beacon-chain/state/stateutil"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/features"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v4/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v4/container/slice"
|
||||
@@ -92,11 +93,16 @@ var denebFields = append(
|
||||
)
|
||||
|
||||
const (
|
||||
phase0SharedFieldRefCount = 10
|
||||
altairSharedFieldRefCount = 11
|
||||
bellatrixSharedFieldRefCount = 12
|
||||
capellaSharedFieldRefCount = 14
|
||||
denebSharedFieldRefCount = 14
|
||||
phase0SharedFieldRefCount = 10
|
||||
altairSharedFieldRefCount = 11
|
||||
bellatrixSharedFieldRefCount = 12
|
||||
capellaSharedFieldRefCount = 14
|
||||
denebSharedFieldRefCount = 14
|
||||
experimentalStatePhase0SharedFieldRefCount = 5
|
||||
experimentalStateAltairSharedFieldRefCount = 5
|
||||
experimentalStateBellatrixSharedFieldRefCount = 6
|
||||
experimentalStateCapellaSharedFieldRefCount = 8
|
||||
experimentalStateDenebSharedFieldRefCount = 8
|
||||
)
|
||||
|
||||
// InitializeFromProtoPhase0 the beacon state from a protobuf representation.
|
||||
@@ -131,22 +137,10 @@ func InitializeFromProtoUnsafePhase0(st *ethpb.BeaconState) (state.BeaconState,
|
||||
return nil, errors.New("received nil state")
|
||||
}
|
||||
|
||||
var bRoots customtypes.BlockRoots
|
||||
for i, r := range st.BlockRoots {
|
||||
copy(bRoots[i][:], r)
|
||||
}
|
||||
var sRoots customtypes.StateRoots
|
||||
for i, r := range st.StateRoots {
|
||||
copy(sRoots[i][:], r)
|
||||
}
|
||||
hRoots := customtypes.HistoricalRoots(make([][32]byte, len(st.HistoricalRoots)))
|
||||
for i, r := range st.HistoricalRoots {
|
||||
copy(hRoots[i][:], r)
|
||||
}
|
||||
var mixes customtypes.RandaoMixes
|
||||
for i, m := range st.RandaoMixes {
|
||||
copy(mixes[i][:], m)
|
||||
}
|
||||
|
||||
fieldCount := params.BeaconConfig().BeaconStateFieldCount
|
||||
b := &BeaconState{
|
||||
@@ -156,15 +150,10 @@ func InitializeFromProtoUnsafePhase0(st *ethpb.BeaconState) (state.BeaconState,
|
||||
slot: st.Slot,
|
||||
fork: st.Fork,
|
||||
latestBlockHeader: st.LatestBlockHeader,
|
||||
blockRoots: &bRoots,
|
||||
stateRoots: &sRoots,
|
||||
historicalRoots: hRoots,
|
||||
eth1Data: st.Eth1Data,
|
||||
eth1DataVotes: st.Eth1DataVotes,
|
||||
eth1DepositIndex: st.Eth1DepositIndex,
|
||||
validators: st.Validators,
|
||||
balances: st.Balances,
|
||||
randaoMixes: &mixes,
|
||||
slashings: st.Slashings,
|
||||
previousEpochAttestations: st.PreviousEpochAttestations,
|
||||
currentEpochAttestations: st.CurrentEpochAttestations,
|
||||
@@ -173,12 +162,45 @@ func InitializeFromProtoUnsafePhase0(st *ethpb.BeaconState) (state.BeaconState,
|
||||
currentJustifiedCheckpoint: st.CurrentJustifiedCheckpoint,
|
||||
finalizedCheckpoint: st.FinalizedCheckpoint,
|
||||
|
||||
dirtyFields: make(map[types.FieldIndex]bool, fieldCount),
|
||||
dirtyIndices: make(map[types.FieldIndex][]uint64, fieldCount),
|
||||
stateFieldLeaves: make(map[types.FieldIndex]*fieldtrie.FieldTrie, fieldCount),
|
||||
sharedFieldReferences: make(map[types.FieldIndex]*stateutil.Reference, phase0SharedFieldRefCount),
|
||||
rebuildTrie: make(map[types.FieldIndex]bool, fieldCount),
|
||||
valMapHandler: stateutil.NewValMapHandler(st.Validators),
|
||||
id: types.Enumerator.Inc(),
|
||||
|
||||
dirtyFields: make(map[types.FieldIndex]bool, fieldCount),
|
||||
dirtyIndices: make(map[types.FieldIndex][]uint64, fieldCount),
|
||||
stateFieldLeaves: make(map[types.FieldIndex]*fieldtrie.FieldTrie, fieldCount),
|
||||
rebuildTrie: make(map[types.FieldIndex]bool, fieldCount),
|
||||
valMapHandler: stateutil.NewValMapHandler(st.Validators),
|
||||
}
|
||||
|
||||
if features.Get().EnableExperimentalState {
|
||||
b.blockRootsMultiValue = NewMultiValueBlockRoots(st.BlockRoots)
|
||||
b.stateRootsMultiValue = NewMultiValueStateRoots(st.StateRoots)
|
||||
b.randaoMixesMultiValue = NewMultiValueRandaoMixes(st.RandaoMixes)
|
||||
b.balancesMultiValue = NewMultiValueBalances(st.Balances)
|
||||
b.validatorsMultiValue = NewMultiValueValidators(st.Validators)
|
||||
b.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, experimentalStatePhase0SharedFieldRefCount)
|
||||
} else {
|
||||
bRoots := make([][32]byte, fieldparams.BlockRootsLength)
|
||||
for i, r := range st.BlockRoots {
|
||||
bRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
b.blockRoots = bRoots
|
||||
|
||||
sRoots := make([][32]byte, fieldparams.StateRootsLength)
|
||||
for i, r := range st.StateRoots {
|
||||
sRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
b.stateRoots = sRoots
|
||||
|
||||
mixes := make([][32]byte, fieldparams.RandaoMixesLength)
|
||||
for i, m := range st.RandaoMixes {
|
||||
mixes[i] = bytesutil.ToBytes32(m)
|
||||
}
|
||||
b.randaoMixes = mixes
|
||||
|
||||
b.balances = st.Balances
|
||||
b.validators = st.Validators
|
||||
|
||||
b.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, phase0SharedFieldRefCount)
|
||||
}
|
||||
|
||||
for _, f := range phase0Fields {
|
||||
@@ -193,16 +215,18 @@ func InitializeFromProtoUnsafePhase0(st *ethpb.BeaconState) (state.BeaconState,
|
||||
}
|
||||
|
||||
// Initialize field reference tracking for shared data.
|
||||
b.sharedFieldReferences[types.BlockRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.StateRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.HistoricalRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Eth1DataVotes] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Validators] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Balances] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.RandaoMixes] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Slashings] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.PreviousEpochAttestations] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.CurrentEpochAttestations] = stateutil.NewRef(1)
|
||||
if !features.Get().EnableExperimentalState {
|
||||
b.sharedFieldReferences[types.BlockRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.StateRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.RandaoMixes] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Balances] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Validators] = stateutil.NewRef(1)
|
||||
}
|
||||
|
||||
state.StateCount.Inc()
|
||||
// Finalizer runs when dst is being destroyed in garbage collection.
|
||||
@@ -217,22 +241,10 @@ func InitializeFromProtoUnsafeAltair(st *ethpb.BeaconStateAltair) (state.BeaconS
|
||||
return nil, errors.New("received nil state")
|
||||
}
|
||||
|
||||
var bRoots customtypes.BlockRoots
|
||||
for i, r := range st.BlockRoots {
|
||||
bRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
var sRoots customtypes.StateRoots
|
||||
for i, r := range st.StateRoots {
|
||||
sRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
hRoots := customtypes.HistoricalRoots(make([][32]byte, len(st.HistoricalRoots)))
|
||||
for i, r := range st.HistoricalRoots {
|
||||
hRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
var mixes customtypes.RandaoMixes
|
||||
for i, m := range st.RandaoMixes {
|
||||
mixes[i] = bytesutil.ToBytes32(m)
|
||||
}
|
||||
|
||||
fieldCount := params.BeaconConfig().BeaconStateAltairFieldCount
|
||||
b := &BeaconState{
|
||||
@@ -242,15 +254,10 @@ func InitializeFromProtoUnsafeAltair(st *ethpb.BeaconStateAltair) (state.BeaconS
|
||||
slot: st.Slot,
|
||||
fork: st.Fork,
|
||||
latestBlockHeader: st.LatestBlockHeader,
|
||||
blockRoots: &bRoots,
|
||||
stateRoots: &sRoots,
|
||||
historicalRoots: hRoots,
|
||||
eth1Data: st.Eth1Data,
|
||||
eth1DataVotes: st.Eth1DataVotes,
|
||||
eth1DepositIndex: st.Eth1DepositIndex,
|
||||
validators: st.Validators,
|
||||
balances: st.Balances,
|
||||
randaoMixes: &mixes,
|
||||
slashings: st.Slashings,
|
||||
previousEpochParticipation: st.PreviousEpochParticipation,
|
||||
currentEpochParticipation: st.CurrentEpochParticipation,
|
||||
@@ -258,16 +265,50 @@ func InitializeFromProtoUnsafeAltair(st *ethpb.BeaconStateAltair) (state.BeaconS
|
||||
previousJustifiedCheckpoint: st.PreviousJustifiedCheckpoint,
|
||||
currentJustifiedCheckpoint: st.CurrentJustifiedCheckpoint,
|
||||
finalizedCheckpoint: st.FinalizedCheckpoint,
|
||||
inactivityScores: st.InactivityScores,
|
||||
currentSyncCommittee: st.CurrentSyncCommittee,
|
||||
nextSyncCommittee: st.NextSyncCommittee,
|
||||
|
||||
dirtyFields: make(map[types.FieldIndex]bool, fieldCount),
|
||||
dirtyIndices: make(map[types.FieldIndex][]uint64, fieldCount),
|
||||
stateFieldLeaves: make(map[types.FieldIndex]*fieldtrie.FieldTrie, fieldCount),
|
||||
sharedFieldReferences: make(map[types.FieldIndex]*stateutil.Reference, altairSharedFieldRefCount),
|
||||
rebuildTrie: make(map[types.FieldIndex]bool, fieldCount),
|
||||
valMapHandler: stateutil.NewValMapHandler(st.Validators),
|
||||
id: types.Enumerator.Inc(),
|
||||
|
||||
dirtyFields: make(map[types.FieldIndex]bool, fieldCount),
|
||||
dirtyIndices: make(map[types.FieldIndex][]uint64, fieldCount),
|
||||
stateFieldLeaves: make(map[types.FieldIndex]*fieldtrie.FieldTrie, fieldCount),
|
||||
rebuildTrie: make(map[types.FieldIndex]bool, fieldCount),
|
||||
valMapHandler: stateutil.NewValMapHandler(st.Validators),
|
||||
}
|
||||
|
||||
if features.Get().EnableExperimentalState {
|
||||
b.blockRootsMultiValue = NewMultiValueBlockRoots(st.BlockRoots)
|
||||
b.stateRootsMultiValue = NewMultiValueStateRoots(st.StateRoots)
|
||||
b.randaoMixesMultiValue = NewMultiValueRandaoMixes(st.RandaoMixes)
|
||||
b.balancesMultiValue = NewMultiValueBalances(st.Balances)
|
||||
b.validatorsMultiValue = NewMultiValueValidators(st.Validators)
|
||||
b.inactivityScoresMultiValue = NewMultiValueInactivityScores(st.InactivityScores)
|
||||
b.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, experimentalStateAltairSharedFieldRefCount)
|
||||
} else {
|
||||
bRoots := make([][32]byte, fieldparams.BlockRootsLength)
|
||||
for i, r := range st.BlockRoots {
|
||||
bRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
b.blockRoots = bRoots
|
||||
|
||||
sRoots := make([][32]byte, fieldparams.StateRootsLength)
|
||||
for i, r := range st.StateRoots {
|
||||
sRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
b.stateRoots = sRoots
|
||||
|
||||
mixes := make([][32]byte, fieldparams.RandaoMixesLength)
|
||||
for i, m := range st.RandaoMixes {
|
||||
mixes[i] = bytesutil.ToBytes32(m)
|
||||
}
|
||||
b.randaoMixes = mixes
|
||||
|
||||
b.balances = st.Balances
|
||||
b.validators = st.Validators
|
||||
b.inactivityScores = st.InactivityScores
|
||||
|
||||
b.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, altairSharedFieldRefCount)
|
||||
}
|
||||
|
||||
for _, f := range altairFields {
|
||||
@@ -282,17 +323,19 @@ func InitializeFromProtoUnsafeAltair(st *ethpb.BeaconStateAltair) (state.BeaconS
|
||||
}
|
||||
|
||||
// Initialize field reference tracking for shared data.
|
||||
b.sharedFieldReferences[types.BlockRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.StateRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.HistoricalRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Eth1DataVotes] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Validators] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Balances] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.RandaoMixes] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Slashings] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.PreviousEpochParticipationBits] = stateutil.NewRef(1) // New in Altair.
|
||||
b.sharedFieldReferences[types.CurrentEpochParticipationBits] = stateutil.NewRef(1) // New in Altair.
|
||||
b.sharedFieldReferences[types.InactivityScores] = stateutil.NewRef(1) // New in Altair.
|
||||
if !features.Get().EnableExperimentalState {
|
||||
b.sharedFieldReferences[types.BlockRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.StateRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.RandaoMixes] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Balances] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Validators] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.InactivityScores] = stateutil.NewRef(1)
|
||||
}
|
||||
|
||||
state.StateCount.Inc()
|
||||
// Finalizer runs when dst is being destroyed in garbage collection.
|
||||
@@ -307,22 +350,10 @@ func InitializeFromProtoUnsafeBellatrix(st *ethpb.BeaconStateBellatrix) (state.B
|
||||
return nil, errors.New("received nil state")
|
||||
}
|
||||
|
||||
var bRoots customtypes.BlockRoots
|
||||
for i, r := range st.BlockRoots {
|
||||
bRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
var sRoots customtypes.StateRoots
|
||||
for i, r := range st.StateRoots {
|
||||
sRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
hRoots := customtypes.HistoricalRoots(make([][32]byte, len(st.HistoricalRoots)))
|
||||
for i, r := range st.HistoricalRoots {
|
||||
hRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
var mixes customtypes.RandaoMixes
|
||||
for i, m := range st.RandaoMixes {
|
||||
mixes[i] = bytesutil.ToBytes32(m)
|
||||
}
|
||||
|
||||
fieldCount := params.BeaconConfig().BeaconStateBellatrixFieldCount
|
||||
b := &BeaconState{
|
||||
@@ -332,15 +363,10 @@ func InitializeFromProtoUnsafeBellatrix(st *ethpb.BeaconStateBellatrix) (state.B
|
||||
slot: st.Slot,
|
||||
fork: st.Fork,
|
||||
latestBlockHeader: st.LatestBlockHeader,
|
||||
blockRoots: &bRoots,
|
||||
stateRoots: &sRoots,
|
||||
historicalRoots: hRoots,
|
||||
eth1Data: st.Eth1Data,
|
||||
eth1DataVotes: st.Eth1DataVotes,
|
||||
eth1DepositIndex: st.Eth1DepositIndex,
|
||||
validators: st.Validators,
|
||||
balances: st.Balances,
|
||||
randaoMixes: &mixes,
|
||||
slashings: st.Slashings,
|
||||
previousEpochParticipation: st.PreviousEpochParticipation,
|
||||
currentEpochParticipation: st.CurrentEpochParticipation,
|
||||
@@ -348,17 +374,51 @@ func InitializeFromProtoUnsafeBellatrix(st *ethpb.BeaconStateBellatrix) (state.B
|
||||
previousJustifiedCheckpoint: st.PreviousJustifiedCheckpoint,
|
||||
currentJustifiedCheckpoint: st.CurrentJustifiedCheckpoint,
|
||||
finalizedCheckpoint: st.FinalizedCheckpoint,
|
||||
inactivityScores: st.InactivityScores,
|
||||
currentSyncCommittee: st.CurrentSyncCommittee,
|
||||
nextSyncCommittee: st.NextSyncCommittee,
|
||||
latestExecutionPayloadHeader: st.LatestExecutionPayloadHeader,
|
||||
|
||||
dirtyFields: make(map[types.FieldIndex]bool, fieldCount),
|
||||
dirtyIndices: make(map[types.FieldIndex][]uint64, fieldCount),
|
||||
stateFieldLeaves: make(map[types.FieldIndex]*fieldtrie.FieldTrie, fieldCount),
|
||||
sharedFieldReferences: make(map[types.FieldIndex]*stateutil.Reference, bellatrixSharedFieldRefCount),
|
||||
rebuildTrie: make(map[types.FieldIndex]bool, fieldCount),
|
||||
valMapHandler: stateutil.NewValMapHandler(st.Validators),
|
||||
id: types.Enumerator.Inc(),
|
||||
|
||||
dirtyFields: make(map[types.FieldIndex]bool, fieldCount),
|
||||
dirtyIndices: make(map[types.FieldIndex][]uint64, fieldCount),
|
||||
stateFieldLeaves: make(map[types.FieldIndex]*fieldtrie.FieldTrie, fieldCount),
|
||||
rebuildTrie: make(map[types.FieldIndex]bool, fieldCount),
|
||||
valMapHandler: stateutil.NewValMapHandler(st.Validators),
|
||||
}
|
||||
|
||||
if features.Get().EnableExperimentalState {
|
||||
b.blockRootsMultiValue = NewMultiValueBlockRoots(st.BlockRoots)
|
||||
b.stateRootsMultiValue = NewMultiValueStateRoots(st.StateRoots)
|
||||
b.randaoMixesMultiValue = NewMultiValueRandaoMixes(st.RandaoMixes)
|
||||
b.balancesMultiValue = NewMultiValueBalances(st.Balances)
|
||||
b.validatorsMultiValue = NewMultiValueValidators(st.Validators)
|
||||
b.inactivityScoresMultiValue = NewMultiValueInactivityScores(st.InactivityScores)
|
||||
b.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, experimentalStateBellatrixSharedFieldRefCount)
|
||||
} else {
|
||||
bRoots := make([][32]byte, fieldparams.BlockRootsLength)
|
||||
for i, r := range st.BlockRoots {
|
||||
bRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
b.blockRoots = bRoots
|
||||
|
||||
sRoots := make([][32]byte, fieldparams.StateRootsLength)
|
||||
for i, r := range st.StateRoots {
|
||||
sRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
b.stateRoots = sRoots
|
||||
|
||||
mixes := make([][32]byte, fieldparams.RandaoMixesLength)
|
||||
for i, m := range st.RandaoMixes {
|
||||
mixes[i] = bytesutil.ToBytes32(m)
|
||||
}
|
||||
b.randaoMixes = mixes
|
||||
|
||||
b.balances = st.Balances
|
||||
b.validators = st.Validators
|
||||
b.inactivityScores = st.InactivityScores
|
||||
|
||||
b.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, bellatrixSharedFieldRefCount)
|
||||
}
|
||||
|
||||
for _, f := range bellatrixFields {
|
||||
@@ -373,18 +433,20 @@ func InitializeFromProtoUnsafeBellatrix(st *ethpb.BeaconStateBellatrix) (state.B
|
||||
}
|
||||
|
||||
// Initialize field reference tracking for shared data.
|
||||
b.sharedFieldReferences[types.BlockRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.StateRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.HistoricalRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Eth1DataVotes] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Validators] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Balances] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.RandaoMixes] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Slashings] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.PreviousEpochParticipationBits] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.CurrentEpochParticipationBits] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.InactivityScores] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.LatestExecutionPayloadHeader] = stateutil.NewRef(1) // New in Bellatrix.
|
||||
if !features.Get().EnableExperimentalState {
|
||||
b.sharedFieldReferences[types.BlockRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.StateRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.RandaoMixes] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Balances] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Validators] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.InactivityScores] = stateutil.NewRef(1)
|
||||
}
|
||||
|
||||
state.StateCount.Inc()
|
||||
// Finalizer runs when dst is being destroyed in garbage collection.
|
||||
@@ -399,22 +461,10 @@ func InitializeFromProtoUnsafeCapella(st *ethpb.BeaconStateCapella) (state.Beaco
|
||||
return nil, errors.New("received nil state")
|
||||
}
|
||||
|
||||
var bRoots customtypes.BlockRoots
|
||||
for i, r := range st.BlockRoots {
|
||||
bRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
var sRoots customtypes.StateRoots
|
||||
for i, r := range st.StateRoots {
|
||||
sRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
hRoots := customtypes.HistoricalRoots(make([][32]byte, len(st.HistoricalRoots)))
|
||||
for i, r := range st.HistoricalRoots {
|
||||
hRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
var mixes customtypes.RandaoMixes
|
||||
for i, m := range st.RandaoMixes {
|
||||
mixes[i] = bytesutil.ToBytes32(m)
|
||||
}
|
||||
|
||||
fieldCount := params.BeaconConfig().BeaconStateCapellaFieldCount
|
||||
b := &BeaconState{
|
||||
@@ -424,15 +474,10 @@ func InitializeFromProtoUnsafeCapella(st *ethpb.BeaconStateCapella) (state.Beaco
|
||||
slot: st.Slot,
|
||||
fork: st.Fork,
|
||||
latestBlockHeader: st.LatestBlockHeader,
|
||||
blockRoots: &bRoots,
|
||||
stateRoots: &sRoots,
|
||||
historicalRoots: hRoots,
|
||||
eth1Data: st.Eth1Data,
|
||||
eth1DataVotes: st.Eth1DataVotes,
|
||||
eth1DepositIndex: st.Eth1DepositIndex,
|
||||
validators: st.Validators,
|
||||
balances: st.Balances,
|
||||
randaoMixes: &mixes,
|
||||
slashings: st.Slashings,
|
||||
previousEpochParticipation: st.PreviousEpochParticipation,
|
||||
currentEpochParticipation: st.CurrentEpochParticipation,
|
||||
@@ -440,7 +485,6 @@ func InitializeFromProtoUnsafeCapella(st *ethpb.BeaconStateCapella) (state.Beaco
|
||||
previousJustifiedCheckpoint: st.PreviousJustifiedCheckpoint,
|
||||
currentJustifiedCheckpoint: st.CurrentJustifiedCheckpoint,
|
||||
finalizedCheckpoint: st.FinalizedCheckpoint,
|
||||
inactivityScores: st.InactivityScores,
|
||||
currentSyncCommittee: st.CurrentSyncCommittee,
|
||||
nextSyncCommittee: st.NextSyncCommittee,
|
||||
latestExecutionPayloadHeaderCapella: st.LatestExecutionPayloadHeader,
|
||||
@@ -448,12 +492,47 @@ func InitializeFromProtoUnsafeCapella(st *ethpb.BeaconStateCapella) (state.Beaco
|
||||
nextWithdrawalValidatorIndex: st.NextWithdrawalValidatorIndex,
|
||||
historicalSummaries: st.HistoricalSummaries,
|
||||
|
||||
dirtyFields: make(map[types.FieldIndex]bool, fieldCount),
|
||||
dirtyIndices: make(map[types.FieldIndex][]uint64, fieldCount),
|
||||
stateFieldLeaves: make(map[types.FieldIndex]*fieldtrie.FieldTrie, fieldCount),
|
||||
sharedFieldReferences: make(map[types.FieldIndex]*stateutil.Reference, capellaSharedFieldRefCount),
|
||||
rebuildTrie: make(map[types.FieldIndex]bool, fieldCount),
|
||||
valMapHandler: stateutil.NewValMapHandler(st.Validators),
|
||||
id: types.Enumerator.Inc(),
|
||||
|
||||
dirtyFields: make(map[types.FieldIndex]bool, fieldCount),
|
||||
dirtyIndices: make(map[types.FieldIndex][]uint64, fieldCount),
|
||||
stateFieldLeaves: make(map[types.FieldIndex]*fieldtrie.FieldTrie, fieldCount),
|
||||
rebuildTrie: make(map[types.FieldIndex]bool, fieldCount),
|
||||
valMapHandler: stateutil.NewValMapHandler(st.Validators),
|
||||
}
|
||||
|
||||
if features.Get().EnableExperimentalState {
|
||||
b.blockRootsMultiValue = NewMultiValueBlockRoots(st.BlockRoots)
|
||||
b.stateRootsMultiValue = NewMultiValueStateRoots(st.StateRoots)
|
||||
b.randaoMixesMultiValue = NewMultiValueRandaoMixes(st.RandaoMixes)
|
||||
b.balancesMultiValue = NewMultiValueBalances(st.Balances)
|
||||
b.validatorsMultiValue = NewMultiValueValidators(st.Validators)
|
||||
b.inactivityScoresMultiValue = NewMultiValueInactivityScores(st.InactivityScores)
|
||||
b.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, experimentalStateCapellaSharedFieldRefCount)
|
||||
} else {
|
||||
bRoots := make([][32]byte, fieldparams.BlockRootsLength)
|
||||
for i, r := range st.BlockRoots {
|
||||
bRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
b.blockRoots = bRoots
|
||||
|
||||
sRoots := make([][32]byte, fieldparams.StateRootsLength)
|
||||
for i, r := range st.StateRoots {
|
||||
sRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
b.stateRoots = sRoots
|
||||
|
||||
mixes := make([][32]byte, fieldparams.RandaoMixesLength)
|
||||
for i, m := range st.RandaoMixes {
|
||||
mixes[i] = bytesutil.ToBytes32(m)
|
||||
}
|
||||
b.randaoMixes = mixes
|
||||
|
||||
b.balances = st.Balances
|
||||
b.validators = st.Validators
|
||||
b.inactivityScores = st.InactivityScores
|
||||
|
||||
b.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, capellaSharedFieldRefCount)
|
||||
}
|
||||
|
||||
for _, f := range capellaFields {
|
||||
@@ -468,19 +547,21 @@ func InitializeFromProtoUnsafeCapella(st *ethpb.BeaconStateCapella) (state.Beaco
|
||||
}
|
||||
|
||||
// Initialize field reference tracking for shared data.
|
||||
b.sharedFieldReferences[types.BlockRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.StateRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.HistoricalRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Eth1DataVotes] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Validators] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Balances] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.RandaoMixes] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Slashings] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.PreviousEpochParticipationBits] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.CurrentEpochParticipationBits] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.InactivityScores] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.LatestExecutionPayloadHeaderCapella] = stateutil.NewRef(1) // New in Capella.
|
||||
b.sharedFieldReferences[types.HistoricalSummaries] = stateutil.NewRef(1) // New in Capella.
|
||||
if !features.Get().EnableExperimentalState {
|
||||
b.sharedFieldReferences[types.BlockRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.StateRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.RandaoMixes] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Balances] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Validators] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.InactivityScores] = stateutil.NewRef(1)
|
||||
}
|
||||
|
||||
state.StateCount.Inc()
|
||||
// Finalizer runs when dst is being destroyed in garbage collection.
|
||||
@@ -495,22 +576,10 @@ func InitializeFromProtoUnsafeDeneb(st *ethpb.BeaconStateDeneb) (state.BeaconSta
|
||||
return nil, errors.New("received nil state")
|
||||
}
|
||||
|
||||
var bRoots customtypes.BlockRoots
|
||||
for i, r := range st.BlockRoots {
|
||||
bRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
var sRoots customtypes.StateRoots
|
||||
for i, r := range st.StateRoots {
|
||||
sRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
hRoots := customtypes.HistoricalRoots(make([][32]byte, len(st.HistoricalRoots)))
|
||||
for i, r := range st.HistoricalRoots {
|
||||
hRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
var mixes customtypes.RandaoMixes
|
||||
for i, m := range st.RandaoMixes {
|
||||
mixes[i] = bytesutil.ToBytes32(m)
|
||||
}
|
||||
|
||||
fieldCount := params.BeaconConfig().BeaconStateDenebFieldCount
|
||||
b := &BeaconState{
|
||||
@@ -520,15 +589,10 @@ func InitializeFromProtoUnsafeDeneb(st *ethpb.BeaconStateDeneb) (state.BeaconSta
|
||||
slot: st.Slot,
|
||||
fork: st.Fork,
|
||||
latestBlockHeader: st.LatestBlockHeader,
|
||||
blockRoots: &bRoots,
|
||||
stateRoots: &sRoots,
|
||||
historicalRoots: hRoots,
|
||||
eth1Data: st.Eth1Data,
|
||||
eth1DataVotes: st.Eth1DataVotes,
|
||||
eth1DepositIndex: st.Eth1DepositIndex,
|
||||
validators: st.Validators,
|
||||
balances: st.Balances,
|
||||
randaoMixes: &mixes,
|
||||
slashings: st.Slashings,
|
||||
previousEpochParticipation: st.PreviousEpochParticipation,
|
||||
currentEpochParticipation: st.CurrentEpochParticipation,
|
||||
@@ -536,7 +600,6 @@ func InitializeFromProtoUnsafeDeneb(st *ethpb.BeaconStateDeneb) (state.BeaconSta
|
||||
previousJustifiedCheckpoint: st.PreviousJustifiedCheckpoint,
|
||||
currentJustifiedCheckpoint: st.CurrentJustifiedCheckpoint,
|
||||
finalizedCheckpoint: st.FinalizedCheckpoint,
|
||||
inactivityScores: st.InactivityScores,
|
||||
currentSyncCommittee: st.CurrentSyncCommittee,
|
||||
nextSyncCommittee: st.NextSyncCommittee,
|
||||
latestExecutionPayloadHeaderDeneb: st.LatestExecutionPayloadHeader,
|
||||
@@ -544,12 +607,45 @@ func InitializeFromProtoUnsafeDeneb(st *ethpb.BeaconStateDeneb) (state.BeaconSta
|
||||
nextWithdrawalValidatorIndex: st.NextWithdrawalValidatorIndex,
|
||||
historicalSummaries: st.HistoricalSummaries,
|
||||
|
||||
dirtyFields: make(map[types.FieldIndex]bool, fieldCount),
|
||||
dirtyIndices: make(map[types.FieldIndex][]uint64, fieldCount),
|
||||
stateFieldLeaves: make(map[types.FieldIndex]*fieldtrie.FieldTrie, fieldCount),
|
||||
sharedFieldReferences: make(map[types.FieldIndex]*stateutil.Reference, capellaSharedFieldRefCount),
|
||||
rebuildTrie: make(map[types.FieldIndex]bool, fieldCount),
|
||||
valMapHandler: stateutil.NewValMapHandler(st.Validators),
|
||||
dirtyFields: make(map[types.FieldIndex]bool, fieldCount),
|
||||
dirtyIndices: make(map[types.FieldIndex][]uint64, fieldCount),
|
||||
stateFieldLeaves: make(map[types.FieldIndex]*fieldtrie.FieldTrie, fieldCount),
|
||||
rebuildTrie: make(map[types.FieldIndex]bool, fieldCount),
|
||||
valMapHandler: stateutil.NewValMapHandler(st.Validators),
|
||||
}
|
||||
|
||||
if features.Get().EnableExperimentalState {
|
||||
b.blockRootsMultiValue = NewMultiValueBlockRoots(st.BlockRoots)
|
||||
b.stateRootsMultiValue = NewMultiValueStateRoots(st.StateRoots)
|
||||
b.randaoMixesMultiValue = NewMultiValueRandaoMixes(st.RandaoMixes)
|
||||
b.balancesMultiValue = NewMultiValueBalances(st.Balances)
|
||||
b.validatorsMultiValue = NewMultiValueValidators(st.Validators)
|
||||
b.inactivityScoresMultiValue = NewMultiValueInactivityScores(st.InactivityScores)
|
||||
b.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, experimentalStateDenebSharedFieldRefCount)
|
||||
} else {
|
||||
bRoots := make([][32]byte, fieldparams.BlockRootsLength)
|
||||
for i, r := range st.BlockRoots {
|
||||
bRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
b.blockRoots = bRoots
|
||||
|
||||
sRoots := make([][32]byte, fieldparams.StateRootsLength)
|
||||
for i, r := range st.StateRoots {
|
||||
sRoots[i] = bytesutil.ToBytes32(r)
|
||||
}
|
||||
b.stateRoots = sRoots
|
||||
|
||||
mixes := make([][32]byte, fieldparams.RandaoMixesLength)
|
||||
for i, m := range st.RandaoMixes {
|
||||
mixes[i] = bytesutil.ToBytes32(m)
|
||||
}
|
||||
b.randaoMixes = mixes
|
||||
|
||||
b.balances = st.Balances
|
||||
b.validators = st.Validators
|
||||
b.inactivityScores = st.InactivityScores
|
||||
|
||||
b.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, denebSharedFieldRefCount)
|
||||
}
|
||||
|
||||
for _, f := range denebFields {
|
||||
@@ -564,19 +660,21 @@ func InitializeFromProtoUnsafeDeneb(st *ethpb.BeaconStateDeneb) (state.BeaconSta
|
||||
}
|
||||
|
||||
// Initialize field reference tracking for shared data.
|
||||
b.sharedFieldReferences[types.BlockRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.StateRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.HistoricalRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Eth1DataVotes] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Validators] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Balances] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.RandaoMixes] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Slashings] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.PreviousEpochParticipationBits] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.CurrentEpochParticipationBits] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.InactivityScores] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.LatestExecutionPayloadHeaderDeneb] = stateutil.NewRef(1) // New in Deneb.
|
||||
b.sharedFieldReferences[types.HistoricalSummaries] = stateutil.NewRef(1) // New in Capella.
|
||||
if !features.Get().EnableExperimentalState {
|
||||
b.sharedFieldReferences[types.BlockRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.StateRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.RandaoMixes] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Balances] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.Validators] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[types.InactivityScores] = stateutil.NewRef(1)
|
||||
}
|
||||
|
||||
state.StateCount.Inc()
|
||||
// Finalizer runs when dst is being destroyed in garbage collection.
|
||||
@@ -615,8 +713,11 @@ func (b *BeaconState) Copy() state.BeaconState {
|
||||
|
||||
// Large arrays, infrequently changed, constant size.
|
||||
blockRoots: b.blockRoots,
|
||||
blockRootsMultiValue: b.blockRootsMultiValue,
|
||||
stateRoots: b.stateRoots,
|
||||
stateRootsMultiValue: b.stateRootsMultiValue,
|
||||
randaoMixes: b.randaoMixes,
|
||||
randaoMixesMultiValue: b.randaoMixesMultiValue,
|
||||
previousEpochAttestations: b.previousEpochAttestations,
|
||||
currentEpochAttestations: b.currentEpochAttestations,
|
||||
eth1DataVotes: b.eth1DataVotes,
|
||||
@@ -624,12 +725,15 @@ func (b *BeaconState) Copy() state.BeaconState {
|
||||
|
||||
// Large arrays, increases over time.
|
||||
balances: b.balances,
|
||||
balancesMultiValue: b.balancesMultiValue,
|
||||
historicalRoots: b.historicalRoots,
|
||||
historicalSummaries: b.historicalSummaries,
|
||||
validators: b.validators,
|
||||
validatorsMultiValue: b.validatorsMultiValue,
|
||||
previousEpochParticipation: b.previousEpochParticipation,
|
||||
currentEpochParticipation: b.currentEpochParticipation,
|
||||
inactivityScores: b.inactivityScores,
|
||||
inactivityScoresMultiValue: b.inactivityScoresMultiValue,
|
||||
|
||||
// Everything else, too small to be concerned about, constant size.
|
||||
genesisValidatorsRoot: b.genesisValidatorsRoot,
|
||||
@@ -646,6 +750,8 @@ func (b *BeaconState) Copy() state.BeaconState {
|
||||
latestExecutionPayloadHeaderCapella: b.latestExecutionPayloadHeaderCapellaVal(),
|
||||
latestExecutionPayloadHeaderDeneb: b.latestExecutionPayloadHeaderDenebVal(),
|
||||
|
||||
id: types.Enumerator.Inc(),
|
||||
|
||||
dirtyFields: make(map[types.FieldIndex]bool, fieldCount),
|
||||
dirtyIndices: make(map[types.FieldIndex][]uint64, fieldCount),
|
||||
rebuildTrie: make(map[types.FieldIndex]bool, fieldCount),
|
||||
@@ -655,17 +761,43 @@ func (b *BeaconState) Copy() state.BeaconState {
|
||||
valMapHandler: b.valMapHandler,
|
||||
}
|
||||
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
dst.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, phase0SharedFieldRefCount)
|
||||
case version.Altair:
|
||||
dst.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, altairSharedFieldRefCount)
|
||||
case version.Bellatrix:
|
||||
dst.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, bellatrixSharedFieldRefCount)
|
||||
case version.Capella:
|
||||
dst.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, capellaSharedFieldRefCount)
|
||||
case version.Deneb:
|
||||
dst.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, denebSharedFieldRefCount)
|
||||
if features.Get().EnableExperimentalState {
|
||||
b.blockRootsMultiValue.Copy(b, dst)
|
||||
b.stateRootsMultiValue.Copy(b, dst)
|
||||
b.randaoMixesMultiValue.Copy(b, dst)
|
||||
b.balancesMultiValue.Copy(b, dst)
|
||||
if b.version > version.Phase0 {
|
||||
b.inactivityScoresMultiValue.Copy(b, dst)
|
||||
}
|
||||
b.validatorsMultiValue.Copy(b, dst)
|
||||
}
|
||||
|
||||
if features.Get().EnableExperimentalState {
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
dst.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, experimentalStatePhase0SharedFieldRefCount)
|
||||
case version.Altair:
|
||||
dst.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, experimentalStateAltairSharedFieldRefCount)
|
||||
case version.Bellatrix:
|
||||
dst.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, experimentalStateBellatrixSharedFieldRefCount)
|
||||
case version.Capella:
|
||||
dst.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, experimentalStateCapellaSharedFieldRefCount)
|
||||
case version.Deneb:
|
||||
dst.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, experimentalStateDenebSharedFieldRefCount)
|
||||
}
|
||||
} else {
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
dst.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, phase0SharedFieldRefCount)
|
||||
case version.Altair:
|
||||
dst.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, altairSharedFieldRefCount)
|
||||
case version.Bellatrix:
|
||||
dst.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, bellatrixSharedFieldRefCount)
|
||||
case version.Capella:
|
||||
dst.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, capellaSharedFieldRefCount)
|
||||
case version.Deneb:
|
||||
dst.sharedFieldReferences = make(map[types.FieldIndex]*stateutil.Reference, denebSharedFieldRefCount)
|
||||
}
|
||||
}
|
||||
|
||||
for field, ref := range b.sharedFieldReferences {
|
||||
@@ -824,25 +956,9 @@ func (b *BeaconState) rootSelector(ctx context.Context, field types.FieldIndex)
|
||||
case types.LatestBlockHeader:
|
||||
return stateutil.BlockHeaderRoot(b.latestBlockHeader)
|
||||
case types.BlockRoots:
|
||||
if b.rebuildTrie[field] {
|
||||
err := b.resetFieldTrie(field, b.blockRoots, fieldparams.BlockRootsLength)
|
||||
if err != nil {
|
||||
return [32]byte{}, err
|
||||
}
|
||||
delete(b.rebuildTrie, field)
|
||||
return b.stateFieldLeaves[field].TrieRoot()
|
||||
}
|
||||
return b.recomputeFieldTrie(field, b.blockRoots)
|
||||
return b.blockRootsRootSelector(field)
|
||||
case types.StateRoots:
|
||||
if b.rebuildTrie[field] {
|
||||
err := b.resetFieldTrie(field, b.stateRoots, fieldparams.StateRootsLength)
|
||||
if err != nil {
|
||||
return [32]byte{}, err
|
||||
}
|
||||
delete(b.rebuildTrie, field)
|
||||
return b.stateFieldLeaves[field].TrieRoot()
|
||||
}
|
||||
return b.recomputeFieldTrie(field, b.stateRoots)
|
||||
return b.stateRootsRootSelector(field)
|
||||
case types.HistoricalRoots:
|
||||
hRoots := make([][]byte, len(b.historicalRoots))
|
||||
for i := range hRoots {
|
||||
@@ -866,35 +982,11 @@ func (b *BeaconState) rootSelector(ctx context.Context, field types.FieldIndex)
|
||||
}
|
||||
return b.recomputeFieldTrie(field, b.eth1DataVotes)
|
||||
case types.Validators:
|
||||
if b.rebuildTrie[field] {
|
||||
err := b.resetFieldTrie(field, b.validators, fieldparams.ValidatorRegistryLimit)
|
||||
if err != nil {
|
||||
return [32]byte{}, err
|
||||
}
|
||||
delete(b.rebuildTrie, field)
|
||||
return b.stateFieldLeaves[field].TrieRoot()
|
||||
}
|
||||
return b.recomputeFieldTrie(11, b.validators)
|
||||
return b.validatorsRootSelector(field)
|
||||
case types.Balances:
|
||||
if b.rebuildTrie[field] {
|
||||
err := b.resetFieldTrie(field, b.balances, stateutil.ValidatorLimitForBalancesChunks())
|
||||
if err != nil {
|
||||
return [32]byte{}, err
|
||||
}
|
||||
delete(b.rebuildTrie, field)
|
||||
return b.stateFieldLeaves[field].TrieRoot()
|
||||
}
|
||||
return b.recomputeFieldTrie(12, b.balances)
|
||||
return b.balancesRootSelector(field)
|
||||
case types.RandaoMixes:
|
||||
if b.rebuildTrie[field] {
|
||||
err := b.resetFieldTrie(field, b.randaoMixes, fieldparams.RandaoMixesLength)
|
||||
if err != nil {
|
||||
return [32]byte{}, err
|
||||
}
|
||||
delete(b.rebuildTrie, field)
|
||||
return b.stateFieldLeaves[field].TrieRoot()
|
||||
}
|
||||
return b.recomputeFieldTrie(13, b.randaoMixes)
|
||||
return b.randaoMixesRootSelector(field)
|
||||
case types.Slashings:
|
||||
return ssz.SlashingsRoot(b.slashings)
|
||||
case types.PreviousEpochAttestations:
|
||||
@@ -938,7 +1030,11 @@ func (b *BeaconState) rootSelector(ctx context.Context, field types.FieldIndex)
|
||||
case types.FinalizedCheckpoint:
|
||||
return ssz.CheckpointRoot(b.finalizedCheckpoint)
|
||||
case types.InactivityScores:
|
||||
return stateutil.Uint64ListRootWithRegistryLimit(b.inactivityScores)
|
||||
if features.Get().EnableExperimentalState {
|
||||
return stateutil.Uint64ListRootWithRegistryLimit(b.inactivityScoresMultiValue.Value(b))
|
||||
} else {
|
||||
return stateutil.Uint64ListRootWithRegistryLimit(b.inactivityScores)
|
||||
}
|
||||
case types.CurrentSyncCommittee:
|
||||
return stateutil.SyncCommitteeRoot(b.currentSyncCommittee)
|
||||
case types.NextSyncCommittee:
|
||||
@@ -1054,5 +1150,142 @@ func finalizerCleanup(b *BeaconState) {
|
||||
for i := range b.stateFieldLeaves {
|
||||
delete(b.stateFieldLeaves, i)
|
||||
}
|
||||
|
||||
if features.Get().EnableExperimentalState {
|
||||
if b.blockRootsMultiValue != nil {
|
||||
b.blockRootsMultiValue.Detach(b)
|
||||
}
|
||||
if b.stateRootsMultiValue != nil {
|
||||
b.stateRootsMultiValue.Detach(b)
|
||||
}
|
||||
if b.randaoMixesMultiValue != nil {
|
||||
b.randaoMixesMultiValue.Detach(b)
|
||||
}
|
||||
if b.balancesMultiValue != nil {
|
||||
b.balancesMultiValue.Detach(b)
|
||||
}
|
||||
if b.inactivityScoresMultiValue != nil {
|
||||
b.inactivityScoresMultiValue.Detach(b)
|
||||
}
|
||||
if b.validatorsMultiValue != nil {
|
||||
b.validatorsMultiValue.Detach(b)
|
||||
}
|
||||
}
|
||||
|
||||
state.StateCount.Sub(1)
|
||||
}
|
||||
|
||||
func (b *BeaconState) blockRootsRootSelector(field types.FieldIndex) ([32]byte, error) {
|
||||
if b.rebuildTrie[field] {
|
||||
if features.Get().EnableExperimentalState {
|
||||
err := b.resetFieldTrie(field, customtypes.BlockRoots(b.blockRootsMultiValue.Value(b)), fieldparams.BlockRootsLength)
|
||||
if err != nil {
|
||||
return [32]byte{}, err
|
||||
}
|
||||
} else {
|
||||
err := b.resetFieldTrie(field, b.blockRoots, fieldparams.BlockRootsLength)
|
||||
if err != nil {
|
||||
return [32]byte{}, err
|
||||
}
|
||||
}
|
||||
delete(b.rebuildTrie, field)
|
||||
return b.stateFieldLeaves[field].TrieRoot()
|
||||
}
|
||||
if features.Get().EnableExperimentalState {
|
||||
return b.recomputeFieldTrie(field, customtypes.BlockRoots(b.blockRootsMultiValue.Value(b)))
|
||||
} else {
|
||||
return b.recomputeFieldTrie(field, b.blockRoots)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BeaconState) stateRootsRootSelector(field types.FieldIndex) ([32]byte, error) {
|
||||
if b.rebuildTrie[field] {
|
||||
if features.Get().EnableExperimentalState {
|
||||
err := b.resetFieldTrie(field, customtypes.StateRoots(b.stateRootsMultiValue.Value(b)), fieldparams.StateRootsLength)
|
||||
if err != nil {
|
||||
return [32]byte{}, err
|
||||
}
|
||||
} else {
|
||||
err := b.resetFieldTrie(field, b.stateRoots, fieldparams.StateRootsLength)
|
||||
if err != nil {
|
||||
return [32]byte{}, err
|
||||
}
|
||||
}
|
||||
delete(b.rebuildTrie, field)
|
||||
return b.stateFieldLeaves[field].TrieRoot()
|
||||
}
|
||||
if features.Get().EnableExperimentalState {
|
||||
return b.recomputeFieldTrie(field, customtypes.StateRoots(b.stateRootsMultiValue.Value(b)))
|
||||
} else {
|
||||
return b.recomputeFieldTrie(field, b.stateRoots)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BeaconState) validatorsRootSelector(field types.FieldIndex) ([32]byte, error) {
|
||||
if b.rebuildTrie[field] {
|
||||
if features.Get().EnableExperimentalState {
|
||||
err := b.resetFieldTrie(field, b.validatorsMultiValue.Value(b), fieldparams.ValidatorRegistryLimit)
|
||||
if err != nil {
|
||||
return [32]byte{}, err
|
||||
}
|
||||
} else {
|
||||
err := b.resetFieldTrie(field, b.validators, fieldparams.ValidatorRegistryLimit)
|
||||
if err != nil {
|
||||
return [32]byte{}, err
|
||||
}
|
||||
}
|
||||
delete(b.rebuildTrie, field)
|
||||
return b.stateFieldLeaves[field].TrieRoot()
|
||||
}
|
||||
if features.Get().EnableExperimentalState {
|
||||
return b.recomputeFieldTrie(field, b.validatorsMultiValue.Value(b))
|
||||
} else {
|
||||
return b.recomputeFieldTrie(field, b.validators)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BeaconState) balancesRootSelector(field types.FieldIndex) ([32]byte, error) {
|
||||
if b.rebuildTrie[field] {
|
||||
if features.Get().EnableExperimentalState {
|
||||
err := b.resetFieldTrie(field, b.balancesMultiValue.Value(b), stateutil.ValidatorLimitForBalancesChunks())
|
||||
if err != nil {
|
||||
return [32]byte{}, err
|
||||
}
|
||||
} else {
|
||||
err := b.resetFieldTrie(field, b.balances, stateutil.ValidatorLimitForBalancesChunks())
|
||||
if err != nil {
|
||||
return [32]byte{}, err
|
||||
}
|
||||
}
|
||||
delete(b.rebuildTrie, field)
|
||||
return b.stateFieldLeaves[field].TrieRoot()
|
||||
}
|
||||
if features.Get().EnableExperimentalState {
|
||||
return b.recomputeFieldTrie(field, b.balancesMultiValue.Value(b))
|
||||
} else {
|
||||
return b.recomputeFieldTrie(field, b.balances)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BeaconState) randaoMixesRootSelector(field types.FieldIndex) ([32]byte, error) {
|
||||
if b.rebuildTrie[field] {
|
||||
if features.Get().EnableExperimentalState {
|
||||
err := b.resetFieldTrie(field, customtypes.RandaoMixes(b.randaoMixesMultiValue.Value(b)), fieldparams.RandaoMixesLength)
|
||||
if err != nil {
|
||||
return [32]byte{}, err
|
||||
}
|
||||
} else {
|
||||
err := b.resetFieldTrie(field, b.randaoMixes, fieldparams.RandaoMixesLength)
|
||||
if err != nil {
|
||||
return [32]byte{}, err
|
||||
}
|
||||
}
|
||||
delete(b.rebuildTrie, field)
|
||||
return b.stateFieldLeaves[field].TrieRoot()
|
||||
}
|
||||
if features.Get().EnableExperimentalState {
|
||||
return b.recomputeFieldTrie(field, customtypes.RandaoMixes(b.randaoMixesMultiValue.Value(b)))
|
||||
} else {
|
||||
return b.recomputeFieldTrie(field, b.randaoMixes)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
// Ensure type BeaconState below implements BeaconState interface.
|
||||
var _ state.BeaconState = (*BeaconState)(nil)
|
||||
|
||||
// initialization for tests
|
||||
func init() {
|
||||
fieldMap = make(map[types.FieldIndex]types.DataType)
|
||||
// Initialize the fixed sized arrays.
|
||||
|
||||
@@ -5,5 +5,8 @@ go_library(
|
||||
srcs = ["types.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/state/state-native/types",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["@com_github_pkg_errors//:go_default_library"],
|
||||
deps = [
|
||||
"//consensus-types:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -2,6 +2,7 @@ package types
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
consensus_types "github.com/prysmaticlabs/prysm/v4/consensus-types"
|
||||
)
|
||||
|
||||
// DataType signifies the data type of the field.
|
||||
@@ -210,3 +211,6 @@ const (
|
||||
NextWithdrawalValidatorIndex
|
||||
HistoricalSummaries
|
||||
)
|
||||
|
||||
// Enumerator keeps track of the number of states created since the node's start.
|
||||
var Enumerator = &consensus_types.ThreadSafeEnumerator{}
|
||||
|
||||
@@ -185,7 +185,7 @@ func TestBeaconState_ImmutabilityWithSharedResources(t *testing.T) {
|
||||
|
||||
// Randao mixes
|
||||
require.DeepEqual(t, a.RandaoMixes(), b.RandaoMixes(), "Test precondition failed, fields are not equal")
|
||||
require.NoError(t, a.UpdateRandaoMixesAtIndex(1, []byte("foo")))
|
||||
require.NoError(t, a.UpdateRandaoMixesAtIndex(1, bytesutil.ToBytes32([]byte("foo"))))
|
||||
if reflect.DeepEqual(a.RandaoMixes(), b.RandaoMixes()) {
|
||||
t.Error("Expect a.RandaoMixes() to be different from b.RandaoMixes()")
|
||||
}
|
||||
|
||||
@@ -30,7 +30,13 @@ func TestMigrateToCold_CanSaveFinalizedInfo(t *testing.T) {
|
||||
require.NoError(t, service.MigrateToCold(ctx, br))
|
||||
|
||||
wanted := &finalizedInfo{state: beaconState, root: br, slot: 1}
|
||||
assert.DeepEqual(t, wanted, service.finalizedInfo, "Incorrect finalized info")
|
||||
assert.DeepEqual(t, wanted.root, service.finalizedInfo.root)
|
||||
assert.Equal(t, wanted.slot, service.finalizedInfo.slot)
|
||||
expectedHTR, err := wanted.state.HashTreeRoot(ctx)
|
||||
require.NoError(t, err)
|
||||
actualHTR, err := service.finalizedInfo.state.HashTreeRoot(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, actualHTR)
|
||||
}
|
||||
|
||||
func TestMigrateToCold_HappyPath(t *testing.T) {
|
||||
|
||||
@@ -34,12 +34,20 @@ func TestMockHistoryStates(t *testing.T) {
|
||||
genesisRoot := hist.slotMap[0]
|
||||
st, err := hist.StateOrError(ctx, genesisRoot)
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, hist.states[genesisRoot], st)
|
||||
expectedHTR, err := hist.states[genesisRoot].HashTreeRoot(ctx)
|
||||
require.NoError(t, err)
|
||||
actualHTR, err := st.HashTreeRoot(ctx)
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, expectedHTR, actualHTR)
|
||||
require.Equal(t, primitives.Slot(0), st.Slot())
|
||||
|
||||
shouldExist, err := hist.StateOrError(ctx, hist.slotMap[middle])
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, hist.states[hist.slotMap[middle]], shouldExist)
|
||||
expectedHTR, err = hist.states[hist.slotMap[middle]].HashTreeRoot(ctx)
|
||||
require.NoError(t, err)
|
||||
actualHTR, err = shouldExist.HashTreeRoot(ctx)
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, expectedHTR, actualHTR)
|
||||
require.Equal(t, middle, shouldExist.Slot())
|
||||
|
||||
cantExist, err := hist.StateOrError(ctx, hist.slotMap[end])
|
||||
|
||||
@@ -37,6 +37,7 @@ const disabledFeatureFlag = "Disabled feature flag"
|
||||
// Flags is a struct to represent which features the client will perform on runtime.
|
||||
type Flags struct {
|
||||
// Feature related flags.
|
||||
EnableExperimentalState bool // EnableExperimentalState turns on the latest and greatest (but potentially unstable) changes to the beacon state.
|
||||
WriteSSZStateTransitions bool // WriteSSZStateTransitions to tmp directory.
|
||||
EnablePeerScorer bool // EnablePeerScorer enables experimental peer scoring in p2p.
|
||||
DisableReorgLateBlocks bool // DisableReorgLateBlocks disables reorgs of late blocks.
|
||||
@@ -176,6 +177,11 @@ func ConfigureBeaconChain(ctx *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if ctx.Bool(enableExperimentalState.Name) {
|
||||
logEnabled(enableExperimentalState)
|
||||
cfg.EnableExperimentalState = true
|
||||
}
|
||||
|
||||
if ctx.Bool(writeSSZStateTransitionsFlag.Name) {
|
||||
logEnabled(writeSSZStateTransitionsFlag)
|
||||
cfg.WriteSSZStateTransitions = true
|
||||
|
||||
@@ -33,6 +33,10 @@ var (
|
||||
Name: "dev",
|
||||
Usage: "Enable experimental features still in development. These features may not be stable.",
|
||||
}
|
||||
enableExperimentalState = &cli.BoolFlag{
|
||||
Name: "enable-experimental-state",
|
||||
Usage: "Turn on the latest and greatest (but potentially unstable) changes to the beacon state",
|
||||
}
|
||||
writeSSZStateTransitionsFlag = &cli.BoolFlag{
|
||||
Name: "interop-write-ssz-state-transitions",
|
||||
Usage: "Write ssz states to disk after attempted state transition",
|
||||
@@ -165,6 +169,7 @@ var (
|
||||
var devModeFlags = []cli.Flag{
|
||||
enableVerboseSigVerification,
|
||||
enableEIP4881,
|
||||
enableExperimentalState,
|
||||
}
|
||||
|
||||
// ValidatorFlags contains a list of all the feature flags that apply to the validator client.
|
||||
@@ -189,6 +194,7 @@ var E2EValidatorFlags = []string{
|
||||
// BeaconChainFlags contains a list of all the feature flags that apply to the beacon-chain client.
|
||||
var BeaconChainFlags = append(deprecatedBeaconFlags, append(deprecatedFlags, []cli.Flag{
|
||||
devModeFlag,
|
||||
enableExperimentalState,
|
||||
writeSSZStateTransitionsFlag,
|
||||
disableGRPCConnectionLogging,
|
||||
HoleskyTestnet,
|
||||
|
||||
@@ -3,6 +3,7 @@ package consensus_types
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
|
||||
errors2 "github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v4/runtime/version"
|
||||
@@ -13,9 +14,21 @@ var (
|
||||
ErrNilObjectWrapped = errors.New("attempted to wrap nil object")
|
||||
// ErrUnsupportedField is returned when a getter/setter access is not supported.
|
||||
ErrUnsupportedField = errors.New("unsupported getter")
|
||||
// ErrOutOfBounds is returned when a slice or array index does not exist.
|
||||
ErrOutOfBounds = errors.New("index out of bounds")
|
||||
)
|
||||
|
||||
// ErrNotSupported constructs a message informing about an unsupported field access.
|
||||
func ErrNotSupported(funcName string, ver int) error {
|
||||
return errors2.Wrap(ErrUnsupportedField, fmt.Sprintf("%s is not supported for %s", funcName, version.String(ver)))
|
||||
}
|
||||
|
||||
// ThreadSafeEnumerator is a thread-safe counter of all objects created since the node's start.
|
||||
type ThreadSafeEnumerator struct {
|
||||
counter uint64
|
||||
}
|
||||
|
||||
// Inc increments the enumerator and returns the new object count.
|
||||
func (c *ThreadSafeEnumerator) Inc() uint64 {
|
||||
return atomic.AddUint64(&c.counter, 1)
|
||||
}
|
||||
|
||||
@@ -5,10 +5,6 @@ go_library(
|
||||
srcs = ["multi_value_slice.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/container/multi-value-slice",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//container/multi-value-slice/interfaces:go_default_library",
|
||||
"@com_github_google_uuid//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
@@ -18,6 +14,5 @@ go_test(
|
||||
deps = [
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"@com_github_google_uuid//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["interfaces.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/v4/container/multi-value-slice/interfaces",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["@com_github_google_uuid//:go_default_library"],
|
||||
)
|
||||
@@ -1,9 +0,0 @@
|
||||
package interfaces
|
||||
|
||||
import "github.com/google/uuid"
|
||||
|
||||
// Identifiable represents an object that can be uniquely identified by its Id.
|
||||
type Identifiable interface {
|
||||
Id() uuid.UUID
|
||||
SetId(id uuid.UUID)
|
||||
}
|
||||
@@ -92,20 +92,25 @@ package mvslice
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/prysmaticlabs/prysm/v4/container/multi-value-slice/interfaces"
|
||||
)
|
||||
|
||||
// Id is an object identifier.
|
||||
type Id = uint64
|
||||
|
||||
// Identifiable represents an object that can be uniquely identified by its Id.
|
||||
type Identifiable interface {
|
||||
Id() Id
|
||||
}
|
||||
|
||||
// MultiValueSlice defines an abstraction over all concrete implementations of the generic Slice.
|
||||
type MultiValueSlice[O interfaces.Identifiable] interface {
|
||||
Len(obj O) uuid.UUID
|
||||
type MultiValueSlice[O Identifiable] interface {
|
||||
Len(obj O) int
|
||||
}
|
||||
|
||||
// Value defines a single value along with one or more IDs that share this value.
|
||||
type Value[V any] struct {
|
||||
val V
|
||||
ids []uuid.UUID
|
||||
ids []uint64
|
||||
}
|
||||
|
||||
// MultiValueItem defines a collection of Value items.
|
||||
@@ -119,11 +124,11 @@ type MultiValueItem[V any] struct {
|
||||
// - O interfaces.Identifiable - the type of objects sharing the slice. The constraint is required
|
||||
// because we need a way to compare objects against each other in order to know which objects
|
||||
// values should be accessed.
|
||||
type Slice[V comparable, O interfaces.Identifiable] struct {
|
||||
type Slice[V comparable, O Identifiable] struct {
|
||||
sharedItems []V
|
||||
individualItems map[uint64]*MultiValueItem[V]
|
||||
appendedItems []*MultiValueItem[V]
|
||||
cachedLengths map[uuid.UUID]int
|
||||
cachedLengths map[uint64]int
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
@@ -132,7 +137,7 @@ func (s *Slice[V, O]) Init(items []V) {
|
||||
s.sharedItems = items
|
||||
s.individualItems = map[uint64]*MultiValueItem[V]{}
|
||||
s.appendedItems = []*MultiValueItem[V]{}
|
||||
s.cachedLengths = map[uuid.UUID]int{}
|
||||
s.cachedLengths = map[uint64]int{}
|
||||
}
|
||||
|
||||
// Len returns the number of items for the input object.
|
||||
@@ -283,7 +288,7 @@ func (s *Slice[V, O]) Append(obj O, val V) {
|
||||
defer s.lock.Unlock()
|
||||
|
||||
if len(s.appendedItems) == 0 {
|
||||
s.appendedItems = append(s.appendedItems, &MultiValueItem[V]{Values: []*Value[V]{{val: val, ids: []uuid.UUID{obj.Id()}}}})
|
||||
s.appendedItems = append(s.appendedItems, &MultiValueItem[V]{Values: []*Value[V]{{val: val, ids: []uint64{obj.Id()}}}})
|
||||
s.cachedLengths[obj.Id()] = len(s.sharedItems) + 1
|
||||
return
|
||||
}
|
||||
@@ -306,7 +311,7 @@ func (s *Slice[V, O]) Append(obj O, val V) {
|
||||
}
|
||||
}
|
||||
if newValue {
|
||||
item.Values = append(item.Values, &Value[V]{val: val, ids: []uuid.UUID{obj.Id()}})
|
||||
item.Values = append(item.Values, &Value[V]{val: val, ids: []uint64{obj.Id()}})
|
||||
}
|
||||
|
||||
l, ok := s.cachedLengths[obj.Id()]
|
||||
@@ -320,7 +325,7 @@ func (s *Slice[V, O]) Append(obj O, val V) {
|
||||
}
|
||||
}
|
||||
|
||||
s.appendedItems = append(s.appendedItems, &MultiValueItem[V]{Values: []*Value[V]{{val: val, ids: []uuid.UUID{obj.Id()}}}})
|
||||
s.appendedItems = append(s.appendedItems, &MultiValueItem[V]{Values: []*Value[V]{{val: val, ids: []uint64{obj.Id()}}}})
|
||||
|
||||
s.cachedLengths[obj.Id()] = s.cachedLengths[obj.Id()] + 1
|
||||
}
|
||||
@@ -419,7 +424,7 @@ func (s *Slice[V, O]) updateOriginalItem(obj O, index uint64, val V) {
|
||||
}
|
||||
|
||||
if !ok {
|
||||
s.individualItems[index] = &MultiValueItem[V]{Values: []*Value[V]{{val: val, ids: []uuid.UUID{obj.Id()}}}}
|
||||
s.individualItems[index] = &MultiValueItem[V]{Values: []*Value[V]{{val: val, ids: []uint64{obj.Id()}}}}
|
||||
} else {
|
||||
newValue := true
|
||||
for _, v := range ind.Values {
|
||||
@@ -430,7 +435,7 @@ func (s *Slice[V, O]) updateOriginalItem(obj O, index uint64, val V) {
|
||||
}
|
||||
}
|
||||
if newValue {
|
||||
ind.Values = append(ind.Values, &Value[V]{val: val, ids: []uuid.UUID{obj.Id()}})
|
||||
ind.Values = append(ind.Values, &Value[V]{val: val, ids: []uint64{obj.Id()}})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -464,13 +469,13 @@ func (s *Slice[V, O]) updateAppendedItem(obj O, index uint64, val V) error {
|
||||
}
|
||||
}
|
||||
if newValue {
|
||||
item.Values = append(item.Values, &Value[V]{val: val, ids: []uuid.UUID{obj.Id()}})
|
||||
item.Values = append(item.Values, &Value[V]{val: val, ids: []uint64{obj.Id()}})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func containsId(ids []uuid.UUID, wanted uuid.UUID) (int, bool) {
|
||||
func containsId(ids []uint64, wanted uint64) (int, bool) {
|
||||
for i, id := range ids {
|
||||
if id == wanted {
|
||||
return i, true
|
||||
|
||||
@@ -4,40 +4,31 @@ import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v4/testing/require"
|
||||
)
|
||||
|
||||
var (
|
||||
id1 = uuid.New()
|
||||
id2 = uuid.New()
|
||||
id999 = uuid.New()
|
||||
)
|
||||
|
||||
type testObject struct {
|
||||
id uuid.UUID
|
||||
slice *Slice[int, *testObject]
|
||||
id uint64
|
||||
}
|
||||
|
||||
func (o *testObject) Id() uuid.UUID {
|
||||
func (o *testObject) Id() uint64 {
|
||||
return o.id
|
||||
}
|
||||
|
||||
func (o *testObject) SetId(id uuid.UUID) {
|
||||
func (o *testObject) SetId(id uint64) {
|
||||
o.id = id
|
||||
}
|
||||
|
||||
func TestLen(t *testing.T) {
|
||||
s := &Slice[int, *testObject]{}
|
||||
s.Init([]int{1, 2, 3})
|
||||
id := uuid.New()
|
||||
s.cachedLengths[id] = 123
|
||||
s.cachedLengths[1] = 123
|
||||
t.Run("cached", func(t *testing.T) {
|
||||
assert.Equal(t, 123, s.Len(&testObject{id: id}))
|
||||
assert.Equal(t, 123, s.Len(&testObject{id: 1}))
|
||||
})
|
||||
t.Run("not cached", func(t *testing.T) {
|
||||
assert.Equal(t, 3, s.Len(&testObject{id: uuid.New()}))
|
||||
assert.Equal(t, 3, s.Len(&testObject{id: 999}))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -51,12 +42,12 @@ func TestCopy(t *testing.T) {
|
||||
// - length of destination object is cached
|
||||
|
||||
s := setup()
|
||||
src := &testObject{id: id1, slice: s}
|
||||
dst := &testObject{id: id999, slice: s}
|
||||
src := &testObject{id: 1}
|
||||
dst := &testObject{id: 999}
|
||||
|
||||
s.Copy(src, dst)
|
||||
|
||||
assert.Equal(t, (*MultiValueItem[int])(nil), dst.slice.individualItems[0])
|
||||
assert.Equal(t, (*MultiValueItem[int])(nil), s.individualItems[0])
|
||||
assertIndividualFound(t, s, dst.id, 1, 1)
|
||||
assertIndividualFound(t, s, dst.id, 2, 3)
|
||||
assertIndividualFound(t, s, dst.id, 3, 1)
|
||||
@@ -64,7 +55,7 @@ func TestCopy(t *testing.T) {
|
||||
assertAppendedFound(t, s, dst.id, 0, 1)
|
||||
assertAppendedFound(t, s, dst.id, 1, 3)
|
||||
assertAppendedNotFound(t, s, dst.id, 2)
|
||||
l, ok := s.cachedLengths[id999]
|
||||
l, ok := s.cachedLengths[999]
|
||||
require.Equal(t, true, ok)
|
||||
assert.Equal(t, 7, l)
|
||||
}
|
||||
@@ -76,8 +67,8 @@ func TestValue(t *testing.T) {
|
||||
// - correct values are returned for an object without appended items
|
||||
|
||||
s := setup()
|
||||
first := &testObject{id: id1, slice: s}
|
||||
second := &testObject{id: id2, slice: s}
|
||||
first := &testObject{id: 1}
|
||||
second := &testObject{id: 2}
|
||||
|
||||
v := s.Value(first)
|
||||
|
||||
@@ -104,9 +95,8 @@ func TestValue(t *testing.T) {
|
||||
|
||||
s = &Slice[int, *testObject]{}
|
||||
s.Init([]int{1, 2, 3})
|
||||
id := uuid.New()
|
||||
|
||||
v = s.Value(&testObject{id: id})
|
||||
v = s.Value(&testObject{id: 999})
|
||||
|
||||
require.Equal(t, 3, len(v))
|
||||
assert.Equal(t, 1, v[0])
|
||||
@@ -122,8 +112,8 @@ func TestAt(t *testing.T) {
|
||||
// - ERROR when index not too large in general, but too large for an object
|
||||
|
||||
s := setup()
|
||||
first := &testObject{id: id1, slice: s}
|
||||
second := &testObject{id: id2, slice: s}
|
||||
first := &testObject{id: 1}
|
||||
second := &testObject{id: 2}
|
||||
|
||||
v, err := s.At(first, 0)
|
||||
require.NoError(t, err)
|
||||
@@ -194,8 +184,8 @@ func TestUpdateAt(t *testing.T) {
|
||||
// - ERROR when index not too large in general, but too large for an object
|
||||
|
||||
s := setup()
|
||||
first := &testObject{id: id1, slice: s}
|
||||
second := &testObject{id: id2, slice: s}
|
||||
first := &testObject{id: 1}
|
||||
second := &testObject{id: 2}
|
||||
|
||||
require.NoError(t, s.UpdateAt(first, 0, 999))
|
||||
assert.Equal(t, 123, s.sharedItems[0])
|
||||
@@ -258,8 +248,8 @@ func TestAppend(t *testing.T) {
|
||||
// we want to start with the simplest slice possible
|
||||
s := &Slice[int, *testObject]{}
|
||||
s.Init([]int{0})
|
||||
first := &testObject{id: id1, slice: s}
|
||||
second := &testObject{id: id2, slice: s}
|
||||
first := &testObject{id: 1}
|
||||
second := &testObject{id: 2}
|
||||
|
||||
// append first value ever
|
||||
s.Append(first, 1)
|
||||
@@ -306,7 +296,7 @@ func TestDetach(t *testing.T) {
|
||||
// - length removed from cache
|
||||
|
||||
s := setup()
|
||||
obj := &testObject{id: id1, slice: s}
|
||||
obj := &testObject{id: 1}
|
||||
|
||||
s.Detach(obj)
|
||||
|
||||
@@ -352,11 +342,11 @@ func setup() *Slice[int, *testObject] {
|
||||
Values: []*Value[int]{
|
||||
{
|
||||
val: 1,
|
||||
ids: []uuid.UUID{id1},
|
||||
ids: []uint64{1},
|
||||
},
|
||||
{
|
||||
val: 2,
|
||||
ids: []uuid.UUID{id2},
|
||||
ids: []uint64{2},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -364,7 +354,7 @@ func setup() *Slice[int, *testObject] {
|
||||
Values: []*Value[int]{
|
||||
{
|
||||
val: 3,
|
||||
ids: []uuid.UUID{id1, id2},
|
||||
ids: []uint64{1, 2},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -372,7 +362,7 @@ func setup() *Slice[int, *testObject] {
|
||||
Values: []*Value[int]{
|
||||
{
|
||||
val: 1,
|
||||
ids: []uuid.UUID{id1},
|
||||
ids: []uint64{1},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -380,7 +370,7 @@ func setup() *Slice[int, *testObject] {
|
||||
Values: []*Value[int]{
|
||||
{
|
||||
val: 2,
|
||||
ids: []uuid.UUID{id2},
|
||||
ids: []uint64{2},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -389,11 +379,11 @@ func setup() *Slice[int, *testObject] {
|
||||
Values: []*Value[int]{
|
||||
{
|
||||
val: 1,
|
||||
ids: []uuid.UUID{id1},
|
||||
ids: []uint64{1},
|
||||
},
|
||||
{
|
||||
val: 2,
|
||||
ids: []uuid.UUID{id2},
|
||||
ids: []uint64{2},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -401,7 +391,7 @@ func setup() *Slice[int, *testObject] {
|
||||
Values: []*Value[int]{
|
||||
{
|
||||
val: 3,
|
||||
ids: []uuid.UUID{id1, id2},
|
||||
ids: []uint64{1, 2},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -409,18 +399,18 @@ func setup() *Slice[int, *testObject] {
|
||||
Values: []*Value[int]{
|
||||
{
|
||||
val: 2,
|
||||
ids: []uuid.UUID{id2},
|
||||
ids: []uint64{2},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
s.cachedLengths[id1] = 7
|
||||
s.cachedLengths[id2] = 8
|
||||
s.cachedLengths[1] = 7
|
||||
s.cachedLengths[2] = 8
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func assertIndividualFound(t *testing.T, slice *Slice[int, *testObject], id uuid.UUID, itemIndex uint64, expected int) {
|
||||
func assertIndividualFound(t *testing.T, slice *Slice[int, *testObject], id uint64, itemIndex uint64, expected int) {
|
||||
found := false
|
||||
for _, v := range slice.individualItems[itemIndex].Values {
|
||||
for _, o := range v.ids {
|
||||
@@ -433,7 +423,7 @@ func assertIndividualFound(t *testing.T, slice *Slice[int, *testObject], id uuid
|
||||
assert.Equal(t, true, found)
|
||||
}
|
||||
|
||||
func assertIndividualNotFound(t *testing.T, slice *Slice[int, *testObject], id uuid.UUID, itemIndex uint64) {
|
||||
func assertIndividualNotFound(t *testing.T, slice *Slice[int, *testObject], id uint64, itemIndex uint64) {
|
||||
found := false
|
||||
for _, v := range slice.individualItems[itemIndex].Values {
|
||||
for _, o := range v.ids {
|
||||
@@ -445,7 +435,7 @@ func assertIndividualNotFound(t *testing.T, slice *Slice[int, *testObject], id u
|
||||
assert.Equal(t, false, found)
|
||||
}
|
||||
|
||||
func assertAppendedFound(t *testing.T, slice *Slice[int, *testObject], id uuid.UUID, itemIndex uint64, expected int) {
|
||||
func assertAppendedFound(t *testing.T, slice *Slice[int, *testObject], id uint64, itemIndex uint64, expected int) {
|
||||
found := false
|
||||
for _, v := range slice.appendedItems[itemIndex].Values {
|
||||
for _, o := range v.ids {
|
||||
@@ -458,7 +448,7 @@ func assertAppendedFound(t *testing.T, slice *Slice[int, *testObject], id uuid.U
|
||||
assert.Equal(t, true, found)
|
||||
}
|
||||
|
||||
func assertAppendedNotFound(t *testing.T, slice *Slice[int, *testObject], id uuid.UUID, itemIndex uint64) {
|
||||
func assertAppendedNotFound(t *testing.T, slice *Slice[int, *testObject], id uint64, itemIndex uint64) {
|
||||
found := false
|
||||
for _, v := range slice.appendedItems[itemIndex].Values {
|
||||
for _, o := range v.ids {
|
||||
@@ -485,12 +475,11 @@ func BenchmarkValue(b *testing.B) {
|
||||
b.Run("100,000 equal individual items", func(b *testing.B) {
|
||||
s := &Slice[int, *testObject]{}
|
||||
s.Init(make([]int, _100k))
|
||||
s.individualItems[0] = &MultiValueItem[int]{Values: []*Value[int]{{val: 999, ids: []uuid.UUID{}}}}
|
||||
s.individualItems[0] = &MultiValueItem[int]{Values: []*Value[int]{{val: 999, ids: []uint64{}}}}
|
||||
objs := make([]*testObject, _100k)
|
||||
for i := 0; i < len(objs); i++ {
|
||||
id := uuid.New()
|
||||
objs[i] = &testObject{id: id, slice: s}
|
||||
s.individualItems[0].Values[0].ids = append(s.individualItems[0].Values[0].ids, id)
|
||||
objs[i] = &testObject{id: uint64(i)}
|
||||
s.individualItems[0].Values[0].ids = append(s.individualItems[0].Values[0].ids, uint64(i))
|
||||
}
|
||||
for i := 0; i < b.N; i++ {
|
||||
s.Value(objs[rand.Intn(_100k)])
|
||||
@@ -501,9 +490,8 @@ func BenchmarkValue(b *testing.B) {
|
||||
s.Init(make([]int, _100k))
|
||||
objs := make([]*testObject, _100k)
|
||||
for i := 0; i < len(objs); i++ {
|
||||
id := uuid.New()
|
||||
objs[i] = &testObject{id: id, slice: s}
|
||||
s.individualItems[uint64(i)] = &MultiValueItem[int]{Values: []*Value[int]{{val: i, ids: []uuid.UUID{id}}}}
|
||||
objs[i] = &testObject{id: uint64(i)}
|
||||
s.individualItems[uint64(i)] = &MultiValueItem[int]{Values: []*Value[int]{{val: i, ids: []uint64{uint64(i)}}}}
|
||||
}
|
||||
for i := 0; i < b.N; i++ {
|
||||
s.Value(objs[rand.Intn(_100k)])
|
||||
@@ -512,12 +500,11 @@ func BenchmarkValue(b *testing.B) {
|
||||
b.Run("100,000 shared items and 100,000 equal appended items", func(b *testing.B) {
|
||||
s := &Slice[int, *testObject]{}
|
||||
s.Init(make([]int, _100k))
|
||||
s.appendedItems = []*MultiValueItem[int]{{Values: []*Value[int]{{val: 999, ids: []uuid.UUID{}}}}}
|
||||
s.appendedItems = []*MultiValueItem[int]{{Values: []*Value[int]{{val: 999, ids: []uint64{}}}}}
|
||||
objs := make([]*testObject, _100k)
|
||||
for i := 0; i < len(objs); i++ {
|
||||
id := uuid.New()
|
||||
objs[i] = &testObject{id: id, slice: s}
|
||||
s.appendedItems[0].Values[0].ids = append(s.appendedItems[0].Values[0].ids, id)
|
||||
objs[i] = &testObject{id: uint64(i)}
|
||||
s.appendedItems[0].Values[0].ids = append(s.appendedItems[0].Values[0].ids, uint64(i))
|
||||
}
|
||||
for i := 0; i < b.N; i++ {
|
||||
s.Value(objs[rand.Intn(_100k)])
|
||||
@@ -529,9 +516,8 @@ func BenchmarkValue(b *testing.B) {
|
||||
s.appendedItems = []*MultiValueItem[int]{}
|
||||
objs := make([]*testObject, _100k)
|
||||
for i := 0; i < len(objs); i++ {
|
||||
id := uuid.New()
|
||||
objs[i] = &testObject{id: id, slice: s}
|
||||
s.appendedItems = append(s.appendedItems, &MultiValueItem[int]{Values: []*Value[int]{{val: i, ids: []uuid.UUID{id}}}})
|
||||
objs[i] = &testObject{id: uint64(i)}
|
||||
s.appendedItems = append(s.appendedItems, &MultiValueItem[int]{Values: []*Value[int]{{val: i, ids: []uint64{uint64(i)}}}})
|
||||
}
|
||||
for i := 0; i < b.N; i++ {
|
||||
s.Value(objs[rand.Intn(_100k)])
|
||||
@@ -547,12 +533,11 @@ func BenchmarkValue(b *testing.B) {
|
||||
b.Run("1,000,000 equal individual items", func(b *testing.B) {
|
||||
s := &Slice[int, *testObject]{}
|
||||
s.Init(make([]int, _1m))
|
||||
s.individualItems[0] = &MultiValueItem[int]{Values: []*Value[int]{{val: 999, ids: []uuid.UUID{}}}}
|
||||
s.individualItems[0] = &MultiValueItem[int]{Values: []*Value[int]{{val: 999, ids: []uint64{}}}}
|
||||
objs := make([]*testObject, _1m)
|
||||
for i := 0; i < len(objs); i++ {
|
||||
id := uuid.New()
|
||||
objs[i] = &testObject{id: id, slice: s}
|
||||
s.individualItems[0].Values[0].ids = append(s.individualItems[0].Values[0].ids, id)
|
||||
objs[i] = &testObject{id: uint64(i)}
|
||||
s.individualItems[0].Values[0].ids = append(s.individualItems[0].Values[0].ids, uint64(i))
|
||||
}
|
||||
for i := 0; i < b.N; i++ {
|
||||
s.Value(objs[rand.Intn(_1m)])
|
||||
@@ -563,9 +548,8 @@ func BenchmarkValue(b *testing.B) {
|
||||
s.Init(make([]int, _1m))
|
||||
objs := make([]*testObject, _1m)
|
||||
for i := 0; i < len(objs); i++ {
|
||||
id := uuid.New()
|
||||
objs[i] = &testObject{id: id, slice: s}
|
||||
s.individualItems[uint64(i)] = &MultiValueItem[int]{Values: []*Value[int]{{val: i, ids: []uuid.UUID{id}}}}
|
||||
objs[i] = &testObject{id: uint64(i)}
|
||||
s.individualItems[uint64(i)] = &MultiValueItem[int]{Values: []*Value[int]{{val: i, ids: []uint64{uint64(i)}}}}
|
||||
}
|
||||
for i := 0; i < b.N; i++ {
|
||||
s.Value(objs[rand.Intn(_1m)])
|
||||
@@ -574,12 +558,11 @@ func BenchmarkValue(b *testing.B) {
|
||||
b.Run("1,000,000 shared items and 1,000,000 equal appended items", func(b *testing.B) {
|
||||
s := &Slice[int, *testObject]{}
|
||||
s.Init(make([]int, _1m))
|
||||
s.appendedItems = []*MultiValueItem[int]{{Values: []*Value[int]{{val: 999, ids: []uuid.UUID{}}}}}
|
||||
s.appendedItems = []*MultiValueItem[int]{{Values: []*Value[int]{{val: 999, ids: []uint64{}}}}}
|
||||
objs := make([]*testObject, _1m)
|
||||
for i := 0; i < len(objs); i++ {
|
||||
id := uuid.New()
|
||||
objs[i] = &testObject{id: id, slice: s}
|
||||
s.appendedItems[0].Values[0].ids = append(s.appendedItems[0].Values[0].ids, id)
|
||||
objs[i] = &testObject{id: uint64(i)}
|
||||
s.appendedItems[0].Values[0].ids = append(s.appendedItems[0].Values[0].ids, uint64(i))
|
||||
}
|
||||
for i := 0; i < b.N; i++ {
|
||||
s.Value(objs[rand.Intn(_1m)])
|
||||
@@ -591,9 +574,8 @@ func BenchmarkValue(b *testing.B) {
|
||||
s.appendedItems = []*MultiValueItem[int]{}
|
||||
objs := make([]*testObject, _1m)
|
||||
for i := 0; i < len(objs); i++ {
|
||||
id := uuid.New()
|
||||
objs[i] = &testObject{id: id, slice: s}
|
||||
s.appendedItems = append(s.appendedItems, &MultiValueItem[int]{Values: []*Value[int]{{val: i, ids: []uuid.UUID{id}}}})
|
||||
objs[i] = &testObject{id: uint64(i)}
|
||||
s.appendedItems = append(s.appendedItems, &MultiValueItem[int]{Values: []*Value[int]{{val: i, ids: []uint64{uint64(i)}}}})
|
||||
}
|
||||
for i := 0; i < b.N; i++ {
|
||||
s.Value(objs[rand.Intn(_1m)])
|
||||
@@ -609,12 +591,11 @@ func BenchmarkValue(b *testing.B) {
|
||||
b.Run("10,000,000 equal individual items", func(b *testing.B) {
|
||||
s := &Slice[int, *testObject]{}
|
||||
s.Init(make([]int, _10m))
|
||||
s.individualItems[0] = &MultiValueItem[int]{Values: []*Value[int]{{val: 999, ids: []uuid.UUID{}}}}
|
||||
s.individualItems[0] = &MultiValueItem[int]{Values: []*Value[int]{{val: 999, ids: []uint64{}}}}
|
||||
objs := make([]*testObject, _10m)
|
||||
for i := 0; i < len(objs); i++ {
|
||||
id := uuid.New()
|
||||
objs[i] = &testObject{id: id, slice: s}
|
||||
s.individualItems[0].Values[0].ids = append(s.individualItems[0].Values[0].ids, id)
|
||||
objs[i] = &testObject{id: uint64(i)}
|
||||
s.individualItems[0].Values[0].ids = append(s.individualItems[0].Values[0].ids, uint64(i))
|
||||
}
|
||||
for i := 0; i < b.N; i++ {
|
||||
s.Value(objs[rand.Intn(_10m)])
|
||||
@@ -625,9 +606,8 @@ func BenchmarkValue(b *testing.B) {
|
||||
s.Init(make([]int, _10m))
|
||||
objs := make([]*testObject, _10m)
|
||||
for i := 0; i < len(objs); i++ {
|
||||
id := uuid.New()
|
||||
objs[i] = &testObject{id: id, slice: s}
|
||||
s.individualItems[uint64(i)] = &MultiValueItem[int]{Values: []*Value[int]{{val: i, ids: []uuid.UUID{id}}}}
|
||||
objs[i] = &testObject{id: uint64(i)}
|
||||
s.individualItems[uint64(i)] = &MultiValueItem[int]{Values: []*Value[int]{{val: i, ids: []uint64{uint64(i)}}}}
|
||||
}
|
||||
for i := 0; i < b.N; i++ {
|
||||
s.Value(objs[rand.Intn(_10m)])
|
||||
@@ -636,12 +616,11 @@ func BenchmarkValue(b *testing.B) {
|
||||
b.Run("10,000,000 shared items and 10,000,000 equal appended items", func(b *testing.B) {
|
||||
s := &Slice[int, *testObject]{}
|
||||
s.Init(make([]int, _10m))
|
||||
s.appendedItems = []*MultiValueItem[int]{{Values: []*Value[int]{{val: 999, ids: []uuid.UUID{}}}}}
|
||||
s.appendedItems = []*MultiValueItem[int]{{Values: []*Value[int]{{val: 999, ids: []uint64{}}}}}
|
||||
objs := make([]*testObject, _10m)
|
||||
for i := 0; i < len(objs); i++ {
|
||||
id := uuid.New()
|
||||
objs[i] = &testObject{id: id, slice: s}
|
||||
s.appendedItems[0].Values[0].ids = append(s.appendedItems[0].Values[0].ids, id)
|
||||
objs[i] = &testObject{id: uint64(i)}
|
||||
s.appendedItems[0].Values[0].ids = append(s.appendedItems[0].Values[0].ids, uint64(i))
|
||||
}
|
||||
for i := 0; i < b.N; i++ {
|
||||
s.Value(objs[rand.Intn(_10m)])
|
||||
@@ -653,9 +632,8 @@ func BenchmarkValue(b *testing.B) {
|
||||
s.appendedItems = []*MultiValueItem[int]{}
|
||||
objs := make([]*testObject, _10m)
|
||||
for i := 0; i < len(objs); i++ {
|
||||
id := uuid.New()
|
||||
objs[i] = &testObject{id: id, slice: s}
|
||||
s.appendedItems = append(s.appendedItems, &MultiValueItem[int]{Values: []*Value[int]{{val: i, ids: []uuid.UUID{id}}}})
|
||||
objs[i] = &testObject{id: uint64(i)}
|
||||
s.appendedItems = append(s.appendedItems, &MultiValueItem[int]{Values: []*Value[int]{{val: i, ids: []uint64{uint64(i)}}}})
|
||||
}
|
||||
for i := 0; i < b.N; i++ {
|
||||
s.Value(objs[rand.Intn(_10m)])
|
||||
|
||||
@@ -89,24 +89,65 @@ func (s *PremineGenesisConfig) prepare(ctx context.Context) (state.BeaconState,
|
||||
func (s *PremineGenesisConfig) empty() (state.BeaconState, error) {
|
||||
var e state.BeaconState
|
||||
var err error
|
||||
|
||||
bRoots := make([][]byte, fieldparams.BlockRootsLength)
|
||||
for i := range bRoots {
|
||||
bRoots[i] = bytesutil.PadTo([]byte{}, 32)
|
||||
}
|
||||
sRoots := make([][]byte, fieldparams.StateRootsLength)
|
||||
for i := range sRoots {
|
||||
sRoots[i] = bytesutil.PadTo([]byte{}, 32)
|
||||
}
|
||||
mixes := make([][]byte, fieldparams.RandaoMixesLength)
|
||||
for i := range mixes {
|
||||
mixes[i] = bytesutil.PadTo([]byte{}, 32)
|
||||
}
|
||||
|
||||
switch s.Version {
|
||||
case version.Phase0:
|
||||
e, err = state_native.InitializeFromProtoPhase0(ðpb.BeaconState{})
|
||||
e, err = state_native.InitializeFromProtoPhase0(ðpb.BeaconState{
|
||||
BlockRoots: bRoots,
|
||||
StateRoots: sRoots,
|
||||
RandaoMixes: mixes,
|
||||
Balances: []uint64{},
|
||||
Validators: []*ethpb.Validator{},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case version.Altair:
|
||||
e, err = state_native.InitializeFromProtoAltair(ðpb.BeaconStateAltair{})
|
||||
e, err = state_native.InitializeFromProtoAltair(ðpb.BeaconStateAltair{
|
||||
BlockRoots: bRoots,
|
||||
StateRoots: sRoots,
|
||||
RandaoMixes: mixes,
|
||||
Balances: []uint64{},
|
||||
InactivityScores: []uint64{},
|
||||
Validators: []*ethpb.Validator{},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case version.Bellatrix:
|
||||
e, err = state_native.InitializeFromProtoBellatrix(ðpb.BeaconStateBellatrix{})
|
||||
e, err = state_native.InitializeFromProtoBellatrix(ðpb.BeaconStateBellatrix{
|
||||
BlockRoots: bRoots,
|
||||
StateRoots: sRoots,
|
||||
RandaoMixes: mixes,
|
||||
Balances: []uint64{},
|
||||
InactivityScores: []uint64{},
|
||||
Validators: []*ethpb.Validator{},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case version.Capella:
|
||||
e, err = state_native.InitializeFromProtoCapella(ðpb.BeaconStateCapella{})
|
||||
e, err = state_native.InitializeFromProtoCapella(ðpb.BeaconStateCapella{
|
||||
BlockRoots: bRoots,
|
||||
StateRoots: sRoots,
|
||||
RandaoMixes: mixes,
|
||||
Balances: []uint64{},
|
||||
InactivityScores: []uint64{},
|
||||
Validators: []*ethpb.Validator{},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -121,12 +162,6 @@ func (s *PremineGenesisConfig) empty() (state.BeaconState, error) {
|
||||
if err = e.SetSlot(0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = e.SetValidators([]*ethpb.Validator{}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = e.SetBalances([]uint64{}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = e.SetJustificationBits([]byte{0}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user