mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
Deduplicate native state (a.k.a. One State to rule them all) (#10483)
* v0 * getters/setters * init and copy * hasher * all the nice stuff * make bazel happy * remove tests for smaller PR * remove old states * move files * import fixes * custom MarshalSSZ * fixed deadlock * copy version when copying state * correct issues in state_trie * fix Copy() * better e2e comment * add code to minimal state * spectest test * Revert "Auxiliary commit to revert individual files from 84154423464e8372f7e0a03367403656ac5cd78e" This reverts commit 9602599d183081291dfa0ba4f1036430f63a7822. * native state assert * always error * always log * more native state usage * cleanup * remove empty line * Revert "spectests" This reverts commit 1c49bed5d1cf6224afaf21e18562bf72fae5d2b6. # Conflicts: # beacon-chain/powchain/service.go # beacon-chain/state/v1/state_trie.go # beacon-chain/state/v2/state_trie.go # beacon-chain/state/v3/state_trie.go # testing/spectest/shared/phase0/finality/BUILD.bazel # testing/spectest/shared/phase0/finality/runner.go * dedup field trie * fix test issues * cleanup * use correct field num in FinalizedRootProof * use existing version constant * halfway there * "working" version * some fixes * fix field nums in tests * rename v0types to nativetypes * Revert "Auxiliary commit to revert individual files from dc549b1cf8e724bd08cee1ecc760ff3771d5592d" This reverts commit 7254d3070d8693b283fc686a2e01a822ecbac1b3. * uncomment code * remove map size * Revert "Revert "spectests"" This reverts commit39c271ae6b. * use reverse map * Revert "Revert "Revert "spectests""" This reverts commit19ba8cf95c. * finally found the bug (cherry picked from commit a5414c4be1bdb61a50b391ea5301895e772cc5e9) * simplify populateFieldIndexes * fix copy (cherry picked from commit 7da4fb8cf51557ef931bb781872ea52fc6731af5) * remove native state from e2e * remove index map * unsupported functions * Use ProtobufBeaconState() from native state * tests * typo * reduce complexity of `SaveStatesEfficient` * remove unused receiver name * update doc.go * fix test assertion * fix test assertion 2 * Phase0 justification bits * bring back state tests * rename fieldIndexRev * versioning of ToProto * remove version check from unexported function * hasher tests * don't return error from JustificationBits * extract fieldConvertersNative * helper error function * use fieldConvertersNative * Introduce RealPosition method on FieldIndex * use RealPosition in hasher * remove unused fields * remove TestAppendBeyondIndicesLimit (cherry picked from commit 3017e700282969c30006b64c95c21ffe6b166f8b) * simplify RealPosition * rename field interface * use helper in proofs.go * Update beacon-chain/core/altair/upgrade.go Co-authored-by: Nishant Das <nishdas93@gmail.com> Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
This commit is contained in:
@@ -106,7 +106,7 @@ func weighJustificationAndFinalization(state state.BeaconState,
|
|||||||
if err := state.SetCurrentJustifiedCheckpoint(ðpb.Checkpoint{Epoch: prevEpoch, Root: blockRoot}); err != nil {
|
if err := state.SetCurrentJustifiedCheckpoint(ðpb.Checkpoint{Epoch: prevEpoch, Root: blockRoot}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
newBits := state.JustificationBits()
|
newBits = state.JustificationBits()
|
||||||
newBits.SetBitAt(1, true)
|
newBits.SetBitAt(1, true)
|
||||||
if err := state.SetJustificationBits(newBits); err != nil {
|
if err := state.SetJustificationBits(newBits); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -122,7 +122,7 @@ func weighJustificationAndFinalization(state state.BeaconState,
|
|||||||
if err := state.SetCurrentJustifiedCheckpoint(ðpb.Checkpoint{Epoch: currentEpoch, Root: blockRoot}); err != nil {
|
if err := state.SetCurrentJustifiedCheckpoint(ðpb.Checkpoint{Epoch: currentEpoch, Root: blockRoot}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
newBits := state.JustificationBits()
|
newBits = state.JustificationBits()
|
||||||
newBits.SetBitAt(0, true)
|
newBits.SetBitAt(0, true)
|
||||||
if err := state.SetJustificationBits(newBits); err != nil {
|
if err := state.SetJustificationBits(newBits); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ go_library(
|
|||||||
"//beacon-chain/db/iface:go_default_library",
|
"//beacon-chain/db/iface:go_default_library",
|
||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
"//beacon-chain/state/genesis:go_default_library",
|
"//beacon-chain/state/genesis:go_default_library",
|
||||||
|
"//beacon-chain/state/state-native:go_default_library",
|
||||||
"//beacon-chain/state/v1:go_default_library",
|
"//beacon-chain/state/v1:go_default_library",
|
||||||
"//beacon-chain/state/v2:go_default_library",
|
"//beacon-chain/state/v2:go_default_library",
|
||||||
"//beacon-chain/state/v3:go_default_library",
|
"//beacon-chain/state/v3:go_default_library",
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/genesis"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/genesis"
|
||||||
|
state_native "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native"
|
||||||
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
||||||
v2 "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
|
v2 "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
|
||||||
v3 "github.com/prysmaticlabs/prysm/beacon-chain/state/v3"
|
v3 "github.com/prysmaticlabs/prysm/beacon-chain/state/v3"
|
||||||
@@ -204,7 +205,13 @@ func (s *Store) SaveStatesEfficient(ctx context.Context, states []state.ReadOnly
|
|||||||
// look at issue https://github.com/prysmaticlabs/prysm/issues/9262.
|
// look at issue https://github.com/prysmaticlabs/prysm/issues/9262.
|
||||||
switch rawType := states[i].InnerStateUnsafe().(type) {
|
switch rawType := states[i].InnerStateUnsafe().(type) {
|
||||||
case *ethpb.BeaconState:
|
case *ethpb.BeaconState:
|
||||||
pbState, err := v1.ProtobufBeaconState(rawType)
|
var pbState *ethpb.BeaconState
|
||||||
|
var err error
|
||||||
|
if features.Get().EnableNativeState {
|
||||||
|
pbState, err = state_native.ProtobufBeaconStatePhase0(rawType)
|
||||||
|
} else {
|
||||||
|
pbState, err = v1.ProtobufBeaconState(rawType)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -225,7 +232,13 @@ func (s *Store) SaveStatesEfficient(ctx context.Context, states []state.ReadOnly
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case *ethpb.BeaconStateAltair:
|
case *ethpb.BeaconStateAltair:
|
||||||
pbState, err := v2.ProtobufBeaconState(rawType)
|
var pbState *ethpb.BeaconStateAltair
|
||||||
|
var err error
|
||||||
|
if features.Get().EnableNativeState {
|
||||||
|
pbState, err = state_native.ProtobufBeaconStateAltair(rawType)
|
||||||
|
} else {
|
||||||
|
pbState, err = v2.ProtobufBeaconState(rawType)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -247,7 +260,13 @@ func (s *Store) SaveStatesEfficient(ctx context.Context, states []state.ReadOnly
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case *ethpb.BeaconStateBellatrix:
|
case *ethpb.BeaconStateBellatrix:
|
||||||
pbState, err := v3.ProtobufBeaconState(rawType)
|
var pbState *ethpb.BeaconStateBellatrix
|
||||||
|
var err error
|
||||||
|
if features.Get().EnableNativeState {
|
||||||
|
pbState, err = state_native.ProtobufBeaconStateBellatrix(rawType)
|
||||||
|
} else {
|
||||||
|
pbState, err = v3.ProtobufBeaconState(rawType)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -274,28 +293,7 @@ func (s *Store) SaveStatesEfficient(ctx context.Context, states []state.ReadOnly
|
|||||||
}
|
}
|
||||||
|
|
||||||
// store the validator entries separately to save space.
|
// store the validator entries separately to save space.
|
||||||
valBkt := tx.Bucket(stateValidatorsBucket)
|
return s.storeValidatorEntriesSeparately(ctx, tx, validatorsEntries)
|
||||||
for hashStr, validatorEntry := range validatorsEntries {
|
|
||||||
key := []byte(hashStr)
|
|
||||||
// if the entry is not in the cache and not in the DB,
|
|
||||||
// then insert it in the DB and add to the cache.
|
|
||||||
if _, ok := s.validatorEntryCache.Get(key); !ok {
|
|
||||||
validatorEntryCacheMiss.Inc()
|
|
||||||
if valEntry := valBkt.Get(key); valEntry == nil {
|
|
||||||
valBytes, encodeErr := encode(ctx, validatorEntry)
|
|
||||||
if encodeErr != nil {
|
|
||||||
return encodeErr
|
|
||||||
}
|
|
||||||
if putErr := valBkt.Put(key, valBytes); putErr != nil {
|
|
||||||
return putErr
|
|
||||||
}
|
|
||||||
s.validatorEntryCache.Set(key, validatorEntry, int64(len(valBytes)))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
validatorEntryCacheHit.Inc()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -303,6 +301,31 @@ func (s *Store) SaveStatesEfficient(ctx context.Context, states []state.ReadOnly
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Store) storeValidatorEntriesSeparately(ctx context.Context, tx *bolt.Tx, validatorsEntries map[string]*ethpb.Validator) error {
|
||||||
|
valBkt := tx.Bucket(stateValidatorsBucket)
|
||||||
|
for hashStr, validatorEntry := range validatorsEntries {
|
||||||
|
key := []byte(hashStr)
|
||||||
|
// if the entry is not in the cache and not in the DB,
|
||||||
|
// then insert it in the DB and add to the cache.
|
||||||
|
if _, ok := s.validatorEntryCache.Get(key); !ok {
|
||||||
|
validatorEntryCacheMiss.Inc()
|
||||||
|
if valEntry := valBkt.Get(key); valEntry == nil {
|
||||||
|
valBytes, encodeErr := encode(ctx, validatorEntry)
|
||||||
|
if encodeErr != nil {
|
||||||
|
return encodeErr
|
||||||
|
}
|
||||||
|
if putErr := valBkt.Put(key, valBytes); putErr != nil {
|
||||||
|
return putErr
|
||||||
|
}
|
||||||
|
s.validatorEntryCache.Set(key, validatorEntry, int64(len(valBytes)))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
validatorEntryCacheHit.Inc()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// HasState checks if a state by root exists in the db.
|
// HasState checks if a state by root exists in the db.
|
||||||
func (s *Store) HasState(ctx context.Context, blockRoot [32]byte) bool {
|
func (s *Store) HasState(ctx context.Context, blockRoot [32]byte) bool {
|
||||||
_, span := trace.StartSpan(ctx, "BeaconDB.HasState")
|
_, span := trace.StartSpan(ctx, "BeaconDB.HasState")
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ go_library(
|
|||||||
"//beacon-chain/db:go_default_library",
|
"//beacon-chain/db:go_default_library",
|
||||||
"//beacon-chain/powchain/types:go_default_library",
|
"//beacon-chain/powchain/types:go_default_library",
|
||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
"//beacon-chain/state/state-native/v1:go_default_library",
|
"//beacon-chain/state/state-native:go_default_library",
|
||||||
"//beacon-chain/state/stategen:go_default_library",
|
"//beacon-chain/state/stategen:go_default_library",
|
||||||
"//beacon-chain/state/v1:go_default_library",
|
"//beacon-chain/state/v1:go_default_library",
|
||||||
"//config/features:go_default_library",
|
"//config/features:go_default_library",
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ import (
|
|||||||
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
|
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||||
coreState "github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
coreState "github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
|
||||||
|
state_native "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native"
|
||||||
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
||||||
|
"github.com/prysmaticlabs/prysm/config/features"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
contracts "github.com/prysmaticlabs/prysm/contracts/deposit"
|
contracts "github.com/prysmaticlabs/prysm/contracts/deposit"
|
||||||
"github.com/prysmaticlabs/prysm/crypto/hash"
|
"github.com/prysmaticlabs/prysm/crypto/hash"
|
||||||
@@ -516,7 +518,13 @@ func (s *Service) checkForChainstart(ctx context.Context, blockHash [32]byte, bl
|
|||||||
|
|
||||||
// save all powchain related metadata to disk.
|
// save all powchain related metadata to disk.
|
||||||
func (s *Service) savePowchainData(ctx context.Context) error {
|
func (s *Service) savePowchainData(ctx context.Context) error {
|
||||||
pbState, err := v1.ProtobufBeaconState(s.preGenesisState.InnerStateUnsafe())
|
var pbState *ethpb.BeaconState
|
||||||
|
var err error
|
||||||
|
if features.Get().EnableNativeState {
|
||||||
|
pbState, err = state_native.ProtobufBeaconStatePhase0(s.preGenesisState.InnerStateUnsafe())
|
||||||
|
} else {
|
||||||
|
pbState, err = v1.ProtobufBeaconState(s.preGenesisState.InnerStateUnsafe())
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/powchain/types"
|
"github.com/prysmaticlabs/prysm/beacon-chain/powchain/types"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
nativev1 "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/v1"
|
native "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||||
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
||||||
"github.com/prysmaticlabs/prysm/config/features"
|
"github.com/prysmaticlabs/prysm/config/features"
|
||||||
@@ -273,7 +273,7 @@ func (s *Service) Stop() error {
|
|||||||
func (s *Service) ClearPreGenesisData() {
|
func (s *Service) ClearPreGenesisData() {
|
||||||
s.chainStartData.ChainstartDeposits = []*ethpb.Deposit{}
|
s.chainStartData.ChainstartDeposits = []*ethpb.Deposit{}
|
||||||
if features.Get().EnableNativeState {
|
if features.Get().EnableNativeState {
|
||||||
s.preGenesisState = &nativev1.BeaconState{}
|
s.preGenesisState = &native.BeaconState{}
|
||||||
} else {
|
} else {
|
||||||
s.preGenesisState = &v1.BeaconState{}
|
s.preGenesisState = &v1.BeaconState{}
|
||||||
}
|
}
|
||||||
@@ -830,7 +830,13 @@ func (s *Service) ensureValidPowchainData(ctx context.Context) error {
|
|||||||
return errors.Wrap(err, "unable to retrieve eth1 data")
|
return errors.Wrap(err, "unable to retrieve eth1 data")
|
||||||
}
|
}
|
||||||
if eth1Data == nil || !eth1Data.ChainstartData.Chainstarted || !validateDepositContainers(eth1Data.DepositContainers) {
|
if eth1Data == nil || !eth1Data.ChainstartData.Chainstarted || !validateDepositContainers(eth1Data.DepositContainers) {
|
||||||
pbState, err := v1.ProtobufBeaconState(s.preGenesisState.InnerStateUnsafe())
|
var pbState *ethpb.BeaconState
|
||||||
|
var err error
|
||||||
|
if features.Get().EnableNativeState {
|
||||||
|
pbState, err = native.ProtobufBeaconStatePhase0(s.preGenesisState.InnerStateUnsafe())
|
||||||
|
} else {
|
||||||
|
pbState, err = v1.ProtobufBeaconState(s.preGenesisState.InnerStateUnsafe())
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ go_library(
|
|||||||
visibility = ["//beacon-chain:__subpackages__"],
|
visibility = ["//beacon-chain:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
"//beacon-chain/state/state-native/custom-types:go_default_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",
|
"//beacon-chain/state/stateutil:go_default_library",
|
||||||
"//beacon-chain/state/types:go_default_library",
|
"//beacon-chain/state/types:go_default_library",
|
||||||
"//crypto/hash:go_default_library",
|
"//crypto/hash:go_default_library",
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type FieldTrie struct {
|
|||||||
*sync.RWMutex
|
*sync.RWMutex
|
||||||
reference *stateutil.Reference
|
reference *stateutil.Reference
|
||||||
fieldLayers [][]*[32]byte
|
fieldLayers [][]*[32]byte
|
||||||
field types.FieldIndex
|
field types.BeaconStateField
|
||||||
dataType types.DataType
|
dataType types.DataType
|
||||||
length uint64
|
length uint64
|
||||||
numOfElems int
|
numOfElems int
|
||||||
@@ -25,7 +25,7 @@ type FieldTrie struct {
|
|||||||
// NewFieldTrie is the constructor for the field trie data structure. It creates the corresponding
|
// 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
|
// 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.
|
// 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.BeaconStateField, dataType types.DataType, elements interface{}, length uint64) (*FieldTrie, error) {
|
||||||
if elements == nil {
|
if elements == nil {
|
||||||
return &FieldTrie{
|
return &FieldTrie{
|
||||||
field: field,
|
field: field,
|
||||||
@@ -36,10 +36,19 @@ func NewFieldTrie(field types.FieldIndex, dataType types.DataType, elements inte
|
|||||||
numOfElems: 0,
|
numOfElems: 0,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
fieldRoots, err := fieldConverters(field, []uint64{}, elements, true)
|
|
||||||
|
var fieldRoots [][32]byte
|
||||||
|
var err error
|
||||||
|
if field.Native() {
|
||||||
|
fieldRoots, err = fieldConvertersNative(field, []uint64{}, elements, true)
|
||||||
|
} else {
|
||||||
|
fieldRoots, err = fieldConverters(field, []uint64{}, elements, true)
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := validateElements(field, dataType, elements, length); err != nil {
|
if err := validateElements(field, dataType, elements, length); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -84,10 +93,18 @@ func (f *FieldTrie) RecomputeTrie(indices []uint64, elements interface{}) ([32]b
|
|||||||
if len(indices) == 0 {
|
if len(indices) == 0 {
|
||||||
return f.TrieRoot()
|
return f.TrieRoot()
|
||||||
}
|
}
|
||||||
fieldRoots, err := fieldConverters(f.field, indices, elements, false)
|
|
||||||
|
var fieldRoots [][32]byte
|
||||||
|
var err error
|
||||||
|
if f.field.Native() {
|
||||||
|
fieldRoots, err = fieldConvertersNative(f.field, indices, elements, false)
|
||||||
|
} else {
|
||||||
|
fieldRoots, err = fieldConverters(f.field, indices, elements, false)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return [32]byte{}, err
|
return [32]byte{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := f.validateIndices(indices); err != nil {
|
if err := f.validateIndices(indices); err != nil {
|
||||||
return [32]byte{}, err
|
return [32]byte{}, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types"
|
customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types"
|
||||||
|
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/types"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/types"
|
||||||
"github.com/prysmaticlabs/prysm/crypto/hash"
|
"github.com/prysmaticlabs/prysm/crypto/hash"
|
||||||
@@ -18,7 +19,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// ProofFromMerkleLayers creates a proof starting at the leaf index of the state Merkle layers.
|
// ProofFromMerkleLayers creates a proof starting at the leaf index of the state Merkle layers.
|
||||||
func ProofFromMerkleLayers(layers [][][]byte, startingLeafIndex types.FieldIndex) [][]byte {
|
func ProofFromMerkleLayers(layers [][][]byte, startingLeafIndex int) [][]byte {
|
||||||
// The merkle tree structure looks as follows:
|
// The merkle tree structure looks as follows:
|
||||||
// [[r1, r2, r3, r4], [parent1, parent2], [root]]
|
// [[r1, r2, r3, r4], [parent1, parent2], [root]]
|
||||||
proof := make([][]byte, 0)
|
proof := make([][]byte, 0)
|
||||||
@@ -49,7 +50,7 @@ func (f *FieldTrie) validateIndices(idxs []uint64) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateElements(field types.FieldIndex, dataType types.DataType, elements interface{}, length uint64) error {
|
func validateElements(field types.BeaconStateField, dataType types.DataType, elements interface{}, length uint64) error {
|
||||||
if dataType == types.CompressedArray {
|
if dataType == types.CompressedArray {
|
||||||
comLength, err := field.ElemsInChunk()
|
comLength, err := field.ElemsInChunk()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -65,68 +66,118 @@ func validateElements(field types.FieldIndex, dataType types.DataType, elements
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fieldConverters converts the corresponding field and the provided elements to the appropriate roots.
|
// fieldConverters converts the corresponding field and the provided elements to the appropriate roots.
|
||||||
func fieldConverters(field types.FieldIndex, indices []uint64, elements interface{}, convertAll bool) ([][32]byte, error) {
|
func fieldConverters(field types.BeaconStateField, indices []uint64, elements interface{}, convertAll bool) ([][32]byte, error) {
|
||||||
switch field {
|
switch field {
|
||||||
case types.BlockRoots:
|
case types.BlockRoots:
|
||||||
switch val := elements.(type) {
|
return convertBlockRoots(indices, elements, convertAll)
|
||||||
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")
|
|
||||||
}
|
|
||||||
case types.StateRoots:
|
case types.StateRoots:
|
||||||
switch val := elements.(type) {
|
return convertStateRoots(indices, elements, convertAll)
|
||||||
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")
|
|
||||||
}
|
|
||||||
case types.RandaoMixes:
|
case types.RandaoMixes:
|
||||||
switch val := elements.(type) {
|
return convertRandaoMixes(indices, elements, convertAll)
|
||||||
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")
|
|
||||||
}
|
|
||||||
case types.Eth1DataVotes:
|
case types.Eth1DataVotes:
|
||||||
val, ok := elements.([]*ethpb.Eth1Data)
|
return convertEth1DataVotes(indices, elements, convertAll)
|
||||||
if !ok {
|
|
||||||
return nil, errors.Errorf("Wanted type of %v but got %v",
|
|
||||||
reflect.TypeOf([]*ethpb.Eth1Data{}).Name(), reflect.TypeOf(elements).Name())
|
|
||||||
}
|
|
||||||
return handleEth1DataSlice(val, indices, convertAll)
|
|
||||||
case types.Validators:
|
case types.Validators:
|
||||||
val, ok := elements.([]*ethpb.Validator)
|
return convertValidators(indices, elements, convertAll)
|
||||||
if !ok {
|
|
||||||
return nil, errors.Errorf("Wanted type of %v but got %v",
|
|
||||||
reflect.TypeOf([]*ethpb.Validator{}).Name(), reflect.TypeOf(elements).Name())
|
|
||||||
}
|
|
||||||
return handleValidatorSlice(val, indices, convertAll)
|
|
||||||
case types.PreviousEpochAttestations, types.CurrentEpochAttestations:
|
case types.PreviousEpochAttestations, types.CurrentEpochAttestations:
|
||||||
val, ok := elements.([]*ethpb.PendingAttestation)
|
return convertAttestations(indices, elements, convertAll)
|
||||||
if !ok {
|
|
||||||
return nil, errors.Errorf("Wanted type of %v but got %v",
|
|
||||||
reflect.TypeOf([]*ethpb.PendingAttestation{}).Name(), reflect.TypeOf(elements).Name())
|
|
||||||
}
|
|
||||||
return handlePendingAttestationSlice(val, indices, convertAll)
|
|
||||||
case types.Balances:
|
case types.Balances:
|
||||||
val, ok := elements.([]uint64)
|
return convertBalances(indices, elements, convertAll)
|
||||||
if !ok {
|
|
||||||
return nil, errors.Errorf("Wanted type of %v but got %v",
|
|
||||||
reflect.TypeOf([]uint64{}).Name(), reflect.TypeOf(elements).Name())
|
|
||||||
}
|
|
||||||
return handleBalanceSlice(val, indices, convertAll)
|
|
||||||
default:
|
default:
|
||||||
return [][32]byte{}, errors.Errorf("got unsupported type of %v", reflect.TypeOf(elements).Name())
|
return [][32]byte{}, errors.Errorf("got unsupported type of %v", reflect.TypeOf(elements).Name())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fieldConvertersNative converts the corresponding field and the provided elements to the appropriate roots.
|
||||||
|
func fieldConvertersNative(field types.BeaconStateField, indices []uint64, elements interface{}, convertAll bool) ([][32]byte, error) {
|
||||||
|
switch field {
|
||||||
|
case nativetypes.BlockRoots:
|
||||||
|
return convertBlockRoots(indices, elements, convertAll)
|
||||||
|
case nativetypes.StateRoots:
|
||||||
|
return convertStateRoots(indices, elements, convertAll)
|
||||||
|
case nativetypes.RandaoMixes:
|
||||||
|
return convertRandaoMixes(indices, elements, convertAll)
|
||||||
|
case nativetypes.Eth1DataVotes:
|
||||||
|
return convertEth1DataVotes(indices, elements, convertAll)
|
||||||
|
case nativetypes.Validators:
|
||||||
|
return convertValidators(indices, elements, convertAll)
|
||||||
|
case nativetypes.PreviousEpochAttestations, nativetypes.CurrentEpochAttestations:
|
||||||
|
return convertAttestations(indices, elements, convertAll)
|
||||||
|
case nativetypes.Balances:
|
||||||
|
return convertBalances(indices, elements, convertAll)
|
||||||
|
default:
|
||||||
|
return [][32]byte{}, errors.Errorf("got unsupported type of %v", reflect.TypeOf(elements).Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 convertEth1DataVotes(indices []uint64, elements interface{}, convertAll bool) ([][32]byte, error) {
|
||||||
|
val, ok := elements.([]*ethpb.Eth1Data)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.Errorf("Wanted type of %v but got %v",
|
||||||
|
reflect.TypeOf([]*ethpb.Eth1Data{}).Name(), reflect.TypeOf(elements).Name())
|
||||||
|
}
|
||||||
|
return handleEth1DataSlice(val, indices, convertAll)
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertValidators(indices []uint64, elements interface{}, convertAll bool) ([][32]byte, error) {
|
||||||
|
val, ok := elements.([]*ethpb.Validator)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.Errorf("Wanted type of %v but got %v",
|
||||||
|
reflect.TypeOf([]*ethpb.Validator{}).Name(), reflect.TypeOf(elements).Name())
|
||||||
|
}
|
||||||
|
return handleValidatorSlice(val, indices, convertAll)
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertAttestations(indices []uint64, elements interface{}, convertAll bool) ([][32]byte, error) {
|
||||||
|
val, ok := elements.([]*ethpb.PendingAttestation)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.Errorf("Wanted type of %v but got %v",
|
||||||
|
reflect.TypeOf([]*ethpb.PendingAttestation{}).Name(), reflect.TypeOf(elements).Name())
|
||||||
|
}
|
||||||
|
return handlePendingAttestationSlice(val, indices, convertAll)
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertBalances(indices []uint64, elements interface{}, convertAll bool) ([][32]byte, error) {
|
||||||
|
val, ok := elements.([]uint64)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.Errorf("Wanted type of %v but got %v",
|
||||||
|
reflect.TypeOf([]uint64{}).Name(), reflect.TypeOf(elements).Name())
|
||||||
|
}
|
||||||
|
return handleBalanceSlice(val, indices, convertAll)
|
||||||
|
}
|
||||||
|
|
||||||
// handleByteArrays computes and returns byte arrays in a slice of root format.
|
// handleByteArrays computes and returns byte arrays in a slice of root format.
|
||||||
func handleByteArrays(val [][]byte, indices []uint64, convertAll bool) ([][32]byte, error) {
|
func handleByteArrays(val [][]byte, indices []uint64, convertAll bool) ([][32]byte, error) {
|
||||||
length := len(indices)
|
length := len(indices)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ func TestFieldTrie_NewTrie(t *testing.T) {
|
|||||||
newState, _ := util.DeterministicGenesisState(t, 40)
|
newState, _ := util.DeterministicGenesisState(t, 40)
|
||||||
|
|
||||||
// 5 represents the enum value of state roots
|
// 5 represents the enum value of state roots
|
||||||
trie, err := fieldtrie.NewFieldTrie(5, stateTypes.BasicArray, newState.StateRoots(), uint64(params.BeaconConfig().SlotsPerHistoricalRoot))
|
trie, err := fieldtrie.NewFieldTrie(stateTypes.FieldIndex(5), stateTypes.BasicArray, newState.StateRoots(), uint64(params.BeaconConfig().SlotsPerHistoricalRoot))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
root, err := stateutil.RootsArrayHashTreeRoot(newState.StateRoots(), uint64(params.BeaconConfig().SlotsPerHistoricalRoot))
|
root, err := stateutil.RootsArrayHashTreeRoot(newState.StateRoots(), uint64(params.BeaconConfig().SlotsPerHistoricalRoot))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -30,7 +30,7 @@ func TestFieldTrie_NewTrie(t *testing.T) {
|
|||||||
func TestFieldTrie_RecomputeTrie(t *testing.T) {
|
func TestFieldTrie_RecomputeTrie(t *testing.T) {
|
||||||
newState, _ := util.DeterministicGenesisState(t, 32)
|
newState, _ := util.DeterministicGenesisState(t, 32)
|
||||||
// 10 represents the enum value of validators
|
// 10 represents the enum value of validators
|
||||||
trie, err := fieldtrie.NewFieldTrie(11, stateTypes.CompositeArray, newState.Validators(), params.BeaconConfig().ValidatorRegistryLimit)
|
trie, err := fieldtrie.NewFieldTrie(stateTypes.FieldIndex(11), stateTypes.CompositeArray, newState.Validators(), params.BeaconConfig().ValidatorRegistryLimit)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
changedIdx := []uint64{2, 29}
|
changedIdx := []uint64{2, 29}
|
||||||
@@ -58,7 +58,7 @@ func TestFieldTrie_RecomputeTrie(t *testing.T) {
|
|||||||
func TestFieldTrie_CopyTrieImmutable(t *testing.T) {
|
func TestFieldTrie_CopyTrieImmutable(t *testing.T) {
|
||||||
newState, _ := util.DeterministicGenesisState(t, 32)
|
newState, _ := util.DeterministicGenesisState(t, 32)
|
||||||
// 12 represents the enum value of randao mixes.
|
// 12 represents the enum value of randao mixes.
|
||||||
trie, err := fieldtrie.NewFieldTrie(13, stateTypes.BasicArray, newState.RandaoMixes(), uint64(params.BeaconConfig().EpochsPerHistoricalVector))
|
trie, err := fieldtrie.NewFieldTrie(stateTypes.FieldIndex(13), stateTypes.BasicArray, newState.RandaoMixes(), uint64(params.BeaconConfig().EpochsPerHistoricalVector))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
newTrie := trie.CopyTrie()
|
newTrie := trie.CopyTrie()
|
||||||
|
|||||||
@@ -1,20 +1,21 @@
|
|||||||
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||||
load("//proto:ssz_proto_library.bzl", "ssz_proto_files")
|
|
||||||
load("//tools:ssz.bzl", "SSZ_DEPS", "ssz_gen_marshal")
|
|
||||||
|
|
||||||
go_library(
|
go_library(
|
||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = [
|
srcs = [
|
||||||
"doc.go",
|
"doc.go",
|
||||||
"field_roots.go",
|
|
||||||
"getters_attestation.go",
|
"getters_attestation.go",
|
||||||
"getters_block.go",
|
"getters_block.go",
|
||||||
"getters_checkpoint.go",
|
"getters_checkpoint.go",
|
||||||
"getters_eth1.go",
|
"getters_eth1.go",
|
||||||
"getters_misc.go",
|
"getters_misc.go",
|
||||||
|
"getters_participation.go",
|
||||||
|
"getters_payload_header.go",
|
||||||
"getters_randao.go",
|
"getters_randao.go",
|
||||||
"getters_state.go",
|
"getters_state.go",
|
||||||
|
"getters_sync_committee.go",
|
||||||
"getters_validator.go",
|
"getters_validator.go",
|
||||||
|
"hasher.go",
|
||||||
"proofs.go",
|
"proofs.go",
|
||||||
"readonly_validator.go",
|
"readonly_validator.go",
|
||||||
"setters_attestation.go",
|
"setters_attestation.go",
|
||||||
@@ -22,19 +23,20 @@ go_library(
|
|||||||
"setters_checkpoint.go",
|
"setters_checkpoint.go",
|
||||||
"setters_eth1.go",
|
"setters_eth1.go",
|
||||||
"setters_misc.go",
|
"setters_misc.go",
|
||||||
|
"setters_participation.go",
|
||||||
|
"setters_payload_header.go",
|
||||||
"setters_randao.go",
|
"setters_randao.go",
|
||||||
"setters_state.go",
|
"setters_state.go",
|
||||||
|
"setters_sync_committee.go",
|
||||||
"setters_validator.go",
|
"setters_validator.go",
|
||||||
|
"ssz.go",
|
||||||
"state_trie.go",
|
"state_trie.go",
|
||||||
"types.go",
|
"types.go",
|
||||||
"unsupported_getters.go",
|
|
||||||
"unsupported_setters.go",
|
|
||||||
":ssz_generated_files", # keep
|
|
||||||
] + select({
|
] + select({
|
||||||
"//config:mainnet": ["beacon_state_mainnet.go"],
|
"//config:mainnet": ["beacon_state_mainnet.go"],
|
||||||
"//config:minimal": ["beacon_state_minimal.go"],
|
"//config:minimal": ["beacon_state_minimal.go"],
|
||||||
}),
|
}),
|
||||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/v1",
|
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native",
|
||||||
visibility = [
|
visibility = [
|
||||||
"//beacon-chain:__subpackages__",
|
"//beacon-chain:__subpackages__",
|
||||||
"//contracts/deposit:__subpackages__",
|
"//contracts/deposit:__subpackages__",
|
||||||
@@ -54,6 +56,7 @@ go_library(
|
|||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
"//beacon-chain/state/fieldtrie:go_default_library",
|
"//beacon-chain/state/fieldtrie:go_default_library",
|
||||||
"//beacon-chain/state/state-native/custom-types:go_default_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",
|
"//beacon-chain/state/stateutil:go_default_library",
|
||||||
"//beacon-chain/state/types:go_default_library",
|
"//beacon-chain/state/types:go_default_library",
|
||||||
"//config/fieldparams:go_default_library",
|
"//config/fieldparams:go_default_library",
|
||||||
@@ -65,7 +68,6 @@ go_library(
|
|||||||
"//encoding/ssz:go_default_library",
|
"//encoding/ssz:go_default_library",
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
"//proto/prysm/v1alpha1:go_default_library",
|
||||||
"//runtime/version:go_default_library",
|
"//runtime/version:go_default_library",
|
||||||
"@com_github_ferranbt_fastssz//:go_default_library",
|
|
||||||
"@com_github_pkg_errors//:go_default_library",
|
"@com_github_pkg_errors//:go_default_library",
|
||||||
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
||||||
"@io_opencensus_go//trace:go_default_library",
|
"@io_opencensus_go//trace:go_default_library",
|
||||||
@@ -73,14 +75,15 @@ go_library(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
# gazelle:exclude types_bench_test.go
|
|
||||||
go_test(
|
go_test(
|
||||||
name = "go_default_test",
|
name = "go_default_test",
|
||||||
srcs = [
|
srcs = [
|
||||||
"getters_attestation_test.go",
|
"getters_attestation_test.go",
|
||||||
"getters_block_test.go",
|
"getters_block_test.go",
|
||||||
|
"getters_checkpoint_test.go",
|
||||||
"getters_test.go",
|
"getters_test.go",
|
||||||
"getters_validator_test.go",
|
"getters_validator_test.go",
|
||||||
|
"hasher_test.go",
|
||||||
"proofs_test.go",
|
"proofs_test.go",
|
||||||
"readonly_validator_test.go",
|
"readonly_validator_test.go",
|
||||||
"references_test.go",
|
"references_test.go",
|
||||||
@@ -95,9 +98,12 @@ go_test(
|
|||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
"//beacon-chain/state:go_default_library",
|
"//beacon-chain/state:go_default_library",
|
||||||
|
"//beacon-chain/state/state-native/types:go_default_library",
|
||||||
"//beacon-chain/state/stateutil:go_default_library",
|
"//beacon-chain/state/stateutil:go_default_library",
|
||||||
"//beacon-chain/state/testing:go_default_library",
|
"//beacon-chain/state/testing:go_default_library",
|
||||||
"//beacon-chain/state/types:go_default_library",
|
"//beacon-chain/state/v1:go_default_library",
|
||||||
|
"//beacon-chain/state/v2:go_default_library",
|
||||||
|
"//beacon-chain/state/v3:go_default_library",
|
||||||
"//config/fieldparams:go_default_library",
|
"//config/fieldparams:go_default_library",
|
||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
"//consensus-types/primitives:go_default_library",
|
"//consensus-types/primitives:go_default_library",
|
||||||
@@ -113,20 +119,3 @@ go_test(
|
|||||||
"@org_golang_google_protobuf//proto:go_default_library",
|
"@org_golang_google_protobuf//proto:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
ssz_gen_marshal(
|
|
||||||
name = "ssz_generated_files",
|
|
||||||
srcs = select({
|
|
||||||
"//config:mainnet": ["beacon_state_mainnet.go"],
|
|
||||||
"//config:minimal": ["beacon_state_minimal.go"],
|
|
||||||
}),
|
|
||||||
includes = [
|
|
||||||
"//beacon-chain/state/state-native/custom-types:go_default_library",
|
|
||||||
"//config/fieldparams:go_default_library",
|
|
||||||
"//consensus-types/primitives:go_default_library",
|
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
|
||||||
],
|
|
||||||
objs = [
|
|
||||||
"BeaconState[no-htr]",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
//go:build !minimal
|
//go:build !minimal
|
||||||
// +build !minimal
|
// +build !minimal
|
||||||
|
|
||||||
package v3
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
@@ -9,15 +9,16 @@ import (
|
|||||||
"github.com/prysmaticlabs/go-bitfield"
|
"github.com/prysmaticlabs/go-bitfield"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/fieldtrie"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/fieldtrie"
|
||||||
customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types"
|
customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types"
|
||||||
|
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/types"
|
|
||||||
eth2types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
eth2types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BeaconState defines a struct containing utilities for the eth2 chain state, defining
|
// BeaconState defines a struct containing utilities for the Ethereum Beacon Chain state, defining
|
||||||
// getters and setters for its respective values and helpful functions such as HashTreeRoot().
|
// getters and setters for its respective values and helpful functions such as HashTreeRoot().
|
||||||
type BeaconState struct {
|
type BeaconState struct {
|
||||||
|
version int
|
||||||
genesisTime uint64 `ssz-gen:"true"`
|
genesisTime uint64 `ssz-gen:"true"`
|
||||||
genesisValidatorsRoot customtypes.Byte32 `ssz-gen:"true" ssz-size:"32"`
|
genesisValidatorsRoot customtypes.Byte32 `ssz-gen:"true" ssz-size:"32"`
|
||||||
slot eth2types.Slot `ssz-gen:"true"`
|
slot eth2types.Slot `ssz-gen:"true"`
|
||||||
@@ -33,6 +34,8 @@ type BeaconState struct {
|
|||||||
balances []uint64 `ssz-gen:"true" ssz-max:"1099511627776"`
|
balances []uint64 `ssz-gen:"true" ssz-max:"1099511627776"`
|
||||||
randaoMixes *customtypes.RandaoMixes `ssz-gen:"true" ssz-size:"65536,32"`
|
randaoMixes *customtypes.RandaoMixes `ssz-gen:"true" ssz-size:"65536,32"`
|
||||||
slashings []uint64 `ssz-gen:"true" ssz-size:"8192"`
|
slashings []uint64 `ssz-gen:"true" ssz-size:"8192"`
|
||||||
|
previousEpochAttestations []*ethpb.PendingAttestation `ssz-gen:"true" ssz-max:"4096"`
|
||||||
|
currentEpochAttestations []*ethpb.PendingAttestation `ssz-gen:"true" ssz-max:"4096"`
|
||||||
previousEpochParticipation []byte `ssz-gen:"true" ssz-max:"1099511627776"`
|
previousEpochParticipation []byte `ssz-gen:"true" ssz-max:"1099511627776"`
|
||||||
currentEpochParticipation []byte `ssz-gen:"true" ssz-max:"1099511627776"`
|
currentEpochParticipation []byte `ssz-gen:"true" ssz-max:"1099511627776"`
|
||||||
justificationBits bitfield.Bitvector4 `ssz-gen:"true" ssz-size:"1"`
|
justificationBits bitfield.Bitvector4 `ssz-gen:"true" ssz-size:"1"`
|
||||||
@@ -45,11 +48,11 @@ type BeaconState struct {
|
|||||||
latestExecutionPayloadHeader *ethpb.ExecutionPayloadHeader `ssz-gen:"true"`
|
latestExecutionPayloadHeader *ethpb.ExecutionPayloadHeader `ssz-gen:"true"`
|
||||||
|
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
dirtyFields map[types.FieldIndex]bool
|
dirtyFields map[nativetypes.FieldIndex]bool
|
||||||
dirtyIndices map[types.FieldIndex][]uint64
|
dirtyIndices map[nativetypes.FieldIndex][]uint64
|
||||||
stateFieldLeaves map[types.FieldIndex]*fieldtrie.FieldTrie
|
stateFieldLeaves map[nativetypes.FieldIndex]*fieldtrie.FieldTrie
|
||||||
rebuildTrie map[types.FieldIndex]bool
|
rebuildTrie map[nativetypes.FieldIndex]bool
|
||||||
valMapHandler *stateutil.ValidatorMapHandler
|
valMapHandler *stateutil.ValidatorMapHandler
|
||||||
merkleLayers [][][]byte
|
merkleLayers [][][]byte
|
||||||
sharedFieldReferences map[types.FieldIndex]*stateutil.Reference
|
sharedFieldReferences map[nativetypes.FieldIndex]*stateutil.Reference
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
//go:build !minimal
|
//go:build !minimal
|
||||||
// +build !minimal
|
// +build !minimal
|
||||||
|
|
||||||
package v1
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
)
|
)
|
||||||
@@ -79,4 +80,9 @@ func TestMainnetSszValuesAgainstFieldParams(t *testing.T) {
|
|||||||
require.Equal(t, true, ok, "Required field not found")
|
require.Equal(t, true, ok, "Required field not found")
|
||||||
v = f.Tag.Get("ssz-size")
|
v = f.Tag.Get("ssz-size")
|
||||||
assert.Equal(t, "1", v)
|
assert.Equal(t, "1", v)
|
||||||
|
|
||||||
|
f, ok = bsType.FieldByName("inactivityScores")
|
||||||
|
require.Equal(t, true, ok, "Required field not found")
|
||||||
|
v = f.Tag.Get("ssz-max")
|
||||||
|
assert.Equal(t, strconv.Itoa(fieldparams.ValidatorRegistryLimit), v)
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
//go:build minimal
|
//go:build minimal
|
||||||
// +build minimal
|
// +build minimal
|
||||||
|
|
||||||
package v3
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
@@ -9,15 +9,16 @@ import (
|
|||||||
"github.com/prysmaticlabs/go-bitfield"
|
"github.com/prysmaticlabs/go-bitfield"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/fieldtrie"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/fieldtrie"
|
||||||
customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types"
|
customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types"
|
||||||
|
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/types"
|
|
||||||
eth2types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
eth2types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BeaconState defines a struct containing utilities for the eth2 chain state, defining
|
// BeaconState defines a struct containing utilities for the Ethereum Beacon Chain state, defining
|
||||||
// getters and setters for its respective values and helpful functions such as HashTreeRoot().
|
// getters and setters for its respective values and helpful functions such as HashTreeRoot().
|
||||||
type BeaconState struct {
|
type BeaconState struct {
|
||||||
|
version int
|
||||||
genesisTime uint64 `ssz-gen:"true"`
|
genesisTime uint64 `ssz-gen:"true"`
|
||||||
genesisValidatorsRoot customtypes.Byte32 `ssz-gen:"true" ssz-size:"32"`
|
genesisValidatorsRoot customtypes.Byte32 `ssz-gen:"true" ssz-size:"32"`
|
||||||
slot eth2types.Slot `ssz-gen:"true"`
|
slot eth2types.Slot `ssz-gen:"true"`
|
||||||
@@ -33,6 +34,8 @@ type BeaconState struct {
|
|||||||
balances []uint64 `ssz-gen:"true" ssz-max:"1099511627776"`
|
balances []uint64 `ssz-gen:"true" ssz-max:"1099511627776"`
|
||||||
randaoMixes *customtypes.RandaoMixes `ssz-gen:"true" ssz-size:"64,32"`
|
randaoMixes *customtypes.RandaoMixes `ssz-gen:"true" ssz-size:"64,32"`
|
||||||
slashings []uint64 `ssz-gen:"true" ssz-size:"64"`
|
slashings []uint64 `ssz-gen:"true" ssz-size:"64"`
|
||||||
|
previousEpochAttestations []*ethpb.PendingAttestation `ssz-gen:"true" ssz-max:"1024"`
|
||||||
|
currentEpochAttestations []*ethpb.PendingAttestation `ssz-gen:"true" ssz-max:"1024"`
|
||||||
previousEpochParticipation []byte `ssz-gen:"true" ssz-max:"1099511627776"`
|
previousEpochParticipation []byte `ssz-gen:"true" ssz-max:"1099511627776"`
|
||||||
currentEpochParticipation []byte `ssz-gen:"true" ssz-max:"1099511627776"`
|
currentEpochParticipation []byte `ssz-gen:"true" ssz-max:"1099511627776"`
|
||||||
justificationBits bitfield.Bitvector4 `ssz-gen:"true" ssz-size:"1"`
|
justificationBits bitfield.Bitvector4 `ssz-gen:"true" ssz-size:"1"`
|
||||||
@@ -45,11 +48,11 @@ type BeaconState struct {
|
|||||||
latestExecutionPayloadHeader *ethpb.ExecutionPayloadHeader `ssz-gen:"true"`
|
latestExecutionPayloadHeader *ethpb.ExecutionPayloadHeader `ssz-gen:"true"`
|
||||||
|
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
dirtyFields map[types.FieldIndex]bool
|
dirtyFields map[nativetypes.FieldIndex]bool
|
||||||
dirtyIndices map[types.FieldIndex][]uint64
|
dirtyIndices map[nativetypes.FieldIndex][]uint64
|
||||||
stateFieldLeaves map[types.FieldIndex]*fieldtrie.FieldTrie
|
stateFieldLeaves map[nativetypes.FieldIndex]*fieldtrie.FieldTrie
|
||||||
rebuildTrie map[types.FieldIndex]bool
|
rebuildTrie map[nativetypes.FieldIndex]bool
|
||||||
valMapHandler *stateutil.ValidatorMapHandler
|
valMapHandler *stateutil.ValidatorMapHandler
|
||||||
merkleLayers [][][]byte
|
merkleLayers [][][]byte
|
||||||
sharedFieldReferences map[types.FieldIndex]*stateutil.Reference
|
sharedFieldReferences map[nativetypes.FieldIndex]*stateutil.Reference
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
//go:build minimal
|
//go:build minimal
|
||||||
// +build minimal
|
// +build minimal
|
||||||
|
|
||||||
package v1
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
@@ -79,4 +79,9 @@ func TestMinimalSszValuesAgainstFieldParams(t *testing.T) {
|
|||||||
require.Equal(t, true, ok, "Required field not found")
|
require.Equal(t, true, ok, "Required field not found")
|
||||||
v = f.Tag.Get("ssz-size")
|
v = f.Tag.Get("ssz-size")
|
||||||
assert.Equal(t, "1", v)
|
assert.Equal(t, "1", v)
|
||||||
|
|
||||||
|
f, ok = bsType.FieldByName("inactivityScores")
|
||||||
|
require.Equal(t, true, ok, "Required field not found")
|
||||||
|
v = f.Tag.Get("ssz-max")
|
||||||
|
assert.Equal(t, strconv.Itoa(fieldparams.ValidatorRegistryLimit), v)
|
||||||
}
|
}
|
||||||
@@ -1,22 +1,15 @@
|
|||||||
// Package v1 defines how the beacon chain state for Ethereum
|
// Package state_native defines how the beacon chain state for Ethereum
|
||||||
// functions in the running beacon node, using an advanced,
|
// functions in the running beacon node, using an advanced,
|
||||||
// immutable implementation of the state data structure.
|
// immutable implementation of the state data structure.
|
||||||
//
|
//
|
||||||
// BeaconState getters may be accessed from inside or outside the package. To
|
// BeaconState getters may be accessed from inside or outside the package. To
|
||||||
// avoid duplicating locks, we have internal and external versions of the
|
// avoid duplicating locks, we have internal and external versions of the
|
||||||
// getter The external function carries out the short-circuit conditions,
|
// getter. The external function obtains a read lock, then calls the internal function.
|
||||||
// obtains a read lock, then calls the internal function. The internal function
|
// The internal function returns the required data without further locking,
|
||||||
// carries out the short-circuit conditions and returns the required data
|
// allowing it to be used by other package-level functions that already hold a lock.
|
||||||
// without further locking, allowing it to be used by other package-level
|
// Hence the functions look something like this:
|
||||||
// functions that already hold a lock. Hence the functions look something
|
|
||||||
// like this:
|
|
||||||
//
|
//
|
||||||
// func (b *BeaconState) Foo() uint64 {
|
// func (b *BeaconState) Foo() uint64 {
|
||||||
// // Short-circuit conditions.
|
|
||||||
// if !b.hasInnerState() {
|
|
||||||
// return 0
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Read lock.
|
// // Read lock.
|
||||||
// b.lock.RLock()
|
// b.lock.RLock()
|
||||||
// defer b.lock.RUnlock()
|
// defer b.lock.RUnlock()
|
||||||
@@ -26,15 +19,12 @@
|
|||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// func (b *BeaconState) foo() uint64 {
|
// func (b *BeaconState) foo() uint64 {
|
||||||
// // Short-circuit conditions.
|
// (...) // Some processing logic.
|
||||||
// if !b.hasInnerState() {
|
|
||||||
// return 0
|
|
||||||
// }
|
|
||||||
//
|
//
|
||||||
// return b.state.foo
|
// return b.foo
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// Although it is technically possible to remove the short-circuit conditions
|
// Although it is technically possible to remove the short-circuit conditions
|
||||||
// from the external function, that would require every read to obtain a lock
|
// from the external function, that would require every read to obtain a lock
|
||||||
// even if the data was not present, leading to potential slowdowns.
|
// even if the data was not present, leading to potential slowdowns.
|
||||||
package v1
|
package state_native
|
||||||
@@ -1,11 +1,16 @@
|
|||||||
package v1
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PreviousEpochAttestations corresponding to blocks on the beacon chain.
|
// PreviousEpochAttestations corresponding to blocks on the beacon chain.
|
||||||
func (b *BeaconState) PreviousEpochAttestations() ([]*ethpb.PendingAttestation, error) {
|
func (b *BeaconState) PreviousEpochAttestations() ([]*ethpb.PendingAttestation, error) {
|
||||||
|
if b.version != version.Phase0 {
|
||||||
|
return nil, errNotSupported("PreviousEpochAttestations", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
if b.previousEpochAttestations == nil {
|
if b.previousEpochAttestations == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -24,6 +29,10 @@ func (b *BeaconState) previousEpochAttestationsVal() []*ethpb.PendingAttestation
|
|||||||
|
|
||||||
// CurrentEpochAttestations corresponding to blocks on the beacon chain.
|
// CurrentEpochAttestations corresponding to blocks on the beacon chain.
|
||||||
func (b *BeaconState) CurrentEpochAttestations() ([]*ethpb.PendingAttestation, error) {
|
func (b *BeaconState) CurrentEpochAttestations() ([]*ethpb.PendingAttestation, error) {
|
||||||
|
if b.version != version.Phase0 {
|
||||||
|
return nil, errNotSupported("CurrentEpochAttestations", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
if b.currentEpochAttestations == nil {
|
if b.currentEpochAttestations == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package v1
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
@@ -8,14 +8,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestBeaconState_PreviousEpochAttestations(t *testing.T) {
|
func TestBeaconState_PreviousEpochAttestations(t *testing.T) {
|
||||||
s, err := InitializeFromProto(ðpb.BeaconState{})
|
s, err := InitializeFromProtoPhase0(ðpb.BeaconState{})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
atts, err := s.PreviousEpochAttestations()
|
atts, err := s.PreviousEpochAttestations()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.DeepEqual(t, []*ethpb.PendingAttestation(nil), atts)
|
require.DeepEqual(t, []*ethpb.PendingAttestation(nil), atts)
|
||||||
|
|
||||||
want := []*ethpb.PendingAttestation{{ProposerIndex: 100}}
|
want := []*ethpb.PendingAttestation{{ProposerIndex: 100}}
|
||||||
s, err = InitializeFromProto(ðpb.BeaconState{PreviousEpochAttestations: want})
|
s, err = InitializeFromProtoPhase0(ðpb.BeaconState{PreviousEpochAttestations: want})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
got, err := s.PreviousEpochAttestations()
|
got, err := s.PreviousEpochAttestations()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -27,14 +27,14 @@ func TestBeaconState_PreviousEpochAttestations(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestBeaconState_CurrentEpochAttestations(t *testing.T) {
|
func TestBeaconState_CurrentEpochAttestations(t *testing.T) {
|
||||||
s, err := InitializeFromProto(ðpb.BeaconState{})
|
s, err := InitializeFromProtoPhase0(ðpb.BeaconState{})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
atts, err := s.CurrentEpochAttestations()
|
atts, err := s.CurrentEpochAttestations()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.DeepEqual(t, []*ethpb.PendingAttestation(nil), atts)
|
require.DeepEqual(t, []*ethpb.PendingAttestation(nil), atts)
|
||||||
|
|
||||||
want := []*ethpb.PendingAttestation{{ProposerIndex: 101}}
|
want := []*ethpb.PendingAttestation{{ProposerIndex: 101}}
|
||||||
s, err = InitializeFromProto(ðpb.BeaconState{CurrentEpochAttestations: want})
|
s, err = InitializeFromProtoPhase0(ðpb.BeaconState{CurrentEpochAttestations: want})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
got, err := s.CurrentEpochAttestations()
|
got, err := s.CurrentEpochAttestations()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package v1
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
117
beacon-chain/state/state-native/getters_block_test.go
Normal file
117
beacon-chain/state/state-native/getters_block_test.go
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
package state_native
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
|
testtmpl "github.com/prysmaticlabs/prysm/beacon-chain/state/testing"
|
||||||
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBeaconState_LatestBlockHeader_Phase0(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateLatestBlockHeader(
|
||||||
|
t,
|
||||||
|
func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoPhase0(ðpb.BeaconState{})
|
||||||
|
},
|
||||||
|
func(BH *ethpb.BeaconBlockHeader) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoPhase0(ðpb.BeaconState{LatestBlockHeader: BH})
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_LatestBlockHeader_Altair(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateLatestBlockHeader(
|
||||||
|
t,
|
||||||
|
func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoAltair(ðpb.BeaconStateAltair{})
|
||||||
|
},
|
||||||
|
func(BH *ethpb.BeaconBlockHeader) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoAltair(ðpb.BeaconStateAltair{LatestBlockHeader: BH})
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_LatestBlockHeader_Bellatrix(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateLatestBlockHeader(
|
||||||
|
t,
|
||||||
|
func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoBellatrix(ðpb.BeaconStateBellatrix{})
|
||||||
|
},
|
||||||
|
func(BH *ethpb.BeaconBlockHeader) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoBellatrix(ðpb.BeaconStateBellatrix{LatestBlockHeader: BH})
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_BlockRoots_Phase0(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateBlockRootsNative(
|
||||||
|
t,
|
||||||
|
func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoPhase0(ðpb.BeaconState{})
|
||||||
|
},
|
||||||
|
func(BR [][]byte) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoPhase0(ðpb.BeaconState{BlockRoots: BR})
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_BlockRoots_Altair(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateBlockRootsNative(
|
||||||
|
t,
|
||||||
|
func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoAltair(ðpb.BeaconStateAltair{})
|
||||||
|
},
|
||||||
|
func(BR [][]byte) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoAltair(ðpb.BeaconStateAltair{BlockRoots: BR})
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_BlockRoots_Bellatrix(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateBlockRootsNative(
|
||||||
|
t,
|
||||||
|
func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoBellatrix(ðpb.BeaconStateBellatrix{})
|
||||||
|
},
|
||||||
|
func(BR [][]byte) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoBellatrix(ðpb.BeaconStateBellatrix{BlockRoots: BR})
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_BlockRootAtIndex_Phase0(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateBlockRootAtIndexNative(
|
||||||
|
t,
|
||||||
|
func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoPhase0(ðpb.BeaconState{})
|
||||||
|
},
|
||||||
|
func(BR [][]byte) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoPhase0(ðpb.BeaconState{BlockRoots: BR})
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_BlockRootAtIndex_Altair(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateBlockRootAtIndexNative(
|
||||||
|
t,
|
||||||
|
func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoAltair(ðpb.BeaconStateAltair{})
|
||||||
|
},
|
||||||
|
func(BR [][]byte) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoAltair(ðpb.BeaconStateAltair{BlockRoots: BR})
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_BlockRootAtIndex_Bellatrix(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateBlockRootAtIndexNative(
|
||||||
|
t,
|
||||||
|
func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoBellatrix(ðpb.BeaconStateBellatrix{})
|
||||||
|
},
|
||||||
|
func(BR [][]byte) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoBellatrix(ðpb.BeaconStateBellatrix{BlockRoots: BR})
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package v3
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
202
beacon-chain/state/state-native/getters_checkpoint_test.go
Normal file
202
beacon-chain/state/state-native/getters_checkpoint_test.go
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
package state_native
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/prysmaticlabs/go-bitfield"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
|
testtmpl "github.com/prysmaticlabs/prysm/beacon-chain/state/testing"
|
||||||
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBeaconState_PreviousJustifiedCheckpointNil_Phase0(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStatePreviousJustifiedCheckpointNil(
|
||||||
|
t,
|
||||||
|
func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafePhase0(ðpb.BeaconState{})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_PreviousJustifiedCheckpointNil_Altair(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStatePreviousJustifiedCheckpointNil(
|
||||||
|
t,
|
||||||
|
func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafeAltair(ðpb.BeaconStateAltair{})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_PreviousJustifiedCheckpointNil_Bellatrix(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStatePreviousJustifiedCheckpointNil(
|
||||||
|
t,
|
||||||
|
func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafeBellatrix(ðpb.BeaconStateBellatrix{})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_PreviousJustifiedCheckpoint_Phase0(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStatePreviousJustifiedCheckpoint(
|
||||||
|
t,
|
||||||
|
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafePhase0(ðpb.BeaconState{PreviousJustifiedCheckpoint: cp})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_PreviousJustifiedCheckpoint_Altair(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStatePreviousJustifiedCheckpoint(
|
||||||
|
t,
|
||||||
|
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafeAltair(ðpb.BeaconStateAltair{PreviousJustifiedCheckpoint: cp})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_PreviousJustifiedCheckpoint_Bellatrix(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStatePreviousJustifiedCheckpoint(
|
||||||
|
t,
|
||||||
|
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafeBellatrix(ðpb.BeaconStateBellatrix{PreviousJustifiedCheckpoint: cp})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_CurrentJustifiedCheckpointNil_Phase0(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateCurrentJustifiedCheckpointNil(
|
||||||
|
t,
|
||||||
|
func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafePhase0(ðpb.BeaconState{})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_CurrentJustifiedCheckpointNil_Altair(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateCurrentJustifiedCheckpointNil(
|
||||||
|
t,
|
||||||
|
func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafeAltair(ðpb.BeaconStateAltair{})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_CurrentJustifiedCheckpointNil_Bellatrix(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateCurrentJustifiedCheckpointNil(
|
||||||
|
t,
|
||||||
|
func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafeBellatrix(ðpb.BeaconStateBellatrix{})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_CurrentJustifiedCheckpoint_Phase0(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateCurrentJustifiedCheckpoint(
|
||||||
|
t,
|
||||||
|
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafePhase0(ðpb.BeaconState{CurrentJustifiedCheckpoint: cp})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_CurrentJustifiedCheckpoint_Altair(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateCurrentJustifiedCheckpoint(
|
||||||
|
t,
|
||||||
|
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafeAltair(ðpb.BeaconStateAltair{CurrentJustifiedCheckpoint: cp})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_CurrentJustifiedCheckpoint_Bellatrix(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateCurrentJustifiedCheckpoint(
|
||||||
|
t,
|
||||||
|
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafeBellatrix(ðpb.BeaconStateBellatrix{CurrentJustifiedCheckpoint: cp})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_FinalizedCheckpointNil_Phase0(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateFinalizedCheckpointNil(
|
||||||
|
t,
|
||||||
|
func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafePhase0(ðpb.BeaconState{})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_FinalizedCheckpointNil_Altair(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateFinalizedCheckpointNil(
|
||||||
|
t,
|
||||||
|
func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafeAltair(ðpb.BeaconStateAltair{})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_FinalizedCheckpointNil_Bellatrix(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateFinalizedCheckpointNil(
|
||||||
|
t,
|
||||||
|
func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafeBellatrix(ðpb.BeaconStateBellatrix{})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_FinalizedCheckpoint_Phase0(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateFinalizedCheckpoint(
|
||||||
|
t,
|
||||||
|
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafePhase0(ðpb.BeaconState{FinalizedCheckpoint: cp})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_FinalizedCheckpoint_Altair(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateFinalizedCheckpoint(
|
||||||
|
t,
|
||||||
|
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafeAltair(ðpb.BeaconStateAltair{FinalizedCheckpoint: cp})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_FinalizedCheckpoint_Bellatrix(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateFinalizedCheckpoint(
|
||||||
|
t,
|
||||||
|
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafeBellatrix(ðpb.BeaconStateBellatrix{FinalizedCheckpoint: cp})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_JustificationBitsNil_Phase0(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateJustificationBitsNil(
|
||||||
|
t,
|
||||||
|
func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafePhase0(ðpb.BeaconState{})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_JustificationBitsNil_Altair(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateJustificationBitsNil(
|
||||||
|
t,
|
||||||
|
func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafeAltair(ðpb.BeaconStateAltair{})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_JustificationBitsNil_Bellatrix(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateJustificationBitsNil(
|
||||||
|
t,
|
||||||
|
func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafeBellatrix(ðpb.BeaconStateBellatrix{})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_JustificationBits_Phase0(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateJustificationBits(
|
||||||
|
t,
|
||||||
|
func(bits bitfield.Bitvector4) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafePhase0(ðpb.BeaconState{JustificationBits: bits})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_JustificationBits_Altair(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateJustificationBits(
|
||||||
|
t,
|
||||||
|
func(bits bitfield.Bitvector4) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafeAltair(ðpb.BeaconStateAltair{JustificationBits: bits})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_JustificationBits_Bellatrix(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateJustificationBits(
|
||||||
|
t,
|
||||||
|
func(bits bitfield.Bitvector4) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafeBellatrix(ðpb.BeaconStateBellatrix{JustificationBits: bits})
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package v3
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
package v2
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GenesisTime of the beacon state as a uint64.
|
// GenesisTime of the beacon state as a uint64.
|
||||||
@@ -25,8 +24,8 @@ func (b *BeaconState) GenesisValidatorsRoot() []byte {
|
|||||||
// Version of the beacon state. This method
|
// Version of the beacon state. This method
|
||||||
// is strictly meant to be used without a lock
|
// is strictly meant to be used without a lock
|
||||||
// internally.
|
// internally.
|
||||||
func (_ *BeaconState) Version() int {
|
func (b *BeaconState) Version() int {
|
||||||
return version.Altair
|
return b.version
|
||||||
}
|
}
|
||||||
|
|
||||||
// Slot of the current beacon chain state.
|
// Slot of the current beacon chain state.
|
||||||
@@ -1,7 +1,15 @@
|
|||||||
package v3
|
package state_native
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
|
)
|
||||||
|
|
||||||
// CurrentEpochParticipation corresponding to participation bits on the beacon chain.
|
// CurrentEpochParticipation corresponding to participation bits on the beacon chain.
|
||||||
func (b *BeaconState) CurrentEpochParticipation() ([]byte, error) {
|
func (b *BeaconState) CurrentEpochParticipation() ([]byte, error) {
|
||||||
|
if b.version == version.Phase0 {
|
||||||
|
return nil, errNotSupported("CurrentEpochParticipation", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
if b.currentEpochParticipation == nil {
|
if b.currentEpochParticipation == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -14,6 +22,10 @@ func (b *BeaconState) CurrentEpochParticipation() ([]byte, error) {
|
|||||||
|
|
||||||
// PreviousEpochParticipation corresponding to participation bits on the beacon chain.
|
// PreviousEpochParticipation corresponding to participation bits on the beacon chain.
|
||||||
func (b *BeaconState) PreviousEpochParticipation() ([]byte, error) {
|
func (b *BeaconState) PreviousEpochParticipation() ([]byte, error) {
|
||||||
|
if b.version == version.Phase0 {
|
||||||
|
return nil, errNotSupported("PreviousEpochParticipation", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
if b.previousEpochParticipation == nil {
|
if b.previousEpochParticipation == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,16 @@
|
|||||||
package v3
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// LatestExecutionPayloadHeader of the beacon state.
|
// LatestExecutionPayloadHeader of the beacon state.
|
||||||
func (b *BeaconState) LatestExecutionPayloadHeader() (*ethpb.ExecutionPayloadHeader, error) {
|
func (b *BeaconState) LatestExecutionPayloadHeader() (*ethpb.ExecutionPayloadHeader, error) {
|
||||||
|
if b.version == version.Phase0 || b.version == version.Altair {
|
||||||
|
return nil, errNotSupported("LatestExecutionPayloadHeader", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
if b.latestExecutionPayloadHeader == nil {
|
if b.latestExecutionPayloadHeader == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package v3
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
279
beacon-chain/state/state-native/getters_state.go
Normal file
279
beacon-chain/state/state-native/getters_state.go
Normal file
@@ -0,0 +1,279 @@
|
|||||||
|
package state_native
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ToProtoUnsafe returns the pointer value of the underlying
|
||||||
|
// beacon state proto object, bypassing immutability. Use with care.
|
||||||
|
func (b *BeaconState) ToProtoUnsafe() interface{} {
|
||||||
|
if b == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
gvrCopy := b.genesisValidatorsRoot
|
||||||
|
|
||||||
|
switch b.version {
|
||||||
|
case version.Phase0:
|
||||||
|
return ðpb.BeaconState{
|
||||||
|
GenesisTime: b.genesisTime,
|
||||||
|
GenesisValidatorsRoot: gvrCopy[:],
|
||||||
|
Slot: b.slot,
|
||||||
|
Fork: b.fork,
|
||||||
|
LatestBlockHeader: b.latestBlockHeader,
|
||||||
|
BlockRoots: b.blockRoots.Slice(),
|
||||||
|
StateRoots: b.stateRoots.Slice(),
|
||||||
|
HistoricalRoots: b.historicalRoots.Slice(),
|
||||||
|
Eth1Data: b.eth1Data,
|
||||||
|
Eth1DataVotes: b.eth1DataVotes,
|
||||||
|
Eth1DepositIndex: b.eth1DepositIndex,
|
||||||
|
Validators: b.validators,
|
||||||
|
Balances: b.balances,
|
||||||
|
RandaoMixes: b.randaoMixes.Slice(),
|
||||||
|
Slashings: b.slashings,
|
||||||
|
PreviousEpochAttestations: b.previousEpochAttestations,
|
||||||
|
CurrentEpochAttestations: b.currentEpochAttestations,
|
||||||
|
JustificationBits: b.justificationBits,
|
||||||
|
PreviousJustifiedCheckpoint: b.previousJustifiedCheckpoint,
|
||||||
|
CurrentJustifiedCheckpoint: b.currentJustifiedCheckpoint,
|
||||||
|
FinalizedCheckpoint: b.finalizedCheckpoint,
|
||||||
|
}
|
||||||
|
case version.Altair:
|
||||||
|
return ðpb.BeaconStateAltair{
|
||||||
|
GenesisTime: b.genesisTime,
|
||||||
|
GenesisValidatorsRoot: gvrCopy[:],
|
||||||
|
Slot: b.slot,
|
||||||
|
Fork: b.fork,
|
||||||
|
LatestBlockHeader: b.latestBlockHeader,
|
||||||
|
BlockRoots: b.blockRoots.Slice(),
|
||||||
|
StateRoots: b.stateRoots.Slice(),
|
||||||
|
HistoricalRoots: b.historicalRoots.Slice(),
|
||||||
|
Eth1Data: b.eth1Data,
|
||||||
|
Eth1DataVotes: b.eth1DataVotes,
|
||||||
|
Eth1DepositIndex: b.eth1DepositIndex,
|
||||||
|
Validators: b.validators,
|
||||||
|
Balances: b.balances,
|
||||||
|
RandaoMixes: b.randaoMixes.Slice(),
|
||||||
|
Slashings: b.slashings,
|
||||||
|
PreviousEpochParticipation: b.previousEpochParticipation,
|
||||||
|
CurrentEpochParticipation: b.currentEpochParticipation,
|
||||||
|
JustificationBits: b.justificationBits,
|
||||||
|
PreviousJustifiedCheckpoint: b.previousJustifiedCheckpoint,
|
||||||
|
CurrentJustifiedCheckpoint: b.currentJustifiedCheckpoint,
|
||||||
|
FinalizedCheckpoint: b.finalizedCheckpoint,
|
||||||
|
InactivityScores: b.inactivityScores,
|
||||||
|
CurrentSyncCommittee: b.currentSyncCommittee,
|
||||||
|
NextSyncCommittee: b.nextSyncCommittee,
|
||||||
|
}
|
||||||
|
case version.Bellatrix:
|
||||||
|
return ðpb.BeaconStateBellatrix{
|
||||||
|
GenesisTime: b.genesisTime,
|
||||||
|
GenesisValidatorsRoot: gvrCopy[:],
|
||||||
|
Slot: b.slot,
|
||||||
|
Fork: b.fork,
|
||||||
|
LatestBlockHeader: b.latestBlockHeader,
|
||||||
|
BlockRoots: b.blockRoots.Slice(),
|
||||||
|
StateRoots: b.stateRoots.Slice(),
|
||||||
|
HistoricalRoots: b.historicalRoots.Slice(),
|
||||||
|
Eth1Data: b.eth1Data,
|
||||||
|
Eth1DataVotes: b.eth1DataVotes,
|
||||||
|
Eth1DepositIndex: b.eth1DepositIndex,
|
||||||
|
Validators: b.validators,
|
||||||
|
Balances: b.balances,
|
||||||
|
RandaoMixes: b.randaoMixes.Slice(),
|
||||||
|
Slashings: b.slashings,
|
||||||
|
PreviousEpochParticipation: b.previousEpochParticipation,
|
||||||
|
CurrentEpochParticipation: b.currentEpochParticipation,
|
||||||
|
JustificationBits: b.justificationBits,
|
||||||
|
PreviousJustifiedCheckpoint: b.previousJustifiedCheckpoint,
|
||||||
|
CurrentJustifiedCheckpoint: b.currentJustifiedCheckpoint,
|
||||||
|
FinalizedCheckpoint: b.finalizedCheckpoint,
|
||||||
|
InactivityScores: b.inactivityScores,
|
||||||
|
CurrentSyncCommittee: b.currentSyncCommittee,
|
||||||
|
NextSyncCommittee: b.nextSyncCommittee,
|
||||||
|
LatestExecutionPayloadHeader: b.latestExecutionPayloadHeader,
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToProto the beacon state into a protobuf for usage.
|
||||||
|
func (b *BeaconState) ToProto() interface{} {
|
||||||
|
if b == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
b.lock.RLock()
|
||||||
|
defer b.lock.RUnlock()
|
||||||
|
|
||||||
|
gvrCopy := b.genesisValidatorsRoot
|
||||||
|
|
||||||
|
switch b.version {
|
||||||
|
case version.Phase0:
|
||||||
|
return ðpb.BeaconState{
|
||||||
|
GenesisTime: b.genesisTime,
|
||||||
|
GenesisValidatorsRoot: gvrCopy[:],
|
||||||
|
Slot: b.slot,
|
||||||
|
Fork: b.forkVal(),
|
||||||
|
LatestBlockHeader: b.latestBlockHeaderVal(),
|
||||||
|
BlockRoots: b.blockRoots.Slice(),
|
||||||
|
StateRoots: b.stateRoots.Slice(),
|
||||||
|
HistoricalRoots: b.historicalRoots.Slice(),
|
||||||
|
Eth1Data: b.eth1DataVal(),
|
||||||
|
Eth1DataVotes: b.eth1DataVotesVal(),
|
||||||
|
Eth1DepositIndex: b.eth1DepositIndex,
|
||||||
|
Validators: b.validatorsVal(),
|
||||||
|
Balances: b.balancesVal(),
|
||||||
|
RandaoMixes: b.randaoMixes.Slice(),
|
||||||
|
Slashings: b.slashingsVal(),
|
||||||
|
PreviousEpochAttestations: b.previousEpochAttestationsVal(),
|
||||||
|
CurrentEpochAttestations: b.currentEpochAttestationsVal(),
|
||||||
|
JustificationBits: b.justificationBitsVal(),
|
||||||
|
PreviousJustifiedCheckpoint: b.previousJustifiedCheckpointVal(),
|
||||||
|
CurrentJustifiedCheckpoint: b.currentJustifiedCheckpointVal(),
|
||||||
|
FinalizedCheckpoint: b.finalizedCheckpointVal(),
|
||||||
|
}
|
||||||
|
case version.Altair:
|
||||||
|
return ðpb.BeaconStateAltair{
|
||||||
|
GenesisTime: b.genesisTime,
|
||||||
|
GenesisValidatorsRoot: gvrCopy[:],
|
||||||
|
Slot: b.slot,
|
||||||
|
Fork: b.forkVal(),
|
||||||
|
LatestBlockHeader: b.latestBlockHeaderVal(),
|
||||||
|
BlockRoots: b.blockRoots.Slice(),
|
||||||
|
StateRoots: b.stateRoots.Slice(),
|
||||||
|
HistoricalRoots: b.historicalRoots.Slice(),
|
||||||
|
Eth1Data: b.eth1DataVal(),
|
||||||
|
Eth1DataVotes: b.eth1DataVotesVal(),
|
||||||
|
Eth1DepositIndex: b.eth1DepositIndex,
|
||||||
|
Validators: b.validatorsVal(),
|
||||||
|
Balances: b.balancesVal(),
|
||||||
|
RandaoMixes: b.randaoMixes.Slice(),
|
||||||
|
Slashings: b.slashingsVal(),
|
||||||
|
PreviousEpochParticipation: b.previousEpochParticipationVal(),
|
||||||
|
CurrentEpochParticipation: b.currentEpochParticipationVal(),
|
||||||
|
JustificationBits: b.justificationBitsVal(),
|
||||||
|
PreviousJustifiedCheckpoint: b.previousJustifiedCheckpointVal(),
|
||||||
|
CurrentJustifiedCheckpoint: b.currentJustifiedCheckpointVal(),
|
||||||
|
FinalizedCheckpoint: b.finalizedCheckpointVal(),
|
||||||
|
InactivityScores: b.inactivityScoresVal(),
|
||||||
|
CurrentSyncCommittee: b.currentSyncCommitteeVal(),
|
||||||
|
NextSyncCommittee: b.nextSyncCommitteeVal(),
|
||||||
|
}
|
||||||
|
case version.Bellatrix:
|
||||||
|
return ðpb.BeaconStateBellatrix{
|
||||||
|
GenesisTime: b.genesisTime,
|
||||||
|
GenesisValidatorsRoot: gvrCopy[:],
|
||||||
|
Slot: b.slot,
|
||||||
|
Fork: b.forkVal(),
|
||||||
|
LatestBlockHeader: b.latestBlockHeaderVal(),
|
||||||
|
BlockRoots: b.blockRoots.Slice(),
|
||||||
|
StateRoots: b.stateRoots.Slice(),
|
||||||
|
HistoricalRoots: b.historicalRoots.Slice(),
|
||||||
|
Eth1Data: b.eth1DataVal(),
|
||||||
|
Eth1DataVotes: b.eth1DataVotesVal(),
|
||||||
|
Eth1DepositIndex: b.eth1DepositIndex,
|
||||||
|
Validators: b.validatorsVal(),
|
||||||
|
Balances: b.balancesVal(),
|
||||||
|
RandaoMixes: b.randaoMixes.Slice(),
|
||||||
|
Slashings: b.slashingsVal(),
|
||||||
|
PreviousEpochParticipation: b.previousEpochParticipationVal(),
|
||||||
|
CurrentEpochParticipation: b.currentEpochParticipationVal(),
|
||||||
|
JustificationBits: b.justificationBitsVal(),
|
||||||
|
PreviousJustifiedCheckpoint: b.previousJustifiedCheckpointVal(),
|
||||||
|
CurrentJustifiedCheckpoint: b.currentJustifiedCheckpointVal(),
|
||||||
|
FinalizedCheckpoint: b.finalizedCheckpointVal(),
|
||||||
|
InactivityScores: b.inactivityScoresVal(),
|
||||||
|
CurrentSyncCommittee: b.currentSyncCommitteeVal(),
|
||||||
|
NextSyncCommittee: b.nextSyncCommitteeVal(),
|
||||||
|
LatestExecutionPayloadHeader: b.latestExecutionPayloadHeaderVal(),
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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()
|
||||||
|
|
||||||
|
r, err := b.stateRootAtIndex(idx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return r[:], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// stateRootAtIndex retrieves a specific state root based on an
|
||||||
|
// input index value.
|
||||||
|
// This assumes that a lock is already held on BeaconState.
|
||||||
|
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 b.stateRoots[idx], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProtobufBeaconStatePhase0 transforms an input into beacon state in the form of protobuf.
|
||||||
|
// Error is returned if the input is not type protobuf beacon state.
|
||||||
|
func ProtobufBeaconStatePhase0(s interface{}) (*ethpb.BeaconState, error) {
|
||||||
|
pbState, ok := s.(*ethpb.BeaconState)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("input is not type ethpb.BeaconState")
|
||||||
|
}
|
||||||
|
return pbState, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProtobufBeaconStateAltair transforms an input into beacon state Altair in the form of protobuf.
|
||||||
|
// Error is returned if the input is not type protobuf beacon state.
|
||||||
|
func ProtobufBeaconStateAltair(s interface{}) (*ethpb.BeaconStateAltair, error) {
|
||||||
|
pbState, ok := s.(*ethpb.BeaconStateAltair)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("input is not type pb.BeaconStateAltair")
|
||||||
|
}
|
||||||
|
return pbState, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProtobufBeaconStateBellatrix transforms an input into beacon state Bellatrix in the form of protobuf.
|
||||||
|
// Error is returned if the input is not type protobuf beacon state.
|
||||||
|
func ProtobufBeaconStateBellatrix(s interface{}) (*ethpb.BeaconStateBellatrix, error) {
|
||||||
|
pbState, ok := s.(*ethpb.BeaconStateBellatrix)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("input is not type pb.BeaconStateBellatrix")
|
||||||
|
}
|
||||||
|
return pbState, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// InnerStateUnsafe returns the pointer value of the underlying
|
||||||
|
// beacon state proto object, bypassing immutability. Use with care.
|
||||||
|
func (b *BeaconState) InnerStateUnsafe() interface{} {
|
||||||
|
return b.ToProtoUnsafe()
|
||||||
|
}
|
||||||
|
|
||||||
|
// CloneInnerState the beacon state into a protobuf for usage.
|
||||||
|
func (b *BeaconState) CloneInnerState() interface{} {
|
||||||
|
return b.ToProto()
|
||||||
|
}
|
||||||
@@ -1,27 +1,20 @@
|
|||||||
package v2
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// currentSyncCommitteeVal of the current sync committee in beacon chain state.
|
|
||||||
// This assumes that a lock is already held on BeaconState.
|
|
||||||
func (b *BeaconState) currentSyncCommitteeVal() *ethpb.SyncCommittee {
|
|
||||||
return CopySyncCommittee(b.currentSyncCommittee)
|
|
||||||
}
|
|
||||||
|
|
||||||
// nextSyncCommitteeVal of the next sync committee in beacon chain state.
|
|
||||||
// This assumes that a lock is already held on BeaconState.
|
|
||||||
func (b *BeaconState) nextSyncCommitteeVal() *ethpb.SyncCommittee {
|
|
||||||
return CopySyncCommittee(b.nextSyncCommittee)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CurrentSyncCommittee of the current sync committee in beacon chain state.
|
// CurrentSyncCommittee of the current sync committee in beacon chain state.
|
||||||
func (b *BeaconState) CurrentSyncCommittee() (*ethpb.SyncCommittee, error) {
|
func (b *BeaconState) CurrentSyncCommittee() (*ethpb.SyncCommittee, error) {
|
||||||
b.lock.RLock()
|
b.lock.RLock()
|
||||||
defer b.lock.RUnlock()
|
defer b.lock.RUnlock()
|
||||||
|
|
||||||
|
if b.version == version.Phase0 {
|
||||||
|
return nil, errNotSupported("CurrentSyncCommittee", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
if b.currentSyncCommittee == nil {
|
if b.currentSyncCommittee == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -29,11 +22,21 @@ func (b *BeaconState) CurrentSyncCommittee() (*ethpb.SyncCommittee, error) {
|
|||||||
return b.currentSyncCommitteeVal(), nil
|
return b.currentSyncCommitteeVal(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// currentSyncCommitteeVal of the current sync committee in beacon chain state.
|
||||||
|
// This assumes that a lock is already held on BeaconState.
|
||||||
|
func (b *BeaconState) currentSyncCommitteeVal() *ethpb.SyncCommittee {
|
||||||
|
return copySyncCommittee(b.currentSyncCommittee)
|
||||||
|
}
|
||||||
|
|
||||||
// NextSyncCommittee of the next sync committee in beacon chain state.
|
// NextSyncCommittee of the next sync committee in beacon chain state.
|
||||||
func (b *BeaconState) NextSyncCommittee() (*ethpb.SyncCommittee, error) {
|
func (b *BeaconState) NextSyncCommittee() (*ethpb.SyncCommittee, error) {
|
||||||
b.lock.RLock()
|
b.lock.RLock()
|
||||||
defer b.lock.RUnlock()
|
defer b.lock.RUnlock()
|
||||||
|
|
||||||
|
if b.version == version.Phase0 {
|
||||||
|
return nil, errNotSupported("NextSyncCommittee", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
if b.nextSyncCommittee == nil {
|
if b.nextSyncCommittee == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -41,8 +44,14 @@ func (b *BeaconState) NextSyncCommittee() (*ethpb.SyncCommittee, error) {
|
|||||||
return b.nextSyncCommitteeVal(), nil
|
return b.nextSyncCommitteeVal(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CopySyncCommittee copies the provided sync committee object.
|
// nextSyncCommitteeVal of the next sync committee in beacon chain state.
|
||||||
func CopySyncCommittee(data *ethpb.SyncCommittee) *ethpb.SyncCommittee {
|
// This assumes that a lock is already held on BeaconState.
|
||||||
|
func (b *BeaconState) nextSyncCommitteeVal() *ethpb.SyncCommittee {
|
||||||
|
return copySyncCommittee(b.nextSyncCommittee)
|
||||||
|
}
|
||||||
|
|
||||||
|
// copySyncCommittee copies the provided sync committee object.
|
||||||
|
func copySyncCommittee(data *ethpb.SyncCommittee) *ethpb.SyncCommittee {
|
||||||
if data == nil {
|
if data == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
99
beacon-chain/state/state-native/getters_test.go
Normal file
99
beacon-chain/state/state-native/getters_test.go
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
package state_native
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
|
testtmpl "github.com/prysmaticlabs/prysm/beacon-chain/state/testing"
|
||||||
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBeaconState_SlotDataRace_Phase0(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateSlotDataRace(t, func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoPhase0(ðpb.BeaconState{Slot: 1})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_SlotDataRace_Altair(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateSlotDataRace(t, func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoAltair(ðpb.BeaconStateAltair{Slot: 1})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_SlotDataRace_Bellatrix(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateSlotDataRace(t, func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoBellatrix(ðpb.BeaconStateBellatrix{Slot: 1})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_MatchCurrentJustifiedCheckpt_Phase0(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateMatchCurrentJustifiedCheckptNative(
|
||||||
|
t,
|
||||||
|
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoPhase0(ðpb.BeaconState{CurrentJustifiedCheckpoint: cp})
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_MatchCurrentJustifiedCheckpt_Altair(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateMatchCurrentJustifiedCheckptNative(
|
||||||
|
t,
|
||||||
|
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoAltair(ðpb.BeaconStateAltair{CurrentJustifiedCheckpoint: cp})
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_MatchCurrentJustifiedCheckpt_Bellatrix(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateMatchCurrentJustifiedCheckptNative(
|
||||||
|
t,
|
||||||
|
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoBellatrix(ðpb.BeaconStateBellatrix{CurrentJustifiedCheckpoint: cp})
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_MatchPreviousJustifiedCheckpt_Phase0(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateMatchPreviousJustifiedCheckptNative(
|
||||||
|
t,
|
||||||
|
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoPhase0(ðpb.BeaconState{PreviousJustifiedCheckpoint: cp})
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_MatchPreviousJustifiedCheckpt_Altair(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateMatchPreviousJustifiedCheckptNative(
|
||||||
|
t,
|
||||||
|
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoAltair(ðpb.BeaconStateAltair{PreviousJustifiedCheckpoint: cp})
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_MatchPreviousJustifiedCheckpt_Bellatrix(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateMatchPreviousJustifiedCheckptNative(
|
||||||
|
t,
|
||||||
|
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoBellatrix(ðpb.BeaconStateBellatrix{PreviousJustifiedCheckpoint: cp})
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_ValidatorByPubkey_Phase0(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateValidatorByPubkey(t, func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoPhase0(ðpb.BeaconState{})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_ValidatorByPubkey_Altair(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateValidatorByPubkey(t, func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoAltair(ðpb.BeaconStateAltair{})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_ValidatorByPubkey_Bellatrix(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateValidatorByPubkey(t, func() (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoBellatrix(ðpb.BeaconStateBellatrix{})
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
package v3
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/v1"
|
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ValidatorIndexOutOfRangeError represents an error scenario where a validator does not exist
|
// ValidatorIndexOutOfRangeError represents an error scenario where a validator does not exist
|
||||||
@@ -111,7 +111,7 @@ func (b *BeaconState) ValidatorAtIndexReadOnly(idx types.ValidatorIndex) (state.
|
|||||||
b.lock.RLock()
|
b.lock.RLock()
|
||||||
defer b.lock.RUnlock()
|
defer b.lock.RUnlock()
|
||||||
|
|
||||||
return v1.NewValidator(b.validators[idx])
|
return NewValidator(b.validators[idx])
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidatorIndexByPubkey returns a given validator by its 48-byte public key.
|
// ValidatorIndexByPubkey returns a given validator by its 48-byte public key.
|
||||||
@@ -164,7 +164,7 @@ func (b *BeaconState) ReadFromEveryValidator(f func(idx int, val state.ReadOnlyV
|
|||||||
b.lock.RUnlock()
|
b.lock.RUnlock()
|
||||||
|
|
||||||
for i, v := range validators {
|
for i, v := range validators {
|
||||||
v, err := v1.NewValidator(v)
|
v, err := NewValidator(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -250,6 +250,22 @@ func (b *BeaconState) slashingsVal() []uint64 {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InactivityScores of validators participating in consensus on the beacon chain.
|
||||||
|
func (b *BeaconState) InactivityScores() ([]uint64, error) {
|
||||||
|
if b.version == version.Phase0 {
|
||||||
|
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.
|
// inactivityScoresVal of validators participating in consensus on the beacon chain.
|
||||||
// This assumes that a lock is already held on BeaconState.
|
// This assumes that a lock is already held on BeaconState.
|
||||||
func (b *BeaconState) inactivityScoresVal() []uint64 {
|
func (b *BeaconState) inactivityScoresVal() []uint64 {
|
||||||
@@ -261,15 +277,3 @@ func (b *BeaconState) inactivityScoresVal() []uint64 {
|
|||||||
copy(res, b.inactivityScores)
|
copy(res, b.inactivityScores)
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
// InactivityScores of validators participating in consensus on the beacon chain.
|
|
||||||
func (b *BeaconState) InactivityScores() ([]uint64, error) {
|
|
||||||
if b.inactivityScores == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.inactivityScoresVal(), nil
|
|
||||||
}
|
|
||||||
34
beacon-chain/state/state-native/getters_validator_test.go
Normal file
34
beacon-chain/state/state-native/getters_validator_test.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package state_native_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
|
statenative "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native"
|
||||||
|
testtmpl "github.com/prysmaticlabs/prysm/beacon-chain/state/testing"
|
||||||
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBeaconState_ValidatorAtIndexReadOnly_HandlesNilSlice_Phase0(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateValidatorAtIndexReadOnlyHandlesNilSlice(t, func() (state.BeaconState, error) {
|
||||||
|
return statenative.InitializeFromProtoUnsafePhase0(ðpb.BeaconState{
|
||||||
|
Validators: nil,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_ValidatorAtIndexReadOnly_HandlesNilSlice_Altair(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateValidatorAtIndexReadOnlyHandlesNilSlice(t, func() (state.BeaconState, error) {
|
||||||
|
return statenative.InitializeFromProtoUnsafeAltair(ðpb.BeaconStateAltair{
|
||||||
|
Validators: nil,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_ValidatorAtIndexReadOnly_HandlesNilSlice_Bellatrix(t *testing.T) {
|
||||||
|
testtmpl.VerifyBeaconStateValidatorAtIndexReadOnlyHandlesNilSlice(t, func() (state.BeaconState, error) {
|
||||||
|
return statenative.InitializeFromProtoUnsafeBellatrix(ðpb.BeaconStateBellatrix{
|
||||||
|
Validators: nil,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
240
beacon-chain/state/state-native/hasher.go
Normal file
240
beacon-chain/state/state-native/hasher.go
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
package state_native
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/binary"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
||||||
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/crypto/hash"
|
||||||
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
|
"github.com/prysmaticlabs/prysm/encoding/ssz"
|
||||||
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
|
"go.opencensus.io/trace"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ComputeFieldRootsWithHasher hashes the provided state and returns its respective field roots.
|
||||||
|
func ComputeFieldRootsWithHasher(ctx context.Context, state *BeaconState) ([][]byte, error) {
|
||||||
|
_, span := trace.StartSpan(ctx, "ComputeFieldRootsWithHasher")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
if state == nil {
|
||||||
|
return nil, errors.New("nil state")
|
||||||
|
}
|
||||||
|
hasher := hash.CustomSHA256Hasher()
|
||||||
|
var fieldRoots [][]byte
|
||||||
|
switch state.version {
|
||||||
|
case version.Phase0:
|
||||||
|
fieldRoots = make([][]byte, params.BeaconConfig().BeaconStateFieldCount)
|
||||||
|
case version.Altair:
|
||||||
|
fieldRoots = make([][]byte, params.BeaconConfig().BeaconStateAltairFieldCount)
|
||||||
|
case version.Bellatrix:
|
||||||
|
fieldRoots = make([][]byte, params.BeaconConfig().BeaconStateBellatrixFieldCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Genesis time root.
|
||||||
|
genesisRoot := ssz.Uint64Root(state.genesisTime)
|
||||||
|
fieldRoots[nativetypes.GenesisTime.RealPosition()] = genesisRoot[:]
|
||||||
|
|
||||||
|
// Genesis validators root.
|
||||||
|
r := [32]byte{}
|
||||||
|
copy(r[:], state.genesisValidatorsRoot[:])
|
||||||
|
fieldRoots[nativetypes.GenesisValidatorsRoot.RealPosition()] = r[:]
|
||||||
|
|
||||||
|
// Slot root.
|
||||||
|
slotRoot := ssz.Uint64Root(uint64(state.slot))
|
||||||
|
fieldRoots[nativetypes.Slot.RealPosition()] = slotRoot[:]
|
||||||
|
|
||||||
|
// Fork data structure root.
|
||||||
|
forkHashTreeRoot, err := ssz.ForkRoot(state.fork)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not compute fork merkleization")
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.Fork.RealPosition()] = forkHashTreeRoot[:]
|
||||||
|
|
||||||
|
// BeaconBlockHeader data structure root.
|
||||||
|
headerHashTreeRoot, err := stateutil.BlockHeaderRoot(state.latestBlockHeader)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not compute block header merkleization")
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.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)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not compute block roots merkleization")
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.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)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not compute state roots merkleization")
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.StateRoots.RealPosition()] = stateRootsRoot[:]
|
||||||
|
|
||||||
|
// HistoricalRoots slice root.
|
||||||
|
hRoots := make([][]byte, len(state.historicalRoots))
|
||||||
|
for i := range hRoots {
|
||||||
|
hRoots[i] = state.historicalRoots[i][:]
|
||||||
|
}
|
||||||
|
historicalRootsRt, err := ssz.ByteArrayRootWithLimit(hRoots, fieldparams.HistoricalRootsLength)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not compute historical roots merkleization")
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.HistoricalRoots.RealPosition()] = historicalRootsRt[:]
|
||||||
|
|
||||||
|
// Eth1Data data structure root.
|
||||||
|
eth1HashTreeRoot, err := stateutil.Eth1Root(hasher, state.eth1Data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not compute eth1data merkleization")
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.Eth1Data.RealPosition()] = eth1HashTreeRoot[:]
|
||||||
|
|
||||||
|
// Eth1DataVotes slice root.
|
||||||
|
eth1VotesRoot, err := stateutil.Eth1DataVotesRoot(state.eth1DataVotes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not compute eth1data votes merkleization")
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.Eth1DataVotes.RealPosition()] = eth1VotesRoot[:]
|
||||||
|
|
||||||
|
// Eth1DepositIndex root.
|
||||||
|
eth1DepositIndexBuf := make([]byte, 8)
|
||||||
|
binary.LittleEndian.PutUint64(eth1DepositIndexBuf, state.eth1DepositIndex)
|
||||||
|
eth1DepositBuf := bytesutil.ToBytes32(eth1DepositIndexBuf)
|
||||||
|
fieldRoots[nativetypes.Eth1DepositIndex.RealPosition()] = eth1DepositBuf[:]
|
||||||
|
|
||||||
|
// Validators slice root.
|
||||||
|
validatorsRoot, err := stateutil.ValidatorRegistryRoot(state.validators)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not compute validator registry merkleization")
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.Validators.RealPosition()] = validatorsRoot[:]
|
||||||
|
|
||||||
|
// Balances slice root.
|
||||||
|
balancesRoot, err := stateutil.Uint64ListRootWithRegistryLimit(state.balances)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not compute validator balances merkleization")
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.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)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not compute randao roots merkleization")
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.RandaoMixes.RealPosition()] = randaoRootsRoot[:]
|
||||||
|
|
||||||
|
// Slashings array root.
|
||||||
|
slashingsRootsRoot, err := ssz.SlashingsRoot(state.slashings)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not compute slashings merkleization")
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.Slashings.RealPosition()] = slashingsRootsRoot[:]
|
||||||
|
|
||||||
|
if state.version == version.Phase0 {
|
||||||
|
// PreviousEpochAttestations slice root.
|
||||||
|
prevAttsRoot, err := stateutil.EpochAttestationsRoot(state.previousEpochAttestations)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not compute previous epoch attestations merkleization")
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.PreviousEpochAttestations.RealPosition()] = prevAttsRoot[:]
|
||||||
|
|
||||||
|
// CurrentEpochAttestations slice root.
|
||||||
|
currAttsRoot, err := stateutil.EpochAttestationsRoot(state.currentEpochAttestations)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not compute current epoch attestations merkleization")
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.CurrentEpochAttestations.RealPosition()] = currAttsRoot[:]
|
||||||
|
}
|
||||||
|
|
||||||
|
if state.version == version.Altair || state.version == version.Bellatrix {
|
||||||
|
// PreviousEpochParticipation slice root.
|
||||||
|
prevParticipationRoot, err := stateutil.ParticipationBitsRoot(state.previousEpochParticipation)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not compute previous epoch participation merkleization")
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.PreviousEpochParticipationBits.RealPosition()] = prevParticipationRoot[:]
|
||||||
|
|
||||||
|
// CurrentEpochParticipation slice root.
|
||||||
|
currParticipationRoot, err := stateutil.ParticipationBitsRoot(state.currentEpochParticipation)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not compute current epoch participation merkleization")
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.CurrentEpochParticipationBits.RealPosition()] = currParticipationRoot[:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// JustificationBits root.
|
||||||
|
justifiedBitsRoot := bytesutil.ToBytes32(state.justificationBits)
|
||||||
|
fieldRoots[nativetypes.JustificationBits.RealPosition()] = justifiedBitsRoot[:]
|
||||||
|
|
||||||
|
// PreviousJustifiedCheckpoint data structure root.
|
||||||
|
prevCheckRoot, err := ssz.CheckpointRoot(hasher, state.previousJustifiedCheckpoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not compute previous justified checkpoint merkleization")
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.PreviousJustifiedCheckpoint.RealPosition()] = prevCheckRoot[:]
|
||||||
|
|
||||||
|
// CurrentJustifiedCheckpoint data structure root.
|
||||||
|
currJustRoot, err := ssz.CheckpointRoot(hasher, state.currentJustifiedCheckpoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not compute current justified checkpoint merkleization")
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.CurrentJustifiedCheckpoint.RealPosition()] = currJustRoot[:]
|
||||||
|
|
||||||
|
// FinalizedCheckpoint data structure root.
|
||||||
|
finalRoot, err := ssz.CheckpointRoot(hasher, state.finalizedCheckpoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not compute finalized checkpoint merkleization")
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.FinalizedCheckpoint.RealPosition()] = finalRoot[:]
|
||||||
|
|
||||||
|
if state.version == version.Altair || state.version == version.Bellatrix {
|
||||||
|
// Inactivity scores root.
|
||||||
|
inactivityScoresRoot, err := stateutil.Uint64ListRootWithRegistryLimit(state.inactivityScores)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not compute inactivityScoreRoot")
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.InactivityScores.RealPosition()] = inactivityScoresRoot[:]
|
||||||
|
|
||||||
|
// Current sync committee root.
|
||||||
|
currentSyncCommitteeRoot, err := stateutil.SyncCommitteeRoot(state.currentSyncCommittee)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not compute sync committee merkleization")
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.CurrentSyncCommittee.RealPosition()] = currentSyncCommitteeRoot[:]
|
||||||
|
|
||||||
|
// Next sync committee root.
|
||||||
|
nextSyncCommitteeRoot, err := stateutil.SyncCommitteeRoot(state.nextSyncCommittee)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not compute sync committee merkleization")
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.NextSyncCommittee.RealPosition()] = nextSyncCommitteeRoot[:]
|
||||||
|
}
|
||||||
|
|
||||||
|
if state.version == version.Bellatrix {
|
||||||
|
// Execution payload root.
|
||||||
|
executionPayloadRoot, err := state.latestExecutionPayloadHeader.HashTreeRoot()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
fieldRoots[nativetypes.LatestExecutionPayloadHeader.RealPosition()] = executionPayloadRoot[:]
|
||||||
|
}
|
||||||
|
|
||||||
|
return fieldRoots, nil
|
||||||
|
}
|
||||||
355
beacon-chain/state/state-native/hasher_test.go
Normal file
355
beacon-chain/state/state-native/hasher_test.go
Normal file
@@ -0,0 +1,355 @@
|
|||||||
|
package state_native_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/prysmaticlabs/go-bitfield"
|
||||||
|
state_native "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native"
|
||||||
|
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
|
||||||
|
v2 "github.com/prysmaticlabs/prysm/beacon-chain/state/v2"
|
||||||
|
v3 "github.com/prysmaticlabs/prysm/beacon-chain/state/v3"
|
||||||
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestComputeFieldRootsWithHasher_Phase0(t *testing.T) {
|
||||||
|
beaconState, err := util.NewBeaconState(util.FillRootsNaturalOpt)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, beaconState.SetGenesisTime(123))
|
||||||
|
require.NoError(t, beaconState.SetGenesisValidatorsRoot(genesisValidatorsRoot()))
|
||||||
|
require.NoError(t, beaconState.SetSlot(123))
|
||||||
|
require.NoError(t, beaconState.SetFork(fork()))
|
||||||
|
require.NoError(t, beaconState.SetLatestBlockHeader(latestBlockHeader()))
|
||||||
|
historicalRoots, err := util.PrepareRoots(int(params.BeaconConfig().SlotsPerHistoricalRoot))
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, beaconState.SetHistoricalRoots(historicalRoots))
|
||||||
|
require.NoError(t, beaconState.SetEth1Data(eth1Data()))
|
||||||
|
require.NoError(t, beaconState.SetEth1DataVotes([]*ethpb.Eth1Data{eth1Data()}))
|
||||||
|
require.NoError(t, beaconState.SetEth1DepositIndex(123))
|
||||||
|
require.NoError(t, beaconState.SetValidators([]*ethpb.Validator{validator()}))
|
||||||
|
require.NoError(t, beaconState.SetBalances([]uint64{1, 2, 3}))
|
||||||
|
randaoMixes, err := util.PrepareRoots(int(params.BeaconConfig().EpochsPerHistoricalVector))
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, beaconState.SetRandaoMixes(randaoMixes))
|
||||||
|
require.NoError(t, beaconState.SetSlashings([]uint64{1, 2, 3}))
|
||||||
|
require.NoError(t, beaconState.AppendPreviousEpochAttestations(pendingAttestation("previous")))
|
||||||
|
require.NoError(t, beaconState.AppendCurrentEpochAttestations(pendingAttestation("current")))
|
||||||
|
require.NoError(t, beaconState.SetJustificationBits(justificationBits()))
|
||||||
|
require.NoError(t, beaconState.SetPreviousJustifiedCheckpoint(checkpoint("previous")))
|
||||||
|
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(checkpoint("current")))
|
||||||
|
require.NoError(t, beaconState.SetFinalizedCheckpoint(checkpoint("finalized")))
|
||||||
|
|
||||||
|
v1State, ok := beaconState.(*v1.BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
protoState, ok := v1State.InnerStateUnsafe().(*ethpb.BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
initState, err := state_native.InitializeFromProtoPhase0(protoState)
|
||||||
|
require.NoError(t, err)
|
||||||
|
s, ok := initState.(*state_native.BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
root, err := state_native.ComputeFieldRootsWithHasher(context.Background(), s)
|
||||||
|
require.NoError(t, err)
|
||||||
|
expected := [][]byte{
|
||||||
|
{0x7b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||||
|
{0x67, 0x76, 0x72, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||||
|
{0x7b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||||
|
{0x58, 0xba, 0xf, 0x9b, 0x4f, 0x63, 0x1c, 0xa6, 0x19, 0xb1, 0xa2, 0x1f, 0xd1, 0x29, 0xc7, 0x67, 0x9c, 0x32, 0x4, 0x1f, 0xcf, 0x4e, 0x64, 0x9b, 0x8f, 0x21, 0xb4, 0xe6, 0xa5, 0xc9, 0xc, 0x38},
|
||||||
|
{0x8b, 0x5, 0x59, 0x78, 0xed, 0xbe, 0x2c, 0xde, 0xa6, 0xf, 0x52, 0xdc, 0x16, 0x83, 0xa0, 0x5d, 0x8, 0xc3, 0x37, 0x91, 0x3a, 0xf6, 0xfa, 0x6, 0x62, 0xc9, 0x6, 0xb1, 0x41, 0x48, 0xaf, 0xec},
|
||||||
|
{0xcc, 0xa1, 0x69, 0xa8, 0x8b, 0x1e, 0x49, 0x5, 0x1f, 0xe4, 0xd8, 0xff, 0x82, 0xa2, 0x2e, 0xf0, 0x54, 0xd1, 0x13, 0xc9, 0x8e, 0xb9, 0x82, 0xa6, 0x9e, 0x42, 0x2, 0xec, 0x97, 0x6f, 0x33, 0x88},
|
||||||
|
{0xcc, 0xa1, 0x69, 0xa8, 0x8b, 0x1e, 0x49, 0x5, 0x1f, 0xe4, 0xd8, 0xff, 0x82, 0xa2, 0x2e, 0xf0, 0x54, 0xd1, 0x13, 0xc9, 0x8e, 0xb9, 0x82, 0xa6, 0x9e, 0x42, 0x2, 0xec, 0x97, 0x6f, 0x33, 0x88},
|
||||||
|
{0xf, 0xad, 0xd3, 0x92, 0x4b, 0xda, 0xfa, 0xc6, 0x61, 0x50, 0xb7, 0xdf, 0x5f, 0x2c, 0xd0, 0x94, 0xc3, 0xaf, 0x41, 0x9d, 0xa, 0xea, 0x50, 0x96, 0x82, 0x62, 0x1c, 0x72, 0x26, 0x20, 0x6b, 0xac},
|
||||||
|
{0xc9, 0x4e, 0x2c, 0xb0, 0x20, 0xe3, 0xe7, 0x8c, 0x5c, 0xbd, 0xeb, 0x9b, 0xa5, 0x7b, 0x53, 0x50, 0xca, 0xfe, 0xe9, 0x48, 0x9e, 0x8d, 0xf8, 0x4a, 0xe6, 0x8d, 0x9c, 0x97, 0x81, 0x74, 0xb, 0x5e},
|
||||||
|
{0x71, 0x52, 0xd2, 0x9b, 0x87, 0x3c, 0x8a, 0xd9, 0x51, 0x55, 0xc0, 0x42, 0xb, 0xc4, 0x12, 0xa4, 0x79, 0xf5, 0x7d, 0x37, 0x16, 0xf4, 0x90, 0x72, 0x5d, 0xe0, 0x34, 0xb4, 0x2, 0x8c, 0x39, 0xe4},
|
||||||
|
{0x7b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||||
|
{0xf, 0xf7, 0x4f, 0xe1, 0xa9, 0x72, 0x9c, 0x95, 0xf0, 0xe1, 0xde, 0xa4, 0x32, 0xc, 0x67, 0x52, 0x23, 0x13, 0x9e, 0xe2, 0x40, 0x8d, 0xf6, 0x18, 0x57, 0xf0, 0x1a, 0x4a, 0xad, 0x46, 0xce, 0x42},
|
||||||
|
{0xf9, 0x11, 0x2c, 0xc2, 0x71, 0x70, 0xde, 0x47, 0x26, 0xeb, 0x26, 0xd4, 0xa4, 0xe8, 0x68, 0xb, 0x16, 0xa2, 0x6e, 0x52, 0x54, 0xe, 0x5c, 0x83, 0x17, 0x3, 0xea, 0xdd, 0xd5, 0xa7, 0xb2, 0x3f},
|
||||||
|
{0x64, 0xbd, 0x40, 0xa7, 0x10, 0x44, 0x84, 0xed, 0xf3, 0x5f, 0xc3, 0x5d, 0x7b, 0xbe, 0xe8, 0x75, 0xbf, 0x66, 0xcb, 0xce, 0x77, 0xfa, 0x0, 0x3, 0xdd, 0xfb, 0x80, 0xd2, 0x77, 0x1b, 0xc2, 0x8},
|
||||||
|
{0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||||
|
{0x54, 0xd3, 0xce, 0x8a, 0x3f, 0xfd, 0x21, 0x3a, 0xb4, 0xa6, 0xd, 0xb, 0x9f, 0xf2, 0x88, 0xf0, 0xb1, 0x44, 0x9d, 0xb1, 0x2, 0x95, 0x67, 0xdf, 0x6f, 0x28, 0xa9, 0x68, 0xcd, 0xaa, 0x8c, 0x54},
|
||||||
|
{0xeb, 0x8, 0xb4, 0x1b, 0x76, 0xa2, 0x23, 0xbb, 0x4a, 0xd3, 0x78, 0xca, 0x2e, 0xe8, 0x2c, 0xa1, 0xbf, 0x45, 0xf2, 0x58, 0xdf, 0x39, 0xdf, 0x43, 0x40, 0xb, 0x96, 0xcf, 0xfd, 0x9a, 0x87, 0x85},
|
||||||
|
{0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||||
|
{0x76, 0x88, 0xa0, 0x68, 0x45, 0x25, 0x8f, 0xd5, 0xf9, 0xb2, 0xb0, 0x42, 0x68, 0x6b, 0x51, 0xcc, 0x29, 0x94, 0x63, 0x85, 0xec, 0xf5, 0x47, 0xf0, 0x9c, 0x46, 0x86, 0xa9, 0x99, 0x7d, 0x29, 0x6c},
|
||||||
|
{0x41, 0x44, 0x52, 0xff, 0x8c, 0xa6, 0xb3, 0x2e, 0xcc, 0x5e, 0x63, 0x8f, 0x8e, 0x7d, 0xe7, 0x52, 0x42, 0x94, 0x55, 0x2f, 0x89, 0xdd, 0x1e, 0x3c, 0xb0, 0xf4, 0x51, 0x51, 0x36, 0x81, 0x72, 0x1},
|
||||||
|
{0xa9, 0xbb, 0x6a, 0x1f, 0x5d, 0x86, 0x7d, 0xa7, 0x5a, 0x7d, 0x9d, 0x8d, 0xc0, 0x15, 0xb7, 0x0, 0xee, 0xa9, 0x68, 0x51, 0x88, 0x57, 0x5a, 0xd9, 0x4e, 0x1d, 0x8e, 0x44, 0xbf, 0xdc, 0x73, 0xff},
|
||||||
|
}
|
||||||
|
assert.DeepEqual(t, expected, root)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestComputeFieldRootsWithHasher_Altair(t *testing.T) {
|
||||||
|
beaconState, err := util.NewBeaconStateAltair(util.FillRootsNaturalOptAltair)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, beaconState.SetGenesisTime(123))
|
||||||
|
require.NoError(t, beaconState.SetGenesisValidatorsRoot(genesisValidatorsRoot()))
|
||||||
|
require.NoError(t, beaconState.SetSlot(123))
|
||||||
|
require.NoError(t, beaconState.SetFork(fork()))
|
||||||
|
require.NoError(t, beaconState.SetLatestBlockHeader(latestBlockHeader()))
|
||||||
|
historicalRoots, err := util.PrepareRoots(int(params.BeaconConfig().SlotsPerHistoricalRoot))
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, beaconState.SetHistoricalRoots(historicalRoots))
|
||||||
|
require.NoError(t, beaconState.SetEth1Data(eth1Data()))
|
||||||
|
require.NoError(t, beaconState.SetEth1DataVotes([]*ethpb.Eth1Data{eth1Data()}))
|
||||||
|
require.NoError(t, beaconState.SetEth1DepositIndex(123))
|
||||||
|
require.NoError(t, beaconState.SetValidators([]*ethpb.Validator{validator()}))
|
||||||
|
require.NoError(t, beaconState.SetBalances([]uint64{1, 2, 3}))
|
||||||
|
randaoMixes, err := util.PrepareRoots(int(params.BeaconConfig().EpochsPerHistoricalVector))
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, beaconState.SetRandaoMixes(randaoMixes))
|
||||||
|
require.NoError(t, beaconState.SetSlashings([]uint64{1, 2, 3}))
|
||||||
|
require.NoError(t, beaconState.SetPreviousParticipationBits([]byte{1, 2, 3}))
|
||||||
|
require.NoError(t, beaconState.SetCurrentParticipationBits([]byte{1, 2, 3}))
|
||||||
|
require.NoError(t, beaconState.SetJustificationBits(justificationBits()))
|
||||||
|
require.NoError(t, beaconState.SetPreviousJustifiedCheckpoint(checkpoint("previous")))
|
||||||
|
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(checkpoint("current")))
|
||||||
|
require.NoError(t, beaconState.SetFinalizedCheckpoint(checkpoint("finalized")))
|
||||||
|
require.NoError(t, beaconState.SetInactivityScores([]uint64{1, 2, 3}))
|
||||||
|
require.NoError(t, beaconState.SetCurrentSyncCommittee(syncCommittee("current")))
|
||||||
|
require.NoError(t, beaconState.SetNextSyncCommittee(syncCommittee("next")))
|
||||||
|
|
||||||
|
v1State, ok := beaconState.(*v2.BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
protoState, ok := v1State.InnerStateUnsafe().(*ethpb.BeaconStateAltair)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
initState, err := state_native.InitializeFromProtoAltair(protoState)
|
||||||
|
require.NoError(t, err)
|
||||||
|
s, ok := initState.(*state_native.BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
|
||||||
|
root, err := state_native.ComputeFieldRootsWithHasher(context.Background(), s)
|
||||||
|
require.NoError(t, err)
|
||||||
|
expected := [][]byte{
|
||||||
|
{0x7b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||||
|
{0x67, 0x76, 0x72, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||||
|
{0x7b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||||
|
{0x58, 0xba, 0xf, 0x9b, 0x4f, 0x63, 0x1c, 0xa6, 0x19, 0xb1, 0xa2, 0x1f, 0xd1, 0x29, 0xc7, 0x67, 0x9c, 0x32, 0x4, 0x1f, 0xcf, 0x4e, 0x64, 0x9b, 0x8f, 0x21, 0xb4, 0xe6, 0xa5, 0xc9, 0xc, 0x38},
|
||||||
|
{0x8b, 0x5, 0x59, 0x78, 0xed, 0xbe, 0x2c, 0xde, 0xa6, 0xf, 0x52, 0xdc, 0x16, 0x83, 0xa0, 0x5d, 0x8, 0xc3, 0x37, 0x91, 0x3a, 0xf6, 0xfa, 0x6, 0x62, 0xc9, 0x6, 0xb1, 0x41, 0x48, 0xaf, 0xec},
|
||||||
|
{0xcc, 0xa1, 0x69, 0xa8, 0x8b, 0x1e, 0x49, 0x5, 0x1f, 0xe4, 0xd8, 0xff, 0x82, 0xa2, 0x2e, 0xf0, 0x54, 0xd1, 0x13, 0xc9, 0x8e, 0xb9, 0x82, 0xa6, 0x9e, 0x42, 0x2, 0xec, 0x97, 0x6f, 0x33, 0x88},
|
||||||
|
{0xcc, 0xa1, 0x69, 0xa8, 0x8b, 0x1e, 0x49, 0x5, 0x1f, 0xe4, 0xd8, 0xff, 0x82, 0xa2, 0x2e, 0xf0, 0x54, 0xd1, 0x13, 0xc9, 0x8e, 0xb9, 0x82, 0xa6, 0x9e, 0x42, 0x2, 0xec, 0x97, 0x6f, 0x33, 0x88},
|
||||||
|
{0xf, 0xad, 0xd3, 0x92, 0x4b, 0xda, 0xfa, 0xc6, 0x61, 0x50, 0xb7, 0xdf, 0x5f, 0x2c, 0xd0, 0x94, 0xc3, 0xaf, 0x41, 0x9d, 0xa, 0xea, 0x50, 0x96, 0x82, 0x62, 0x1c, 0x72, 0x26, 0x20, 0x6b, 0xac},
|
||||||
|
{0xc9, 0x4e, 0x2c, 0xb0, 0x20, 0xe3, 0xe7, 0x8c, 0x5c, 0xbd, 0xeb, 0x9b, 0xa5, 0x7b, 0x53, 0x50, 0xca, 0xfe, 0xe9, 0x48, 0x9e, 0x8d, 0xf8, 0x4a, 0xe6, 0x8d, 0x9c, 0x97, 0x81, 0x74, 0xb, 0x5e},
|
||||||
|
{0x71, 0x52, 0xd2, 0x9b, 0x87, 0x3c, 0x8a, 0xd9, 0x51, 0x55, 0xc0, 0x42, 0xb, 0xc4, 0x12, 0xa4, 0x79, 0xf5, 0x7d, 0x37, 0x16, 0xf4, 0x90, 0x72, 0x5d, 0xe0, 0x34, 0xb4, 0x2, 0x8c, 0x39, 0xe4},
|
||||||
|
{0x7b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||||
|
{0xf, 0xf7, 0x4f, 0xe1, 0xa9, 0x72, 0x9c, 0x95, 0xf0, 0xe1, 0xde, 0xa4, 0x32, 0xc, 0x67, 0x52, 0x23, 0x13, 0x9e, 0xe2, 0x40, 0x8d, 0xf6, 0x18, 0x57, 0xf0, 0x1a, 0x4a, 0xad, 0x46, 0xce, 0x42},
|
||||||
|
{0xf9, 0x11, 0x2c, 0xc2, 0x71, 0x70, 0xde, 0x47, 0x26, 0xeb, 0x26, 0xd4, 0xa4, 0xe8, 0x68, 0xb, 0x16, 0xa2, 0x6e, 0x52, 0x54, 0xe, 0x5c, 0x83, 0x17, 0x3, 0xea, 0xdd, 0xd5, 0xa7, 0xb2, 0x3f},
|
||||||
|
{0x64, 0xbd, 0x40, 0xa7, 0x10, 0x44, 0x84, 0xed, 0xf3, 0x5f, 0xc3, 0x5d, 0x7b, 0xbe, 0xe8, 0x75, 0xbf, 0x66, 0xcb, 0xce, 0x77, 0xfa, 0x0, 0x3, 0xdd, 0xfb, 0x80, 0xd2, 0x77, 0x1b, 0xc2, 0x8},
|
||||||
|
{0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||||
|
{0x75, 0xb2, 0xae, 0x1d, 0xd8, 0xca, 0xe6, 0x4d, 0xa8, 0xc5, 0xc9, 0x19, 0x8, 0x96, 0xaf, 0x9b, 0xe6, 0xf6, 0x99, 0xb9, 0x58, 0x56, 0x5b, 0x25, 0xea, 0x9c, 0x86, 0x5e, 0x96, 0x6a, 0x48, 0xb},
|
||||||
|
{0x75, 0xb2, 0xae, 0x1d, 0xd8, 0xca, 0xe6, 0x4d, 0xa8, 0xc5, 0xc9, 0x19, 0x8, 0x96, 0xaf, 0x9b, 0xe6, 0xf6, 0x99, 0xb9, 0x58, 0x56, 0x5b, 0x25, 0xea, 0x9c, 0x86, 0x5e, 0x96, 0x6a, 0x48, 0xb},
|
||||||
|
{0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||||
|
{0x76, 0x88, 0xa0, 0x68, 0x45, 0x25, 0x8f, 0xd5, 0xf9, 0xb2, 0xb0, 0x42, 0x68, 0x6b, 0x51, 0xcc, 0x29, 0x94, 0x63, 0x85, 0xec, 0xf5, 0x47, 0xf0, 0x9c, 0x46, 0x86, 0xa9, 0x99, 0x7d, 0x29, 0x6c},
|
||||||
|
{0x41, 0x44, 0x52, 0xff, 0x8c, 0xa6, 0xb3, 0x2e, 0xcc, 0x5e, 0x63, 0x8f, 0x8e, 0x7d, 0xe7, 0x52, 0x42, 0x94, 0x55, 0x2f, 0x89, 0xdd, 0x1e, 0x3c, 0xb0, 0xf4, 0x51, 0x51, 0x36, 0x81, 0x72, 0x1},
|
||||||
|
{0xa9, 0xbb, 0x6a, 0x1f, 0x5d, 0x86, 0x7d, 0xa7, 0x5a, 0x7d, 0x9d, 0x8d, 0xc0, 0x15, 0xb7, 0x0, 0xee, 0xa9, 0x68, 0x51, 0x88, 0x57, 0x5a, 0xd9, 0x4e, 0x1d, 0x8e, 0x44, 0xbf, 0xdc, 0x73, 0xff},
|
||||||
|
{0xf9, 0x11, 0x2c, 0xc2, 0x71, 0x70, 0xde, 0x47, 0x26, 0xeb, 0x26, 0xd4, 0xa4, 0xe8, 0x68, 0xb, 0x16, 0xa2, 0x6e, 0x52, 0x54, 0xe, 0x5c, 0x83, 0x17, 0x3, 0xea, 0xdd, 0xd5, 0xa7, 0xb2, 0x3f},
|
||||||
|
{0x3d, 0xf3, 0x66, 0xd4, 0x12, 0x40, 0x3f, 0x28, 0xeb, 0xe4, 0x19, 0x59, 0xae, 0xab, 0x4d, 0xf3, 0x98, 0x88, 0x7f, 0x1e, 0x58, 0xa, 0x5d, 0xd4, 0xeb, 0xe5, 0x5d, 0x3d, 0x11, 0x70, 0x24, 0x76},
|
||||||
|
{0xd6, 0x4c, 0xb1, 0xac, 0x61, 0x7, 0x26, 0xbb, 0xd3, 0x27, 0x2a, 0xcd, 0xdd, 0x55, 0xf, 0x2b, 0x6a, 0xe8, 0x1, 0x31, 0x48, 0x66, 0x2f, 0x98, 0x7b, 0x6d, 0x27, 0x69, 0xd9, 0x40, 0xcc, 0x37},
|
||||||
|
}
|
||||||
|
assert.DeepEqual(t, expected, root)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestComputeFieldRootsWithHasher_Bellatrix(t *testing.T) {
|
||||||
|
beaconState, err := util.NewBeaconStateBellatrix(util.FillRootsNaturalOptBellatrix)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, beaconState.SetGenesisTime(123))
|
||||||
|
require.NoError(t, beaconState.SetGenesisValidatorsRoot(genesisValidatorsRoot()))
|
||||||
|
require.NoError(t, beaconState.SetSlot(123))
|
||||||
|
require.NoError(t, beaconState.SetFork(fork()))
|
||||||
|
require.NoError(t, beaconState.SetLatestBlockHeader(latestBlockHeader()))
|
||||||
|
historicalRoots, err := util.PrepareRoots(int(params.BeaconConfig().SlotsPerHistoricalRoot))
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, beaconState.SetHistoricalRoots(historicalRoots))
|
||||||
|
require.NoError(t, beaconState.SetEth1Data(eth1Data()))
|
||||||
|
require.NoError(t, beaconState.SetEth1DataVotes([]*ethpb.Eth1Data{eth1Data()}))
|
||||||
|
require.NoError(t, beaconState.SetEth1DepositIndex(123))
|
||||||
|
require.NoError(t, beaconState.SetValidators([]*ethpb.Validator{validator()}))
|
||||||
|
require.NoError(t, beaconState.SetBalances([]uint64{1, 2, 3}))
|
||||||
|
randaoMixes, err := util.PrepareRoots(int(params.BeaconConfig().EpochsPerHistoricalVector))
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, beaconState.SetRandaoMixes(randaoMixes))
|
||||||
|
require.NoError(t, beaconState.SetSlashings([]uint64{1, 2, 3}))
|
||||||
|
require.NoError(t, beaconState.SetPreviousParticipationBits([]byte{1, 2, 3}))
|
||||||
|
require.NoError(t, beaconState.SetCurrentParticipationBits([]byte{1, 2, 3}))
|
||||||
|
require.NoError(t, beaconState.SetJustificationBits(justificationBits()))
|
||||||
|
require.NoError(t, beaconState.SetPreviousJustifiedCheckpoint(checkpoint("previous")))
|
||||||
|
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(checkpoint("current")))
|
||||||
|
require.NoError(t, beaconState.SetFinalizedCheckpoint(checkpoint("finalized")))
|
||||||
|
require.NoError(t, beaconState.SetInactivityScores([]uint64{1, 2, 3}))
|
||||||
|
require.NoError(t, beaconState.SetCurrentSyncCommittee(syncCommittee("current")))
|
||||||
|
require.NoError(t, beaconState.SetNextSyncCommittee(syncCommittee("next")))
|
||||||
|
require.NoError(t, beaconState.SetLatestExecutionPayloadHeader(executionPayloadHeader()))
|
||||||
|
|
||||||
|
v1State, ok := beaconState.(*v3.BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
protoState, ok := v1State.InnerStateUnsafe().(*ethpb.BeaconStateBellatrix)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
initState, err := state_native.InitializeFromProtoBellatrix(protoState)
|
||||||
|
require.NoError(t, err)
|
||||||
|
s, ok := initState.(*state_native.BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
|
||||||
|
root, err := state_native.ComputeFieldRootsWithHasher(context.Background(), s)
|
||||||
|
require.NoError(t, err)
|
||||||
|
expected := [][]byte{
|
||||||
|
{0x7b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||||
|
{0x67, 0x76, 0x72, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||||
|
{0x7b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||||
|
{0x58, 0xba, 0xf, 0x9b, 0x4f, 0x63, 0x1c, 0xa6, 0x19, 0xb1, 0xa2, 0x1f, 0xd1, 0x29, 0xc7, 0x67, 0x9c, 0x32, 0x4, 0x1f, 0xcf, 0x4e, 0x64, 0x9b, 0x8f, 0x21, 0xb4, 0xe6, 0xa5, 0xc9, 0xc, 0x38},
|
||||||
|
{0x8b, 0x5, 0x59, 0x78, 0xed, 0xbe, 0x2c, 0xde, 0xa6, 0xf, 0x52, 0xdc, 0x16, 0x83, 0xa0, 0x5d, 0x8, 0xc3, 0x37, 0x91, 0x3a, 0xf6, 0xfa, 0x6, 0x62, 0xc9, 0x6, 0xb1, 0x41, 0x48, 0xaf, 0xec},
|
||||||
|
{0xcc, 0xa1, 0x69, 0xa8, 0x8b, 0x1e, 0x49, 0x5, 0x1f, 0xe4, 0xd8, 0xff, 0x82, 0xa2, 0x2e, 0xf0, 0x54, 0xd1, 0x13, 0xc9, 0x8e, 0xb9, 0x82, 0xa6, 0x9e, 0x42, 0x2, 0xec, 0x97, 0x6f, 0x33, 0x88},
|
||||||
|
{0xcc, 0xa1, 0x69, 0xa8, 0x8b, 0x1e, 0x49, 0x5, 0x1f, 0xe4, 0xd8, 0xff, 0x82, 0xa2, 0x2e, 0xf0, 0x54, 0xd1, 0x13, 0xc9, 0x8e, 0xb9, 0x82, 0xa6, 0x9e, 0x42, 0x2, 0xec, 0x97, 0x6f, 0x33, 0x88},
|
||||||
|
{0xf, 0xad, 0xd3, 0x92, 0x4b, 0xda, 0xfa, 0xc6, 0x61, 0x50, 0xb7, 0xdf, 0x5f, 0x2c, 0xd0, 0x94, 0xc3, 0xaf, 0x41, 0x9d, 0xa, 0xea, 0x50, 0x96, 0x82, 0x62, 0x1c, 0x72, 0x26, 0x20, 0x6b, 0xac},
|
||||||
|
{0xc9, 0x4e, 0x2c, 0xb0, 0x20, 0xe3, 0xe7, 0x8c, 0x5c, 0xbd, 0xeb, 0x9b, 0xa5, 0x7b, 0x53, 0x50, 0xca, 0xfe, 0xe9, 0x48, 0x9e, 0x8d, 0xf8, 0x4a, 0xe6, 0x8d, 0x9c, 0x97, 0x81, 0x74, 0xb, 0x5e},
|
||||||
|
{0x71, 0x52, 0xd2, 0x9b, 0x87, 0x3c, 0x8a, 0xd9, 0x51, 0x55, 0xc0, 0x42, 0xb, 0xc4, 0x12, 0xa4, 0x79, 0xf5, 0x7d, 0x37, 0x16, 0xf4, 0x90, 0x72, 0x5d, 0xe0, 0x34, 0xb4, 0x2, 0x8c, 0x39, 0xe4},
|
||||||
|
{0x7b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||||
|
{0xf, 0xf7, 0x4f, 0xe1, 0xa9, 0x72, 0x9c, 0x95, 0xf0, 0xe1, 0xde, 0xa4, 0x32, 0xc, 0x67, 0x52, 0x23, 0x13, 0x9e, 0xe2, 0x40, 0x8d, 0xf6, 0x18, 0x57, 0xf0, 0x1a, 0x4a, 0xad, 0x46, 0xce, 0x42},
|
||||||
|
{0xf9, 0x11, 0x2c, 0xc2, 0x71, 0x70, 0xde, 0x47, 0x26, 0xeb, 0x26, 0xd4, 0xa4, 0xe8, 0x68, 0xb, 0x16, 0xa2, 0x6e, 0x52, 0x54, 0xe, 0x5c, 0x83, 0x17, 0x3, 0xea, 0xdd, 0xd5, 0xa7, 0xb2, 0x3f},
|
||||||
|
{0x64, 0xbd, 0x40, 0xa7, 0x10, 0x44, 0x84, 0xed, 0xf3, 0x5f, 0xc3, 0x5d, 0x7b, 0xbe, 0xe8, 0x75, 0xbf, 0x66, 0xcb, 0xce, 0x77, 0xfa, 0x0, 0x3, 0xdd, 0xfb, 0x80, 0xd2, 0x77, 0x1b, 0xc2, 0x8},
|
||||||
|
{0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||||
|
{0x75, 0xb2, 0xae, 0x1d, 0xd8, 0xca, 0xe6, 0x4d, 0xa8, 0xc5, 0xc9, 0x19, 0x8, 0x96, 0xaf, 0x9b, 0xe6, 0xf6, 0x99, 0xb9, 0x58, 0x56, 0x5b, 0x25, 0xea, 0x9c, 0x86, 0x5e, 0x96, 0x6a, 0x48, 0xb},
|
||||||
|
{0x75, 0xb2, 0xae, 0x1d, 0xd8, 0xca, 0xe6, 0x4d, 0xa8, 0xc5, 0xc9, 0x19, 0x8, 0x96, 0xaf, 0x9b, 0xe6, 0xf6, 0x99, 0xb9, 0x58, 0x56, 0x5b, 0x25, 0xea, 0x9c, 0x86, 0x5e, 0x96, 0x6a, 0x48, 0xb},
|
||||||
|
{0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||||
|
{0x76, 0x88, 0xa0, 0x68, 0x45, 0x25, 0x8f, 0xd5, 0xf9, 0xb2, 0xb0, 0x42, 0x68, 0x6b, 0x51, 0xcc, 0x29, 0x94, 0x63, 0x85, 0xec, 0xf5, 0x47, 0xf0, 0x9c, 0x46, 0x86, 0xa9, 0x99, 0x7d, 0x29, 0x6c},
|
||||||
|
{0x41, 0x44, 0x52, 0xff, 0x8c, 0xa6, 0xb3, 0x2e, 0xcc, 0x5e, 0x63, 0x8f, 0x8e, 0x7d, 0xe7, 0x52, 0x42, 0x94, 0x55, 0x2f, 0x89, 0xdd, 0x1e, 0x3c, 0xb0, 0xf4, 0x51, 0x51, 0x36, 0x81, 0x72, 0x1},
|
||||||
|
{0xa9, 0xbb, 0x6a, 0x1f, 0x5d, 0x86, 0x7d, 0xa7, 0x5a, 0x7d, 0x9d, 0x8d, 0xc0, 0x15, 0xb7, 0x0, 0xee, 0xa9, 0x68, 0x51, 0x88, 0x57, 0x5a, 0xd9, 0x4e, 0x1d, 0x8e, 0x44, 0xbf, 0xdc, 0x73, 0xff},
|
||||||
|
{0xf9, 0x11, 0x2c, 0xc2, 0x71, 0x70, 0xde, 0x47, 0x26, 0xeb, 0x26, 0xd4, 0xa4, 0xe8, 0x68, 0xb, 0x16, 0xa2, 0x6e, 0x52, 0x54, 0xe, 0x5c, 0x83, 0x17, 0x3, 0xea, 0xdd, 0xd5, 0xa7, 0xb2, 0x3f},
|
||||||
|
{0x3d, 0xf3, 0x66, 0xd4, 0x12, 0x40, 0x3f, 0x28, 0xeb, 0xe4, 0x19, 0x59, 0xae, 0xab, 0x4d, 0xf3, 0x98, 0x88, 0x7f, 0x1e, 0x58, 0xa, 0x5d, 0xd4, 0xeb, 0xe5, 0x5d, 0x3d, 0x11, 0x70, 0x24, 0x76},
|
||||||
|
{0xd6, 0x4c, 0xb1, 0xac, 0x61, 0x7, 0x26, 0xbb, 0xd3, 0x27, 0x2a, 0xcd, 0xdd, 0x55, 0xf, 0x2b, 0x6a, 0xe8, 0x1, 0x31, 0x48, 0x66, 0x2f, 0x98, 0x7b, 0x6d, 0x27, 0x69, 0xd9, 0x40, 0xcc, 0x37},
|
||||||
|
{0xbc, 0xbb, 0x39, 0x57, 0x61, 0x1d, 0x54, 0xd6, 0x1b, 0xfe, 0x7a, 0xbd, 0x29, 0x52, 0x57, 0xdd, 0x19, 0x1, 0x89, 0x22, 0x7d, 0xdf, 0x7b, 0x53, 0x9f, 0xb, 0x46, 0x5, 0x9f, 0x80, 0xcc, 0x8e},
|
||||||
|
}
|
||||||
|
assert.DeepEqual(t, expected, root)
|
||||||
|
}
|
||||||
|
|
||||||
|
func genesisValidatorsRoot() []byte {
|
||||||
|
gvr := bytesutil.ToBytes32([]byte("gvr"))
|
||||||
|
return gvr[:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func fork() *ethpb.Fork {
|
||||||
|
prev := bytesutil.ToBytes4([]byte("prev"))
|
||||||
|
curr := bytesutil.ToBytes4([]byte("curr"))
|
||||||
|
return ðpb.Fork{
|
||||||
|
PreviousVersion: prev[:],
|
||||||
|
CurrentVersion: curr[:],
|
||||||
|
Epoch: 123,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func latestBlockHeader() *ethpb.BeaconBlockHeader {
|
||||||
|
pr := bytesutil.ToBytes32([]byte("parent"))
|
||||||
|
sr := bytesutil.ToBytes32([]byte("state"))
|
||||||
|
br := bytesutil.ToBytes32([]byte("body"))
|
||||||
|
return ðpb.BeaconBlockHeader{
|
||||||
|
Slot: 123,
|
||||||
|
ProposerIndex: 123,
|
||||||
|
ParentRoot: pr[:],
|
||||||
|
StateRoot: sr[:],
|
||||||
|
BodyRoot: br[:],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func eth1Data() *ethpb.Eth1Data {
|
||||||
|
dr := bytesutil.ToBytes32([]byte("deposit"))
|
||||||
|
bh := bytesutil.ToBytes32([]byte("block"))
|
||||||
|
return ðpb.Eth1Data{
|
||||||
|
DepositRoot: dr[:],
|
||||||
|
DepositCount: 123,
|
||||||
|
BlockHash: bh[:],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func validator() *ethpb.Validator {
|
||||||
|
pk := bytesutil.ToBytes48([]byte("public"))
|
||||||
|
wc := bytesutil.ToBytes32([]byte("withdrawal"))
|
||||||
|
return ðpb.Validator{
|
||||||
|
PublicKey: pk[:],
|
||||||
|
WithdrawalCredentials: wc[:],
|
||||||
|
EffectiveBalance: 123,
|
||||||
|
Slashed: true,
|
||||||
|
ActivationEligibilityEpoch: 123,
|
||||||
|
ActivationEpoch: 123,
|
||||||
|
ExitEpoch: 123,
|
||||||
|
WithdrawableEpoch: 123,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func pendingAttestation(prefix string) *ethpb.PendingAttestation {
|
||||||
|
bbr := bytesutil.ToBytes32([]byte(prefix + "beacon"))
|
||||||
|
r := bytesutil.ToBytes32([]byte(prefix + "root"))
|
||||||
|
return ðpb.PendingAttestation{
|
||||||
|
AggregationBits: bitfield.Bitlist{0x00, 0xFF, 0xFF, 0xFF},
|
||||||
|
Data: ðpb.AttestationData{
|
||||||
|
Slot: 123,
|
||||||
|
CommitteeIndex: 123,
|
||||||
|
BeaconBlockRoot: bbr[:],
|
||||||
|
Source: ðpb.Checkpoint{
|
||||||
|
Epoch: 123,
|
||||||
|
Root: r[:],
|
||||||
|
},
|
||||||
|
Target: ðpb.Checkpoint{
|
||||||
|
Epoch: 123,
|
||||||
|
Root: r[:],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InclusionDelay: 123,
|
||||||
|
ProposerIndex: 123,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func justificationBits() bitfield.Bitvector4 {
|
||||||
|
v := bitfield.NewBitvector4()
|
||||||
|
v.SetBitAt(1, true)
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkpoint(prefix string) *ethpb.Checkpoint {
|
||||||
|
r := bytesutil.ToBytes32([]byte(prefix + "root"))
|
||||||
|
return ðpb.Checkpoint{
|
||||||
|
Epoch: 123,
|
||||||
|
Root: r[:],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func syncCommittee(prefix string) *ethpb.SyncCommittee {
|
||||||
|
pubkeys := make([][]byte, params.BeaconConfig().SyncCommitteeSize)
|
||||||
|
for i := range pubkeys {
|
||||||
|
key := bytesutil.ToBytes48([]byte(prefix + "pubkey"))
|
||||||
|
pubkeys[i] = key[:]
|
||||||
|
}
|
||||||
|
agg := bytesutil.ToBytes48([]byte(prefix + "aggregate"))
|
||||||
|
return ðpb.SyncCommittee{
|
||||||
|
Pubkeys: pubkeys,
|
||||||
|
AggregatePubkey: agg[:],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func executionPayloadHeader() *ethpb.ExecutionPayloadHeader {
|
||||||
|
ph := bytesutil.ToBytes32([]byte("parent"))
|
||||||
|
fr := bytesutil.PadTo([]byte("fee"), 20)
|
||||||
|
sr := bytesutil.ToBytes32([]byte("state"))
|
||||||
|
rr := bytesutil.ToBytes32([]byte("receipts"))
|
||||||
|
lb := bytesutil.PadTo([]byte("logs"), 256)
|
||||||
|
pr := bytesutil.ToBytes32([]byte("prev"))
|
||||||
|
ed := bytesutil.ToBytes32([]byte("extra"))
|
||||||
|
bf := bytesutil.ToBytes32([]byte("base"))
|
||||||
|
bh := bytesutil.ToBytes32([]byte("block"))
|
||||||
|
tr := bytesutil.ToBytes32([]byte("transactions"))
|
||||||
|
return ðpb.ExecutionPayloadHeader{
|
||||||
|
ParentHash: ph[:],
|
||||||
|
FeeRecipient: fr,
|
||||||
|
StateRoot: sr[:],
|
||||||
|
ReceiptsRoot: rr[:],
|
||||||
|
LogsBloom: lb,
|
||||||
|
PrevRandao: pr[:],
|
||||||
|
BlockNumber: 0,
|
||||||
|
GasLimit: 0,
|
||||||
|
GasUsed: 0,
|
||||||
|
Timestamp: 0,
|
||||||
|
ExtraData: ed[:],
|
||||||
|
BaseFeePerGas: bf[:],
|
||||||
|
BlockHash: bh[:],
|
||||||
|
TransactionsRoot: tr[:],
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
package v3
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/fieldtrie"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/fieldtrie"
|
||||||
|
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -18,19 +20,32 @@ func FinalizedRootGeneralizedIndex() uint64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CurrentSyncCommitteeGeneralizedIndex for the beacon state.
|
// CurrentSyncCommitteeGeneralizedIndex for the beacon state.
|
||||||
func CurrentSyncCommitteeGeneralizedIndex() uint64 {
|
func (b *BeaconState) CurrentSyncCommitteeGeneralizedIndex() (uint64, error) {
|
||||||
return uint64(currentSyncCommittee)
|
if b.version == version.Phase0 {
|
||||||
|
return 0, errNotSupported("CurrentSyncCommitteeGeneralizedIndex", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
|
return uint64(nativetypes.CurrentSyncCommittee.RealPosition()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NextSyncCommitteeGeneralizedIndex for the beacon state.
|
// NextSyncCommitteeGeneralizedIndex for the beacon state.
|
||||||
func NextSyncCommitteeGeneralizedIndex() uint64 {
|
func (b *BeaconState) NextSyncCommitteeGeneralizedIndex() (uint64, error) {
|
||||||
return uint64(nextSyncCommittee)
|
if b.version == version.Phase0 {
|
||||||
|
return 0, errNotSupported("NextSyncCommitteeGeneralizedIndex", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
|
return uint64(nativetypes.NextSyncCommittee.RealPosition()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CurrentSyncCommitteeProof from the state's Merkle trie representation.
|
// CurrentSyncCommitteeProof from the state's Merkle trie representation.
|
||||||
func (b *BeaconState) CurrentSyncCommitteeProof(ctx context.Context) ([][]byte, error) {
|
func (b *BeaconState) CurrentSyncCommitteeProof(ctx context.Context) ([][]byte, error) {
|
||||||
b.lock.Lock()
|
b.lock.Lock()
|
||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
|
if b.version == version.Phase0 {
|
||||||
|
return nil, errNotSupported("CurrentSyncCommitteeProof", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
// In case the Merkle layers of the trie are not populated, we need
|
// In case the Merkle layers of the trie are not populated, we need
|
||||||
// to perform some initialization.
|
// to perform some initialization.
|
||||||
if err := b.initializeMerkleLayers(ctx); err != nil {
|
if err := b.initializeMerkleLayers(ctx); err != nil {
|
||||||
@@ -41,20 +56,25 @@ func (b *BeaconState) CurrentSyncCommitteeProof(ctx context.Context) ([][]byte,
|
|||||||
if err := b.recomputeDirtyFields(ctx); err != nil {
|
if err := b.recomputeDirtyFields(ctx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return fieldtrie.ProofFromMerkleLayers(b.merkleLayers, currentSyncCommittee), nil
|
return fieldtrie.ProofFromMerkleLayers(b.merkleLayers, nativetypes.CurrentSyncCommittee.RealPosition()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NextSyncCommitteeProof from the state's Merkle trie representation.
|
// NextSyncCommitteeProof from the state's Merkle trie representation.
|
||||||
func (b *BeaconState) NextSyncCommitteeProof(ctx context.Context) ([][]byte, error) {
|
func (b *BeaconState) NextSyncCommitteeProof(ctx context.Context) ([][]byte, error) {
|
||||||
b.lock.Lock()
|
b.lock.Lock()
|
||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
|
if b.version == version.Phase0 {
|
||||||
|
return nil, errNotSupported("NextSyncCommitteeProof", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
if err := b.initializeMerkleLayers(ctx); err != nil {
|
if err := b.initializeMerkleLayers(ctx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := b.recomputeDirtyFields(ctx); err != nil {
|
if err := b.recomputeDirtyFields(ctx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return fieldtrie.ProofFromMerkleLayers(b.merkleLayers, nextSyncCommittee), nil
|
return fieldtrie.ProofFromMerkleLayers(b.merkleLayers, nativetypes.NextSyncCommittee.RealPosition()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FinalizedRootProof crafts a Merkle proof for the finalized root
|
// FinalizedRootProof crafts a Merkle proof for the finalized root
|
||||||
@@ -62,13 +82,18 @@ func (b *BeaconState) NextSyncCommitteeProof(ctx context.Context) ([][]byte, err
|
|||||||
func (b *BeaconState) FinalizedRootProof(ctx context.Context) ([][]byte, error) {
|
func (b *BeaconState) FinalizedRootProof(ctx context.Context) ([][]byte, error) {
|
||||||
b.lock.Lock()
|
b.lock.Lock()
|
||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
|
if b.version == version.Phase0 {
|
||||||
|
return nil, errNotSupported("FinalizedRootProof", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
if err := b.initializeMerkleLayers(ctx); err != nil {
|
if err := b.initializeMerkleLayers(ctx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := b.recomputeDirtyFields(ctx); err != nil {
|
if err := b.recomputeDirtyFields(ctx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cpt := b.finalizedCheckpoint
|
cpt := b.finalizedCheckpointVal()
|
||||||
// The epoch field of a finalized checkpoint is the neighbor
|
// The epoch field of a finalized checkpoint is the neighbor
|
||||||
// index of the finalized root field in its Merkle tree representation
|
// index of the finalized root field in its Merkle tree representation
|
||||||
// of the checkpoint. This neighbor is the first element added to the proof.
|
// of the checkpoint. This neighbor is the first element added to the proof.
|
||||||
@@ -77,7 +102,7 @@ func (b *BeaconState) FinalizedRootProof(ctx context.Context) ([][]byte, error)
|
|||||||
epochRoot := bytesutil.ToBytes32(epochBuf)
|
epochRoot := bytesutil.ToBytes32(epochBuf)
|
||||||
proof := make([][]byte, 0)
|
proof := make([][]byte, 0)
|
||||||
proof = append(proof, epochRoot[:])
|
proof = append(proof, epochRoot[:])
|
||||||
branch := fieldtrie.ProofFromMerkleLayers(b.merkleLayers, finalizedCheckpoint)
|
branch := fieldtrie.ProofFromMerkleLayers(b.merkleLayers, nativetypes.FinalizedCheckpoint.RealPosition())
|
||||||
proof = append(proof, branch...)
|
proof = append(proof, branch...)
|
||||||
return proof, nil
|
return proof, nil
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
package v1_test
|
package state_native_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/v1"
|
statenative "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native"
|
||||||
"github.com/prysmaticlabs/prysm/container/trie"
|
"github.com/prysmaticlabs/prysm/container/trie"
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
@@ -27,7 +27,7 @@ func TestBeaconStateMerkleProofs(t *testing.T) {
|
|||||||
finalizedRoot := st.FinalizedCheckpoint().Root
|
finalizedRoot := st.FinalizedCheckpoint().Root
|
||||||
proof, err := st.FinalizedRootProof(ctx)
|
proof, err := st.FinalizedRootProof(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
gIndex := v1.FinalizedRootGeneralizedIndex()
|
gIndex := statenative.FinalizedRootGeneralizedIndex()
|
||||||
valid := trie.VerifyMerkleProof(htr[:], finalizedRoot, gIndex, proof)
|
valid := trie.VerifyMerkleProof(htr[:], finalizedRoot, gIndex, proof)
|
||||||
require.Equal(t, true, valid)
|
require.Equal(t, true, valid)
|
||||||
})
|
})
|
||||||
@@ -51,7 +51,7 @@ func TestBeaconStateMerkleProofs(t *testing.T) {
|
|||||||
// changed and should have been marked as a dirty state field.
|
// changed and should have been marked as a dirty state field.
|
||||||
// The proof validity should be false for the old root, but true for the new.
|
// The proof validity should be false for the old root, but true for the new.
|
||||||
finalizedRoot := st.FinalizedCheckpoint().Root
|
finalizedRoot := st.FinalizedCheckpoint().Root
|
||||||
gIndex := v1.FinalizedRootGeneralizedIndex()
|
gIndex := statenative.FinalizedRootGeneralizedIndex()
|
||||||
valid := trie.VerifyMerkleProof(currentRoot[:], finalizedRoot, gIndex, proof)
|
valid := trie.VerifyMerkleProof(currentRoot[:], finalizedRoot, gIndex, proof)
|
||||||
require.Equal(t, false, valid)
|
require.Equal(t, false, valid)
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package v1
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package v1_test
|
package state_native_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/v1"
|
statenative "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
@@ -12,63 +12,63 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestReadOnlyValidator_ReturnsErrorOnNil(t *testing.T) {
|
func TestReadOnlyValidator_ReturnsErrorOnNil(t *testing.T) {
|
||||||
if _, err := v1.NewValidator(nil); err != v1.ErrNilWrappedValidator {
|
if _, err := statenative.NewValidator(nil); err != statenative.ErrNilWrappedValidator {
|
||||||
t.Errorf("Wrong error returned. Got %v, wanted %v", err, v1.ErrNilWrappedValidator)
|
t.Errorf("Wrong error returned. Got %v, wanted %v", err, statenative.ErrNilWrappedValidator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReadOnlyValidator_EffectiveBalance(t *testing.T) {
|
func TestReadOnlyValidator_EffectiveBalance(t *testing.T) {
|
||||||
bal := uint64(234)
|
bal := uint64(234)
|
||||||
v, err := v1.NewValidator(ðpb.Validator{EffectiveBalance: bal})
|
v, err := statenative.NewValidator(ðpb.Validator{EffectiveBalance: bal})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, bal, v.EffectiveBalance())
|
assert.Equal(t, bal, v.EffectiveBalance())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReadOnlyValidator_ActivationEligibilityEpoch(t *testing.T) {
|
func TestReadOnlyValidator_ActivationEligibilityEpoch(t *testing.T) {
|
||||||
epoch := types.Epoch(234)
|
epoch := types.Epoch(234)
|
||||||
v, err := v1.NewValidator(ðpb.Validator{ActivationEligibilityEpoch: epoch})
|
v, err := statenative.NewValidator(ðpb.Validator{ActivationEligibilityEpoch: epoch})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, epoch, v.ActivationEligibilityEpoch())
|
assert.Equal(t, epoch, v.ActivationEligibilityEpoch())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReadOnlyValidator_ActivationEpoch(t *testing.T) {
|
func TestReadOnlyValidator_ActivationEpoch(t *testing.T) {
|
||||||
epoch := types.Epoch(234)
|
epoch := types.Epoch(234)
|
||||||
v, err := v1.NewValidator(ðpb.Validator{ActivationEpoch: epoch})
|
v, err := statenative.NewValidator(ðpb.Validator{ActivationEpoch: epoch})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, epoch, v.ActivationEpoch())
|
assert.Equal(t, epoch, v.ActivationEpoch())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReadOnlyValidator_WithdrawableEpoch(t *testing.T) {
|
func TestReadOnlyValidator_WithdrawableEpoch(t *testing.T) {
|
||||||
epoch := types.Epoch(234)
|
epoch := types.Epoch(234)
|
||||||
v, err := v1.NewValidator(ðpb.Validator{WithdrawableEpoch: epoch})
|
v, err := statenative.NewValidator(ðpb.Validator{WithdrawableEpoch: epoch})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, epoch, v.WithdrawableEpoch())
|
assert.Equal(t, epoch, v.WithdrawableEpoch())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReadOnlyValidator_ExitEpoch(t *testing.T) {
|
func TestReadOnlyValidator_ExitEpoch(t *testing.T) {
|
||||||
epoch := types.Epoch(234)
|
epoch := types.Epoch(234)
|
||||||
v, err := v1.NewValidator(ðpb.Validator{ExitEpoch: epoch})
|
v, err := statenative.NewValidator(ðpb.Validator{ExitEpoch: epoch})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, epoch, v.ExitEpoch())
|
assert.Equal(t, epoch, v.ExitEpoch())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReadOnlyValidator_PublicKey(t *testing.T) {
|
func TestReadOnlyValidator_PublicKey(t *testing.T) {
|
||||||
key := [fieldparams.BLSPubkeyLength]byte{0xFA, 0xCC}
|
key := [fieldparams.BLSPubkeyLength]byte{0xFA, 0xCC}
|
||||||
v, err := v1.NewValidator(ðpb.Validator{PublicKey: key[:]})
|
v, err := statenative.NewValidator(ðpb.Validator{PublicKey: key[:]})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, key, v.PublicKey())
|
assert.Equal(t, key, v.PublicKey())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReadOnlyValidator_WithdrawalCredentials(t *testing.T) {
|
func TestReadOnlyValidator_WithdrawalCredentials(t *testing.T) {
|
||||||
creds := []byte{0xFA, 0xCC}
|
creds := []byte{0xFA, 0xCC}
|
||||||
v, err := v1.NewValidator(ðpb.Validator{WithdrawalCredentials: creds})
|
v, err := statenative.NewValidator(ðpb.Validator{WithdrawalCredentials: creds})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.DeepEqual(t, creds, v.WithdrawalCredentials())
|
assert.DeepEqual(t, creds, v.WithdrawalCredentials())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReadOnlyValidator_Slashed(t *testing.T) {
|
func TestReadOnlyValidator_Slashed(t *testing.T) {
|
||||||
slashed := true
|
slashed := true
|
||||||
v, err := v1.NewValidator(ðpb.Validator{Slashed: slashed})
|
v, err := statenative.NewValidator(ðpb.Validator{Slashed: slashed})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, slashed, v.Slashed())
|
assert.Equal(t, slashed, v.Slashed())
|
||||||
}
|
}
|
||||||
715
beacon-chain/state/state-native/references_test.go
Normal file
715
beacon-chain/state/state-native/references_test.go
Normal file
@@ -0,0 +1,715 @@
|
|||||||
|
package state_native
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"runtime"
|
||||||
|
"runtime/debug"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/prysmaticlabs/go-bitfield"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
|
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
|
||||||
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
|
"github.com/prysmaticlabs/prysm/testing/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestStateReferenceSharing_Finalizer_Phase0(t *testing.T) {
|
||||||
|
// This test showcases the logic on the RandaoMixes field with the GC finalizer.
|
||||||
|
|
||||||
|
s, err := InitializeFromProtoUnsafePhase0(ðpb.BeaconState{RandaoMixes: [][]byte{[]byte("foo")}})
|
||||||
|
require.NoError(t, err)
|
||||||
|
a, ok := s.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
assert.Equal(t, uint(1), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected a single reference for RANDAO mixes")
|
||||||
|
|
||||||
|
func() {
|
||||||
|
// Create object in a different scope for GC
|
||||||
|
b := a.Copy()
|
||||||
|
assert.Equal(t, uint(2), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 references to RANDAO mixes")
|
||||||
|
_ = b
|
||||||
|
}()
|
||||||
|
|
||||||
|
runtime.GC() // Should run finalizer on object b
|
||||||
|
assert.Equal(t, uint(1), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 1 shared reference to RANDAO mixes!")
|
||||||
|
|
||||||
|
copied := a.Copy()
|
||||||
|
b, ok := copied.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
assert.Equal(t, uint(2), b.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 shared references to RANDAO mixes")
|
||||||
|
require.NoError(t, b.UpdateRandaoMixesAtIndex(0, []byte("bar")))
|
||||||
|
if b.sharedFieldReferences[nativetypes.RandaoMixes].Refs() != 1 || a.sharedFieldReferences[nativetypes.RandaoMixes].Refs() != 1 {
|
||||||
|
t.Error("Expected 1 shared reference to RANDAO mix for both a and b")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStateReferenceSharing_Finalizer_Altair(t *testing.T) {
|
||||||
|
// This test showcases the logic on the RandaoMixes field with the GC finalizer.
|
||||||
|
|
||||||
|
s, err := InitializeFromProtoUnsafeAltair(ðpb.BeaconStateAltair{RandaoMixes: [][]byte{[]byte("foo")}})
|
||||||
|
require.NoError(t, err)
|
||||||
|
a, ok := s.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
assert.Equal(t, uint(1), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected a single reference for RANDAO mixes")
|
||||||
|
|
||||||
|
func() {
|
||||||
|
// Create object in a different scope for GC
|
||||||
|
b := a.Copy()
|
||||||
|
assert.Equal(t, uint(2), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 references to RANDAO mixes")
|
||||||
|
_ = b
|
||||||
|
}()
|
||||||
|
|
||||||
|
runtime.GC() // Should run finalizer on object b
|
||||||
|
assert.Equal(t, uint(1), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 1 shared reference to RANDAO mixes!")
|
||||||
|
|
||||||
|
copied := a.Copy()
|
||||||
|
b, ok := copied.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
assert.Equal(t, uint(2), b.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 shared references to RANDAO mixes")
|
||||||
|
require.NoError(t, b.UpdateRandaoMixesAtIndex(0, []byte("bar")))
|
||||||
|
if b.sharedFieldReferences[nativetypes.RandaoMixes].Refs() != 1 || a.sharedFieldReferences[nativetypes.RandaoMixes].Refs() != 1 {
|
||||||
|
t.Error("Expected 1 shared reference to RANDAO mix for both a and b")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStateReferenceSharing_Finalizer_Bellatrix(t *testing.T) {
|
||||||
|
// This test showcases the logic on the RandaoMixes field with the GC finalizer.
|
||||||
|
|
||||||
|
s, err := InitializeFromProtoUnsafeBellatrix(ðpb.BeaconStateBellatrix{RandaoMixes: [][]byte{[]byte("foo")}})
|
||||||
|
require.NoError(t, err)
|
||||||
|
a, ok := s.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
assert.Equal(t, uint(1), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected a single reference for RANDAO mixes")
|
||||||
|
|
||||||
|
func() {
|
||||||
|
// Create object in a different scope for GC
|
||||||
|
b := a.Copy()
|
||||||
|
assert.Equal(t, uint(2), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 references to RANDAO mixes")
|
||||||
|
_ = b
|
||||||
|
}()
|
||||||
|
|
||||||
|
runtime.GC() // Should run finalizer on object b
|
||||||
|
assert.Equal(t, uint(1), a.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 1 shared reference to RANDAO mixes!")
|
||||||
|
|
||||||
|
copied := a.Copy()
|
||||||
|
b, ok := copied.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
assert.Equal(t, uint(2), b.sharedFieldReferences[nativetypes.RandaoMixes].Refs(), "Expected 2 shared references to RANDAO mixes")
|
||||||
|
require.NoError(t, b.UpdateRandaoMixesAtIndex(0, []byte("bar")))
|
||||||
|
if b.sharedFieldReferences[nativetypes.RandaoMixes].Refs() != 1 || a.sharedFieldReferences[nativetypes.RandaoMixes].Refs() != 1 {
|
||||||
|
t.Error("Expected 1 shared reference to RANDAO mix for both a and b")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStateReferenceCopy_NoUnexpectedRootsMutation_Phase0(t *testing.T) {
|
||||||
|
root1, root2 := bytesutil.ToBytes32([]byte("foo")), bytesutil.ToBytes32([]byte("bar"))
|
||||||
|
s, err := InitializeFromProtoUnsafePhase0(ðpb.BeaconState{
|
||||||
|
BlockRoots: [][]byte{
|
||||||
|
root1[:],
|
||||||
|
},
|
||||||
|
StateRoots: [][]byte{
|
||||||
|
root1[:],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
a, ok := s.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assertRefCount(t, a, nativetypes.BlockRoots, 1)
|
||||||
|
assertRefCount(t, a, nativetypes.StateRoots, 1)
|
||||||
|
|
||||||
|
// Copy, increases reference count.
|
||||||
|
copied := a.Copy()
|
||||||
|
b, ok := copied.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
assertRefCount(t, a, nativetypes.BlockRoots, 2)
|
||||||
|
assertRefCount(t, a, nativetypes.StateRoots, 2)
|
||||||
|
assertRefCount(t, b, nativetypes.BlockRoots, 2)
|
||||||
|
assertRefCount(t, b, nativetypes.StateRoots, 2)
|
||||||
|
|
||||||
|
// Assert shared state.
|
||||||
|
blockRootsA := a.BlockRoots()
|
||||||
|
stateRootsA := a.StateRoots()
|
||||||
|
blockRootsB := b.BlockRoots()
|
||||||
|
stateRootsB := b.StateRoots()
|
||||||
|
assertValFound(t, blockRootsA, root1[:])
|
||||||
|
assertValFound(t, blockRootsB, root1[:])
|
||||||
|
assertValFound(t, stateRootsA, root1[:])
|
||||||
|
assertValFound(t, stateRootsB, root1[:])
|
||||||
|
|
||||||
|
// Mutator should only affect calling state: a.
|
||||||
|
require.NoError(t, a.UpdateBlockRootAtIndex(0, root2))
|
||||||
|
require.NoError(t, a.UpdateStateRootAtIndex(0, root2))
|
||||||
|
|
||||||
|
// Assert no shared state mutation occurred only on state a (copy on write).
|
||||||
|
assertValNotFound(t, a.BlockRoots(), root1[:])
|
||||||
|
assertValNotFound(t, a.StateRoots(), root1[:])
|
||||||
|
assertValFound(t, a.BlockRoots(), root2[:])
|
||||||
|
assertValFound(t, a.StateRoots(), root2[:])
|
||||||
|
assertValFound(t, b.BlockRoots(), root1[:])
|
||||||
|
assertValFound(t, b.StateRoots(), root1[:])
|
||||||
|
assert.DeepEqual(t, root2[:], a.BlockRoots()[0], "Expected mutation not found")
|
||||||
|
assert.DeepEqual(t, root2[:], a.StateRoots()[0], "Expected mutation not found")
|
||||||
|
assert.DeepEqual(t, root1[:], blockRootsB[0], "Unexpected mutation found")
|
||||||
|
assert.DeepEqual(t, root1[:], stateRootsB[0], "Unexpected mutation found")
|
||||||
|
|
||||||
|
// Copy on write happened, reference counters are reset.
|
||||||
|
assertRefCount(t, a, nativetypes.BlockRoots, 1)
|
||||||
|
assertRefCount(t, a, nativetypes.StateRoots, 1)
|
||||||
|
assertRefCount(t, b, nativetypes.BlockRoots, 1)
|
||||||
|
assertRefCount(t, b, nativetypes.StateRoots, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStateReferenceCopy_NoUnexpectedRootsMutation_Altair(t *testing.T) {
|
||||||
|
root1, root2 := bytesutil.ToBytes32([]byte("foo")), bytesutil.ToBytes32([]byte("bar"))
|
||||||
|
s, err := InitializeFromProtoUnsafeAltair(ðpb.BeaconStateAltair{
|
||||||
|
BlockRoots: [][]byte{
|
||||||
|
root1[:],
|
||||||
|
},
|
||||||
|
StateRoots: [][]byte{
|
||||||
|
root1[:],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
a, ok := s.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assertRefCount(t, a, nativetypes.BlockRoots, 1)
|
||||||
|
assertRefCount(t, a, nativetypes.StateRoots, 1)
|
||||||
|
|
||||||
|
// Copy, increases reference count.
|
||||||
|
copied := a.Copy()
|
||||||
|
b, ok := copied.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
assertRefCount(t, a, nativetypes.BlockRoots, 2)
|
||||||
|
assertRefCount(t, a, nativetypes.StateRoots, 2)
|
||||||
|
assertRefCount(t, b, nativetypes.BlockRoots, 2)
|
||||||
|
assertRefCount(t, b, nativetypes.StateRoots, 2)
|
||||||
|
|
||||||
|
// Assert shared state.
|
||||||
|
blockRootsA := a.BlockRoots()
|
||||||
|
stateRootsA := a.StateRoots()
|
||||||
|
blockRootsB := b.BlockRoots()
|
||||||
|
stateRootsB := b.StateRoots()
|
||||||
|
assertValFound(t, blockRootsA, root1[:])
|
||||||
|
assertValFound(t, blockRootsB, root1[:])
|
||||||
|
assertValFound(t, stateRootsA, root1[:])
|
||||||
|
assertValFound(t, stateRootsB, root1[:])
|
||||||
|
|
||||||
|
// Mutator should only affect calling state: a.
|
||||||
|
require.NoError(t, a.UpdateBlockRootAtIndex(0, root2))
|
||||||
|
require.NoError(t, a.UpdateStateRootAtIndex(0, root2))
|
||||||
|
|
||||||
|
// Assert no shared state mutation occurred only on state a (copy on write).
|
||||||
|
assertValNotFound(t, a.BlockRoots(), root1[:])
|
||||||
|
assertValNotFound(t, a.StateRoots(), root1[:])
|
||||||
|
assertValFound(t, a.BlockRoots(), root2[:])
|
||||||
|
assertValFound(t, a.StateRoots(), root2[:])
|
||||||
|
assertValFound(t, b.BlockRoots(), root1[:])
|
||||||
|
assertValFound(t, b.StateRoots(), root1[:])
|
||||||
|
assert.DeepEqual(t, root2[:], a.BlockRoots()[0], "Expected mutation not found")
|
||||||
|
assert.DeepEqual(t, root2[:], a.StateRoots()[0], "Expected mutation not found")
|
||||||
|
assert.DeepEqual(t, root1[:], blockRootsB[0], "Unexpected mutation found")
|
||||||
|
assert.DeepEqual(t, root1[:], stateRootsB[0], "Unexpected mutation found")
|
||||||
|
|
||||||
|
// Copy on write happened, reference counters are reset.
|
||||||
|
assertRefCount(t, a, nativetypes.BlockRoots, 1)
|
||||||
|
assertRefCount(t, a, nativetypes.StateRoots, 1)
|
||||||
|
assertRefCount(t, b, nativetypes.BlockRoots, 1)
|
||||||
|
assertRefCount(t, b, nativetypes.StateRoots, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStateReferenceCopy_NoUnexpectedRootsMutation_Bellatrix(t *testing.T) {
|
||||||
|
root1, root2 := bytesutil.ToBytes32([]byte("foo")), bytesutil.ToBytes32([]byte("bar"))
|
||||||
|
s, err := InitializeFromProtoUnsafeBellatrix(ðpb.BeaconStateBellatrix{
|
||||||
|
BlockRoots: [][]byte{
|
||||||
|
root1[:],
|
||||||
|
},
|
||||||
|
StateRoots: [][]byte{
|
||||||
|
root1[:],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
a, ok := s.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assertRefCount(t, a, nativetypes.BlockRoots, 1)
|
||||||
|
assertRefCount(t, a, nativetypes.StateRoots, 1)
|
||||||
|
|
||||||
|
// Copy, increases reference count.
|
||||||
|
copied := a.Copy()
|
||||||
|
b, ok := copied.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
assertRefCount(t, a, nativetypes.BlockRoots, 2)
|
||||||
|
assertRefCount(t, a, nativetypes.StateRoots, 2)
|
||||||
|
assertRefCount(t, b, nativetypes.BlockRoots, 2)
|
||||||
|
assertRefCount(t, b, nativetypes.StateRoots, 2)
|
||||||
|
|
||||||
|
// Assert shared state.
|
||||||
|
blockRootsA := a.BlockRoots()
|
||||||
|
stateRootsA := a.StateRoots()
|
||||||
|
blockRootsB := b.BlockRoots()
|
||||||
|
stateRootsB := b.StateRoots()
|
||||||
|
assertValFound(t, blockRootsA, root1[:])
|
||||||
|
assertValFound(t, blockRootsB, root1[:])
|
||||||
|
assertValFound(t, stateRootsA, root1[:])
|
||||||
|
assertValFound(t, stateRootsB, root1[:])
|
||||||
|
|
||||||
|
// Mutator should only affect calling state: a.
|
||||||
|
require.NoError(t, a.UpdateBlockRootAtIndex(0, root2))
|
||||||
|
require.NoError(t, a.UpdateStateRootAtIndex(0, root2))
|
||||||
|
|
||||||
|
// Assert no shared state mutation occurred only on state a (copy on write).
|
||||||
|
assertValNotFound(t, a.BlockRoots(), root1[:])
|
||||||
|
assertValNotFound(t, a.StateRoots(), root1[:])
|
||||||
|
assertValFound(t, a.BlockRoots(), root2[:])
|
||||||
|
assertValFound(t, a.StateRoots(), root2[:])
|
||||||
|
assertValFound(t, b.BlockRoots(), root1[:])
|
||||||
|
assertValFound(t, b.StateRoots(), root1[:])
|
||||||
|
assert.DeepEqual(t, root2[:], a.BlockRoots()[0], "Expected mutation not found")
|
||||||
|
assert.DeepEqual(t, root2[:], a.StateRoots()[0], "Expected mutation not found")
|
||||||
|
assert.DeepEqual(t, root1[:], blockRootsB[0], "Unexpected mutation found")
|
||||||
|
assert.DeepEqual(t, root1[:], stateRootsB[0], "Unexpected mutation found")
|
||||||
|
|
||||||
|
// Copy on write happened, reference counters are reset.
|
||||||
|
assertRefCount(t, a, nativetypes.BlockRoots, 1)
|
||||||
|
assertRefCount(t, a, nativetypes.StateRoots, 1)
|
||||||
|
assertRefCount(t, b, nativetypes.BlockRoots, 1)
|
||||||
|
assertRefCount(t, b, nativetypes.StateRoots, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStateReferenceCopy_NoUnexpectedRandaoMutation_Phase0(t *testing.T) {
|
||||||
|
|
||||||
|
val1, val2 := bytesutil.ToBytes32([]byte("foo")), bytesutil.ToBytes32([]byte("bar"))
|
||||||
|
s, err := InitializeFromProtoUnsafePhase0(ðpb.BeaconState{
|
||||||
|
RandaoMixes: [][]byte{
|
||||||
|
val1[:],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
a, ok := s.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assertRefCount(t, a, nativetypes.RandaoMixes, 1)
|
||||||
|
|
||||||
|
// Copy, increases reference count.
|
||||||
|
copied := a.Copy()
|
||||||
|
b, ok := copied.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
assertRefCount(t, a, nativetypes.RandaoMixes, 2)
|
||||||
|
assertRefCount(t, b, nativetypes.RandaoMixes, 2)
|
||||||
|
|
||||||
|
// Assert shared state.
|
||||||
|
mixesA := a.RandaoMixes()
|
||||||
|
mixesB := b.RandaoMixes()
|
||||||
|
assertValFound(t, mixesA, val1[:])
|
||||||
|
assertValFound(t, mixesB, val1[:])
|
||||||
|
|
||||||
|
// Mutator should only affect calling state: a.
|
||||||
|
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[:])
|
||||||
|
assertValNotFound(t, a.RandaoMixes(), val1[:])
|
||||||
|
assertValFound(t, b.RandaoMixes(), val1[:])
|
||||||
|
assertValNotFound(t, b.RandaoMixes(), val2[:])
|
||||||
|
assertValFound(t, mixesB, val1[:])
|
||||||
|
assertValNotFound(t, mixesB, val2[:])
|
||||||
|
assert.DeepEqual(t, val2[:], a.RandaoMixes()[0], "Expected mutation not found")
|
||||||
|
assert.DeepEqual(t, val1[:], mixesB[0], "Unexpected mutation found")
|
||||||
|
|
||||||
|
// Copy on write happened, reference counters are reset.
|
||||||
|
assertRefCount(t, a, nativetypes.RandaoMixes, 1)
|
||||||
|
assertRefCount(t, b, nativetypes.RandaoMixes, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStateReferenceCopy_NoUnexpectedRandaoMutation_Altair(t *testing.T) {
|
||||||
|
|
||||||
|
val1, val2 := bytesutil.ToBytes32([]byte("foo")), bytesutil.ToBytes32([]byte("bar"))
|
||||||
|
s, err := InitializeFromProtoUnsafeAltair(ðpb.BeaconStateAltair{
|
||||||
|
RandaoMixes: [][]byte{
|
||||||
|
val1[:],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
a, ok := s.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assertRefCount(t, a, nativetypes.RandaoMixes, 1)
|
||||||
|
|
||||||
|
// Copy, increases reference count.
|
||||||
|
copied := a.Copy()
|
||||||
|
b, ok := copied.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
assertRefCount(t, a, nativetypes.RandaoMixes, 2)
|
||||||
|
assertRefCount(t, b, nativetypes.RandaoMixes, 2)
|
||||||
|
|
||||||
|
// Assert shared state.
|
||||||
|
mixesA := a.RandaoMixes()
|
||||||
|
mixesB := b.RandaoMixes()
|
||||||
|
assertValFound(t, mixesA, val1[:])
|
||||||
|
assertValFound(t, mixesB, val1[:])
|
||||||
|
|
||||||
|
// Mutator should only affect calling state: a.
|
||||||
|
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[:])
|
||||||
|
assertValNotFound(t, a.RandaoMixes(), val1[:])
|
||||||
|
assertValFound(t, b.RandaoMixes(), val1[:])
|
||||||
|
assertValNotFound(t, b.RandaoMixes(), val2[:])
|
||||||
|
assertValFound(t, mixesB, val1[:])
|
||||||
|
assertValNotFound(t, mixesB, val2[:])
|
||||||
|
assert.DeepEqual(t, val2[:], a.RandaoMixes()[0], "Expected mutation not found")
|
||||||
|
assert.DeepEqual(t, val1[:], mixesB[0], "Unexpected mutation found")
|
||||||
|
|
||||||
|
// Copy on write happened, reference counters are reset.
|
||||||
|
assertRefCount(t, a, nativetypes.RandaoMixes, 1)
|
||||||
|
assertRefCount(t, b, nativetypes.RandaoMixes, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStateReferenceCopy_NoUnexpectedRandaoMutation_Bellatrix(t *testing.T) {
|
||||||
|
|
||||||
|
val1, val2 := bytesutil.ToBytes32([]byte("foo")), bytesutil.ToBytes32([]byte("bar"))
|
||||||
|
s, err := InitializeFromProtoUnsafeBellatrix(ðpb.BeaconStateBellatrix{
|
||||||
|
RandaoMixes: [][]byte{
|
||||||
|
val1[:],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
a, ok := s.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assertRefCount(t, a, nativetypes.RandaoMixes, 1)
|
||||||
|
|
||||||
|
// Copy, increases reference count.
|
||||||
|
copied := a.Copy()
|
||||||
|
b, ok := copied.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
assertRefCount(t, a, nativetypes.RandaoMixes, 2)
|
||||||
|
assertRefCount(t, b, nativetypes.RandaoMixes, 2)
|
||||||
|
|
||||||
|
// Assert shared state.
|
||||||
|
mixesA := a.RandaoMixes()
|
||||||
|
mixesB := b.RandaoMixes()
|
||||||
|
assertValFound(t, mixesA, val1[:])
|
||||||
|
assertValFound(t, mixesB, val1[:])
|
||||||
|
|
||||||
|
// Mutator should only affect calling state: a.
|
||||||
|
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[:])
|
||||||
|
assertValNotFound(t, a.RandaoMixes(), val1[:])
|
||||||
|
assertValFound(t, b.RandaoMixes(), val1[:])
|
||||||
|
assertValNotFound(t, b.RandaoMixes(), val2[:])
|
||||||
|
assertValFound(t, mixesB, val1[:])
|
||||||
|
assertValNotFound(t, mixesB, val2[:])
|
||||||
|
assert.DeepEqual(t, val2[:], a.RandaoMixes()[0], "Expected mutation not found")
|
||||||
|
assert.DeepEqual(t, val1[:], mixesB[0], "Unexpected mutation found")
|
||||||
|
|
||||||
|
// Copy on write happened, reference counters are reset.
|
||||||
|
assertRefCount(t, a, nativetypes.RandaoMixes, 1)
|
||||||
|
assertRefCount(t, b, nativetypes.RandaoMixes, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStateReferenceCopy_NoUnexpectedAttestationsMutation(t *testing.T) {
|
||||||
|
assertAttFound := func(vals []*ethpb.PendingAttestation, val uint64) {
|
||||||
|
for i := range vals {
|
||||||
|
if reflect.DeepEqual(vals[i].AggregationBits, bitfield.NewBitlist(val)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.Log(string(debug.Stack()))
|
||||||
|
t.Fatalf("Expected attestation not found (%v), want: %v", vals, val)
|
||||||
|
}
|
||||||
|
assertAttNotFound := func(vals []*ethpb.PendingAttestation, val uint64) {
|
||||||
|
for i := range vals {
|
||||||
|
if reflect.DeepEqual(vals[i].AggregationBits, bitfield.NewBitlist(val)) {
|
||||||
|
t.Log(string(debug.Stack()))
|
||||||
|
t.Fatalf("Unexpected attestation found (%v): %v", vals, val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := InitializeFromProtoUnsafePhase0(ðpb.BeaconState{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
a, ok := s.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
assertRefCount(t, a, nativetypes.PreviousEpochAttestations, 1)
|
||||||
|
assertRefCount(t, a, nativetypes.CurrentEpochAttestations, 1)
|
||||||
|
|
||||||
|
// Update initial state.
|
||||||
|
atts := []*ethpb.PendingAttestation{
|
||||||
|
{AggregationBits: bitfield.NewBitlist(1)},
|
||||||
|
{AggregationBits: bitfield.NewBitlist(2)},
|
||||||
|
}
|
||||||
|
a.setPreviousEpochAttestations(atts[:1])
|
||||||
|
a.setCurrentEpochAttestations(atts[:1])
|
||||||
|
curAtt, err := a.CurrentEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, 1, len(curAtt), "Unexpected number of attestations")
|
||||||
|
preAtt, err := a.PreviousEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, 1, len(preAtt), "Unexpected number of attestations")
|
||||||
|
|
||||||
|
// Copy, increases reference count.
|
||||||
|
copied := a.Copy()
|
||||||
|
b, ok := copied.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
assertRefCount(t, a, nativetypes.PreviousEpochAttestations, 2)
|
||||||
|
assertRefCount(t, a, nativetypes.CurrentEpochAttestations, 2)
|
||||||
|
assertRefCount(t, b, nativetypes.PreviousEpochAttestations, 2)
|
||||||
|
assertRefCount(t, b, nativetypes.CurrentEpochAttestations, 2)
|
||||||
|
prevAtts, err := b.PreviousEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, 1, len(prevAtts), "Unexpected number of attestations")
|
||||||
|
currAtts, err := b.CurrentEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, 1, len(currAtts), "Unexpected number of attestations")
|
||||||
|
|
||||||
|
// Assert shared state.
|
||||||
|
currAttsA, err := a.CurrentEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
prevAttsA, err := a.PreviousEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
currAttsB, err := b.CurrentEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
prevAttsB, err := b.PreviousEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
if len(currAttsA) != len(currAttsB) || len(currAttsA) < 1 {
|
||||||
|
t.Errorf("Unexpected number of attestations, want: %v", 1)
|
||||||
|
}
|
||||||
|
if len(prevAttsA) != len(prevAttsB) || len(prevAttsA) < 1 {
|
||||||
|
t.Errorf("Unexpected number of attestations, want: %v", 1)
|
||||||
|
}
|
||||||
|
assertAttFound(currAttsA, 1)
|
||||||
|
assertAttFound(prevAttsA, 1)
|
||||||
|
assertAttFound(currAttsB, 1)
|
||||||
|
assertAttFound(prevAttsB, 1)
|
||||||
|
|
||||||
|
// Extend state attestations.
|
||||||
|
require.NoError(t, a.AppendCurrentEpochAttestations(atts[1]))
|
||||||
|
require.NoError(t, a.AppendPreviousEpochAttestations(atts[1]))
|
||||||
|
curAtt, err = a.CurrentEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, 2, len(curAtt), "Unexpected number of attestations")
|
||||||
|
preAtt, err = a.PreviousEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, 2, len(preAtt), "Unexpected number of attestations")
|
||||||
|
currAttsA, err = a.CurrentEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
prevAttsA, err = a.PreviousEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
currAttsB, err = b.CurrentEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
prevAttsB, err = b.PreviousEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
assertAttFound(currAttsA, 1)
|
||||||
|
assertAttFound(prevAttsA, 1)
|
||||||
|
assertAttFound(currAttsA, 2)
|
||||||
|
assertAttFound(prevAttsA, 2)
|
||||||
|
assertAttFound(currAttsB, 1)
|
||||||
|
assertAttFound(prevAttsB, 1)
|
||||||
|
assertAttNotFound(currAttsB, 2)
|
||||||
|
assertAttNotFound(prevAttsB, 2)
|
||||||
|
|
||||||
|
// Mutator should only affect calling state: a.
|
||||||
|
applyToEveryAttestation := func(state *BeaconState) {
|
||||||
|
// One MUST copy on write.
|
||||||
|
currEpochAtts, err := state.CurrentEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
atts = make([]*ethpb.PendingAttestation, len(currEpochAtts))
|
||||||
|
copy(atts, currEpochAtts)
|
||||||
|
state.setCurrentEpochAttestations(atts)
|
||||||
|
currEpochAtts, err = state.CurrentEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
for i := range currEpochAtts {
|
||||||
|
att := ethpb.CopyPendingAttestation(currEpochAtts[i])
|
||||||
|
att.AggregationBits = bitfield.NewBitlist(3)
|
||||||
|
currEpochAtts[i] = att
|
||||||
|
}
|
||||||
|
state.setCurrentEpochAttestations(currEpochAtts)
|
||||||
|
|
||||||
|
prevEpochAtts, err := state.PreviousEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
atts = make([]*ethpb.PendingAttestation, len(prevEpochAtts))
|
||||||
|
copy(atts, prevEpochAtts)
|
||||||
|
state.setPreviousEpochAttestations(atts)
|
||||||
|
prevEpochAtts, err = state.PreviousEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
for i := range prevEpochAtts {
|
||||||
|
att := ethpb.CopyPendingAttestation(prevEpochAtts[i])
|
||||||
|
att.AggregationBits = bitfield.NewBitlist(3)
|
||||||
|
prevEpochAtts[i] = att
|
||||||
|
}
|
||||||
|
state.setPreviousEpochAttestations(prevEpochAtts)
|
||||||
|
}
|
||||||
|
applyToEveryAttestation(a)
|
||||||
|
|
||||||
|
// Assert no shared state mutation occurred only on state a (copy on write).
|
||||||
|
currAttsA, err = a.CurrentEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
prevAttsA, err = a.PreviousEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
assertAttFound(currAttsA, 3)
|
||||||
|
assertAttFound(prevAttsA, 3)
|
||||||
|
assertAttNotFound(currAttsA, 1)
|
||||||
|
assertAttNotFound(prevAttsA, 1)
|
||||||
|
assertAttNotFound(currAttsA, 2)
|
||||||
|
assertAttNotFound(prevAttsA, 2)
|
||||||
|
// State b must be unaffected.
|
||||||
|
currAttsB, err = b.CurrentEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
prevAttsB, err = b.PreviousEpochAttestations()
|
||||||
|
require.NoError(t, err)
|
||||||
|
assertAttNotFound(currAttsB, 3)
|
||||||
|
assertAttNotFound(prevAttsB, 3)
|
||||||
|
assertAttFound(currAttsB, 1)
|
||||||
|
assertAttFound(prevAttsB, 1)
|
||||||
|
assertAttNotFound(currAttsB, 2)
|
||||||
|
assertAttNotFound(prevAttsB, 2)
|
||||||
|
|
||||||
|
// Copy on write happened, reference counters are reset.
|
||||||
|
assertRefCount(t, a, nativetypes.CurrentEpochAttestations, 1)
|
||||||
|
assertRefCount(t, b, nativetypes.CurrentEpochAttestations, 1)
|
||||||
|
assertRefCount(t, a, nativetypes.PreviousEpochAttestations, 1)
|
||||||
|
assertRefCount(t, b, nativetypes.PreviousEpochAttestations, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidatorReferences_RemainsConsistent_Phase0(t *testing.T) {
|
||||||
|
s, err := InitializeFromProtoUnsafePhase0(ðpb.BeaconState{
|
||||||
|
Validators: []*ethpb.Validator{
|
||||||
|
{PublicKey: []byte{'A'}},
|
||||||
|
{PublicKey: []byte{'B'}},
|
||||||
|
{PublicKey: []byte{'C'}},
|
||||||
|
{PublicKey: []byte{'D'}},
|
||||||
|
{PublicKey: []byte{'E'}},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
a, ok := s.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
|
||||||
|
// Create a second state.
|
||||||
|
copied := a.Copy()
|
||||||
|
b, ok := copied.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
|
||||||
|
// Update First Validator.
|
||||||
|
assert.NoError(t, a.UpdateValidatorAtIndex(0, ðpb.Validator{PublicKey: []byte{'Z'}}))
|
||||||
|
|
||||||
|
assert.DeepNotEqual(t, a.Validators()[0], b.Validators()[0], "validators are equal when they are supposed to be different")
|
||||||
|
// Modify all validators from copied state.
|
||||||
|
assert.NoError(t, b.ApplyToEveryValidator(func(idx int, val *ethpb.Validator) (bool, *ethpb.Validator, error) {
|
||||||
|
return true, ðpb.Validator{PublicKey: []byte{'V'}}, nil
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Ensure reference is properly accounted for.
|
||||||
|
assert.NoError(t, a.ReadFromEveryValidator(func(idx int, val state.ReadOnlyValidator) error {
|
||||||
|
assert.NotEqual(t, bytesutil.ToBytes48([]byte{'V'}), val.PublicKey())
|
||||||
|
return nil
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidatorReferences_RemainsConsistent_Altair(t *testing.T) {
|
||||||
|
s, err := InitializeFromProtoUnsafeAltair(ðpb.BeaconStateAltair{
|
||||||
|
Validators: []*ethpb.Validator{
|
||||||
|
{PublicKey: []byte{'A'}},
|
||||||
|
{PublicKey: []byte{'B'}},
|
||||||
|
{PublicKey: []byte{'C'}},
|
||||||
|
{PublicKey: []byte{'D'}},
|
||||||
|
{PublicKey: []byte{'E'}},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
a, ok := s.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
|
||||||
|
// Create a second state.
|
||||||
|
copied := a.Copy()
|
||||||
|
b, ok := copied.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
|
||||||
|
// Update First Validator.
|
||||||
|
assert.NoError(t, a.UpdateValidatorAtIndex(0, ðpb.Validator{PublicKey: []byte{'Z'}}))
|
||||||
|
|
||||||
|
assert.DeepNotEqual(t, a.Validators()[0], b.Validators()[0], "validators are equal when they are supposed to be different")
|
||||||
|
// Modify all validators from copied state.
|
||||||
|
assert.NoError(t, b.ApplyToEveryValidator(func(idx int, val *ethpb.Validator) (bool, *ethpb.Validator, error) {
|
||||||
|
return true, ðpb.Validator{PublicKey: []byte{'V'}}, nil
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Ensure reference is properly accounted for.
|
||||||
|
assert.NoError(t, a.ReadFromEveryValidator(func(idx int, val state.ReadOnlyValidator) error {
|
||||||
|
assert.NotEqual(t, bytesutil.ToBytes48([]byte{'V'}), val.PublicKey())
|
||||||
|
return nil
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidatorReferences_RemainsConsistent_Bellatrix(t *testing.T) {
|
||||||
|
s, err := InitializeFromProtoUnsafeBellatrix(ðpb.BeaconStateBellatrix{
|
||||||
|
Validators: []*ethpb.Validator{
|
||||||
|
{PublicKey: []byte{'A'}},
|
||||||
|
{PublicKey: []byte{'B'}},
|
||||||
|
{PublicKey: []byte{'C'}},
|
||||||
|
{PublicKey: []byte{'D'}},
|
||||||
|
{PublicKey: []byte{'E'}},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
a, ok := s.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
|
||||||
|
// Create a second state.
|
||||||
|
copied := a.Copy()
|
||||||
|
b, ok := copied.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
|
||||||
|
// Update First Validator.
|
||||||
|
assert.NoError(t, a.UpdateValidatorAtIndex(0, ðpb.Validator{PublicKey: []byte{'Z'}}))
|
||||||
|
|
||||||
|
assert.DeepNotEqual(t, a.Validators()[0], b.Validators()[0], "validators are equal when they are supposed to be different")
|
||||||
|
// Modify all validators from copied state.
|
||||||
|
assert.NoError(t, b.ApplyToEveryValidator(func(idx int, val *ethpb.Validator) (bool, *ethpb.Validator, error) {
|
||||||
|
return true, ðpb.Validator{PublicKey: []byte{'V'}}, nil
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Ensure reference is properly accounted for.
|
||||||
|
assert.NoError(t, a.ReadFromEveryValidator(func(idx int, val state.ReadOnlyValidator) error {
|
||||||
|
assert.NotEqual(t, bytesutil.ToBytes48([]byte{'V'}), val.PublicKey())
|
||||||
|
return nil
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// assertRefCount checks whether reference count for a given state
|
||||||
|
// at a given index is equal to expected amount.
|
||||||
|
func assertRefCount(t *testing.T, b *BeaconState, idx nativetypes.FieldIndex, want uint) {
|
||||||
|
if cnt := b.sharedFieldReferences[idx].Refs(); cnt != want {
|
||||||
|
t.Errorf("Unexpected count of references for index %d, want: %v, got: %v", idx, want, cnt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// assertValFound checks whether item with a given value exists in list.
|
||||||
|
func assertValFound(t *testing.T, vals [][]byte, val []byte) {
|
||||||
|
for i := range vals {
|
||||||
|
if reflect.DeepEqual(vals[i], val) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.Log(string(debug.Stack()))
|
||||||
|
t.Fatalf("Expected value not found (%v), want: %v", vals, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// assertValNotFound checks whether item with a given value doesn't exist in list.
|
||||||
|
func assertValNotFound(t *testing.T, vals [][]byte, val []byte) {
|
||||||
|
for i := range vals {
|
||||||
|
if reflect.DeepEqual(vals[i], val) {
|
||||||
|
t.Log(string(debug.Stack()))
|
||||||
|
t.Errorf("Unexpected value found (%v),: %v", vals, val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
package v1
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RotateAttestations sets the previous epoch attestations to the current epoch attestations and
|
// RotateAttestations sets the previous epoch attestations to the current epoch attestations and
|
||||||
@@ -14,27 +16,31 @@ func (b *BeaconState) RotateAttestations() error {
|
|||||||
b.lock.Lock()
|
b.lock.Lock()
|
||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
|
if b.version != version.Phase0 {
|
||||||
|
return errNotSupported("RotateAttestations", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
b.setPreviousEpochAttestations(b.currentEpochAttestationsVal())
|
b.setPreviousEpochAttestations(b.currentEpochAttestationsVal())
|
||||||
b.setCurrentEpochAttestations([]*ethpb.PendingAttestation{})
|
b.setCurrentEpochAttestations([]*ethpb.PendingAttestation{})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BeaconState) setPreviousEpochAttestations(val []*ethpb.PendingAttestation) {
|
func (b *BeaconState) setPreviousEpochAttestations(val []*ethpb.PendingAttestation) {
|
||||||
b.sharedFieldReferences[previousEpochAttestations].MinusRef()
|
b.sharedFieldReferences[nativetypes.PreviousEpochAttestations].MinusRef()
|
||||||
b.sharedFieldReferences[previousEpochAttestations] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.PreviousEpochAttestations] = stateutil.NewRef(1)
|
||||||
|
|
||||||
b.previousEpochAttestations = val
|
b.previousEpochAttestations = val
|
||||||
b.markFieldAsDirty(previousEpochAttestations)
|
b.markFieldAsDirty(nativetypes.PreviousEpochAttestations)
|
||||||
b.rebuildTrie[previousEpochAttestations] = true
|
b.rebuildTrie[nativetypes.PreviousEpochAttestations] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BeaconState) setCurrentEpochAttestations(val []*ethpb.PendingAttestation) {
|
func (b *BeaconState) setCurrentEpochAttestations(val []*ethpb.PendingAttestation) {
|
||||||
b.sharedFieldReferences[currentEpochAttestations].MinusRef()
|
b.sharedFieldReferences[nativetypes.CurrentEpochAttestations].MinusRef()
|
||||||
b.sharedFieldReferences[currentEpochAttestations] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.CurrentEpochAttestations] = stateutil.NewRef(1)
|
||||||
|
|
||||||
b.currentEpochAttestations = val
|
b.currentEpochAttestations = val
|
||||||
b.markFieldAsDirty(currentEpochAttestations)
|
b.markFieldAsDirty(nativetypes.CurrentEpochAttestations)
|
||||||
b.rebuildTrie[currentEpochAttestations] = true
|
b.rebuildTrie[nativetypes.CurrentEpochAttestations] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// AppendCurrentEpochAttestations for the beacon state. Appends the new value
|
// AppendCurrentEpochAttestations for the beacon state. Appends the new value
|
||||||
@@ -43,23 +49,27 @@ func (b *BeaconState) AppendCurrentEpochAttestations(val *ethpb.PendingAttestati
|
|||||||
b.lock.Lock()
|
b.lock.Lock()
|
||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
|
if b.version != version.Phase0 {
|
||||||
|
return errNotSupported("AppendCurrentEpochAttestations", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
atts := b.currentEpochAttestations
|
atts := b.currentEpochAttestations
|
||||||
max := uint64(fieldparams.CurrentEpochAttestationsLength)
|
max := uint64(fieldparams.CurrentEpochAttestationsLength)
|
||||||
if uint64(len(atts)) >= max {
|
if uint64(len(atts)) >= max {
|
||||||
return fmt.Errorf("current pending attestation exceeds max length %d", max)
|
return fmt.Errorf("current pending attestation exceeds max length %d", max)
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.sharedFieldReferences[currentEpochAttestations].Refs() > 1 {
|
if b.sharedFieldReferences[nativetypes.CurrentEpochAttestations].Refs() > 1 {
|
||||||
// Copy elements in underlying array by reference.
|
// Copy elements in underlying array by reference.
|
||||||
atts = make([]*ethpb.PendingAttestation, len(b.currentEpochAttestations))
|
atts = make([]*ethpb.PendingAttestation, len(b.currentEpochAttestations))
|
||||||
copy(atts, b.currentEpochAttestations)
|
copy(atts, b.currentEpochAttestations)
|
||||||
b.sharedFieldReferences[currentEpochAttestations].MinusRef()
|
b.sharedFieldReferences[nativetypes.CurrentEpochAttestations].MinusRef()
|
||||||
b.sharedFieldReferences[currentEpochAttestations] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.CurrentEpochAttestations] = stateutil.NewRef(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
b.currentEpochAttestations = append(atts, val)
|
b.currentEpochAttestations = append(atts, val)
|
||||||
b.markFieldAsDirty(currentEpochAttestations)
|
b.markFieldAsDirty(nativetypes.CurrentEpochAttestations)
|
||||||
b.addDirtyIndices(currentEpochAttestations, []uint64{uint64(len(b.currentEpochAttestations) - 1)})
|
b.addDirtyIndices(nativetypes.CurrentEpochAttestations, []uint64{uint64(len(b.currentEpochAttestations) - 1)})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,21 +79,25 @@ func (b *BeaconState) AppendPreviousEpochAttestations(val *ethpb.PendingAttestat
|
|||||||
b.lock.Lock()
|
b.lock.Lock()
|
||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
|
if b.version != version.Phase0 {
|
||||||
|
return errNotSupported("AppendPreviousEpochAttestations", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
atts := b.previousEpochAttestations
|
atts := b.previousEpochAttestations
|
||||||
max := uint64(fieldparams.PreviousEpochAttestationsLength)
|
max := uint64(fieldparams.PreviousEpochAttestationsLength)
|
||||||
if uint64(len(atts)) >= max {
|
if uint64(len(atts)) >= max {
|
||||||
return fmt.Errorf("previous pending attestation exceeds max length %d", max)
|
return fmt.Errorf("previous pending attestation exceeds max length %d", max)
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.sharedFieldReferences[previousEpochAttestations].Refs() > 1 {
|
if b.sharedFieldReferences[nativetypes.PreviousEpochAttestations].Refs() > 1 {
|
||||||
atts = make([]*ethpb.PendingAttestation, len(b.previousEpochAttestations))
|
atts = make([]*ethpb.PendingAttestation, len(b.previousEpochAttestations))
|
||||||
copy(atts, b.previousEpochAttestations)
|
copy(atts, b.previousEpochAttestations)
|
||||||
b.sharedFieldReferences[previousEpochAttestations].MinusRef()
|
b.sharedFieldReferences[nativetypes.PreviousEpochAttestations].MinusRef()
|
||||||
b.sharedFieldReferences[previousEpochAttestations] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.PreviousEpochAttestations] = stateutil.NewRef(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
b.previousEpochAttestations = append(atts, val)
|
b.previousEpochAttestations = append(atts, val)
|
||||||
b.markFieldAsDirty(previousEpochAttestations)
|
b.markFieldAsDirty(nativetypes.PreviousEpochAttestations)
|
||||||
b.addDirtyIndices(previousEpochAttestations, []uint64{uint64(len(b.previousEpochAttestations) - 1)})
|
b.addDirtyIndices(nativetypes.PreviousEpochAttestations, []uint64{uint64(len(b.previousEpochAttestations) - 1)})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package v1
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestBeaconState_RotateAttestations(t *testing.T) {
|
func TestBeaconState_RotateAttestations(t *testing.T) {
|
||||||
st, err := InitializeFromProto(ðpb.BeaconState{
|
st, err := InitializeFromProtoPhase0(ðpb.BeaconState{
|
||||||
Slot: 1,
|
Slot: 1,
|
||||||
CurrentEpochAttestations: []*ethpb.PendingAttestation{{Data: ðpb.AttestationData{Slot: 456}}},
|
CurrentEpochAttestations: []*ethpb.PendingAttestation{{Data: ðpb.AttestationData{Slot: 456}}},
|
||||||
PreviousEpochAttestations: []*ethpb.PendingAttestation{{Data: ðpb.AttestationData{Slot: 123}}},
|
PreviousEpochAttestations: []*ethpb.PendingAttestation{{Data: ðpb.AttestationData{Slot: 123}}},
|
||||||
@@ -17,10 +17,8 @@ func TestBeaconState_RotateAttestations(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.NoError(t, st.RotateAttestations())
|
require.NoError(t, st.RotateAttestations())
|
||||||
currEpochAtts, err := st.CurrentEpochAttestations()
|
s, ok := st.(*BeaconState)
|
||||||
require.NoError(t, err)
|
require.Equal(t, true, ok)
|
||||||
require.Equal(t, 0, len(currEpochAtts))
|
require.Equal(t, 0, len(s.currentEpochAttestationsVal()))
|
||||||
prevEpochAtts, err := st.PreviousEpochAttestations()
|
require.Equal(t, types.Slot(456), s.previousEpochAttestationsVal()[0].Data.Slot)
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, types.Slot(456), prevEpochAtts[0].Data.Slot)
|
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
package v1
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types"
|
customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types"
|
||||||
|
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
@@ -15,7 +16,7 @@ func (b *BeaconState) SetLatestBlockHeader(val *ethpb.BeaconBlockHeader) error {
|
|||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
b.latestBlockHeader = ethpb.CopyBeaconBlockHeader(val)
|
b.latestBlockHeader = ethpb.CopyBeaconBlockHeader(val)
|
||||||
b.markFieldAsDirty(latestBlockHeader)
|
b.markFieldAsDirty(nativetypes.LatestBlockHeader)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,8 +26,8 @@ func (b *BeaconState) SetBlockRoots(val [][]byte) error {
|
|||||||
b.lock.Lock()
|
b.lock.Lock()
|
||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
b.sharedFieldReferences[blockRoots].MinusRef()
|
b.sharedFieldReferences[nativetypes.BlockRoots].MinusRef()
|
||||||
b.sharedFieldReferences[blockRoots] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.BlockRoots] = stateutil.NewRef(1)
|
||||||
|
|
||||||
var rootsArr [fieldparams.BlockRootsLength][32]byte
|
var rootsArr [fieldparams.BlockRootsLength][32]byte
|
||||||
for i := 0; i < len(rootsArr); i++ {
|
for i := 0; i < len(rootsArr); i++ {
|
||||||
@@ -34,8 +35,8 @@ func (b *BeaconState) SetBlockRoots(val [][]byte) error {
|
|||||||
}
|
}
|
||||||
roots := customtypes.BlockRoots(rootsArr)
|
roots := customtypes.BlockRoots(rootsArr)
|
||||||
b.blockRoots = &roots
|
b.blockRoots = &roots
|
||||||
b.markFieldAsDirty(blockRoots)
|
b.markFieldAsDirty(nativetypes.BlockRoots)
|
||||||
b.rebuildTrie[blockRoots] = true
|
b.rebuildTrie[nativetypes.BlockRoots] = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,19 +50,19 @@ func (b *BeaconState) UpdateBlockRootAtIndex(idx uint64, blockRoot [32]byte) err
|
|||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
r := b.blockRoots
|
r := b.blockRoots
|
||||||
if ref := b.sharedFieldReferences[blockRoots]; ref.Refs() > 1 {
|
if ref := b.sharedFieldReferences[nativetypes.BlockRoots]; ref.Refs() > 1 {
|
||||||
// Copy elements in underlying array by reference.
|
// Copy elements in underlying array by reference.
|
||||||
roots := *b.blockRoots
|
roots := *b.blockRoots
|
||||||
rootsCopy := roots
|
rootsCopy := roots
|
||||||
r = &rootsCopy
|
r = &rootsCopy
|
||||||
ref.MinusRef()
|
ref.MinusRef()
|
||||||
b.sharedFieldReferences[blockRoots] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.BlockRoots] = stateutil.NewRef(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
r[idx] = blockRoot
|
r[idx] = blockRoot
|
||||||
b.blockRoots = r
|
b.blockRoots = r
|
||||||
|
|
||||||
b.markFieldAsDirty(blockRoots)
|
b.markFieldAsDirty(nativetypes.BlockRoots)
|
||||||
b.addDirtyIndices(blockRoots, []uint64{idx})
|
b.addDirtyIndices(nativetypes.BlockRoots, []uint64{idx})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
package v2
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/prysmaticlabs/go-bitfield"
|
"github.com/prysmaticlabs/go-bitfield"
|
||||||
|
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -11,7 +12,7 @@ func (b *BeaconState) SetJustificationBits(val bitfield.Bitvector4) error {
|
|||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
b.justificationBits = val
|
b.justificationBits = val
|
||||||
b.markFieldAsDirty(justificationBits)
|
b.markFieldAsDirty(nativetypes.JustificationBits)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,7 +22,7 @@ func (b *BeaconState) SetPreviousJustifiedCheckpoint(val *ethpb.Checkpoint) erro
|
|||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
b.previousJustifiedCheckpoint = val
|
b.previousJustifiedCheckpoint = val
|
||||||
b.markFieldAsDirty(previousJustifiedCheckpoint)
|
b.markFieldAsDirty(nativetypes.PreviousJustifiedCheckpoint)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,7 +32,7 @@ func (b *BeaconState) SetCurrentJustifiedCheckpoint(val *ethpb.Checkpoint) error
|
|||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
b.currentJustifiedCheckpoint = val
|
b.currentJustifiedCheckpoint = val
|
||||||
b.markFieldAsDirty(currentJustifiedCheckpoint)
|
b.markFieldAsDirty(nativetypes.CurrentJustifiedCheckpoint)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,6 +42,6 @@ func (b *BeaconState) SetFinalizedCheckpoint(val *ethpb.Checkpoint) error {
|
|||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
b.finalizedCheckpoint = val
|
b.finalizedCheckpoint = val
|
||||||
b.markFieldAsDirty(finalizedCheckpoint)
|
b.markFieldAsDirty(nativetypes.FinalizedCheckpoint)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package v3
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
)
|
)
|
||||||
@@ -11,7 +12,7 @@ func (b *BeaconState) SetEth1Data(val *ethpb.Eth1Data) error {
|
|||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
b.eth1Data = val
|
b.eth1Data = val
|
||||||
b.markFieldAsDirty(eth1Data)
|
b.markFieldAsDirty(nativetypes.Eth1Data)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,12 +22,12 @@ func (b *BeaconState) SetEth1DataVotes(val []*ethpb.Eth1Data) error {
|
|||||||
b.lock.Lock()
|
b.lock.Lock()
|
||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
b.sharedFieldReferences[eth1DataVotes].MinusRef()
|
b.sharedFieldReferences[nativetypes.Eth1DataVotes].MinusRef()
|
||||||
b.sharedFieldReferences[eth1DataVotes] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.Eth1DataVotes] = stateutil.NewRef(1)
|
||||||
|
|
||||||
b.eth1DataVotes = val
|
b.eth1DataVotes = val
|
||||||
b.markFieldAsDirty(eth1DataVotes)
|
b.markFieldAsDirty(nativetypes.Eth1DataVotes)
|
||||||
b.rebuildTrie[eth1DataVotes] = true
|
b.rebuildTrie[nativetypes.Eth1DataVotes] = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +37,7 @@ func (b *BeaconState) SetEth1DepositIndex(val uint64) error {
|
|||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
b.eth1DepositIndex = val
|
b.eth1DepositIndex = val
|
||||||
b.markFieldAsDirty(eth1DepositIndex)
|
b.markFieldAsDirty(nativetypes.Eth1DepositIndex)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,16 +48,16 @@ func (b *BeaconState) AppendEth1DataVotes(val *ethpb.Eth1Data) error {
|
|||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
votes := b.eth1DataVotes
|
votes := b.eth1DataVotes
|
||||||
if b.sharedFieldReferences[eth1DataVotes].Refs() > 1 {
|
if b.sharedFieldReferences[nativetypes.Eth1DataVotes].Refs() > 1 {
|
||||||
// Copy elements in underlying array by reference.
|
// Copy elements in underlying array by reference.
|
||||||
votes = make([]*ethpb.Eth1Data, len(b.eth1DataVotes))
|
votes = make([]*ethpb.Eth1Data, len(b.eth1DataVotes))
|
||||||
copy(votes, b.eth1DataVotes)
|
copy(votes, b.eth1DataVotes)
|
||||||
b.sharedFieldReferences[eth1DataVotes].MinusRef()
|
b.sharedFieldReferences[nativetypes.Eth1DataVotes].MinusRef()
|
||||||
b.sharedFieldReferences[eth1DataVotes] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.Eth1DataVotes] = stateutil.NewRef(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
b.eth1DataVotes = append(votes, val)
|
b.eth1DataVotes = append(votes, val)
|
||||||
b.markFieldAsDirty(eth1DataVotes)
|
b.markFieldAsDirty(nativetypes.Eth1DataVotes)
|
||||||
b.addDirtyIndices(eth1DataVotes, []uint64{uint64(len(b.eth1DataVotes) - 1)})
|
b.addDirtyIndices(nativetypes.Eth1DataVotes, []uint64{uint64(len(b.eth1DataVotes) - 1)})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package v1
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
||||||
stateTypes "github.com/prysmaticlabs/prysm/beacon-chain/state/types"
|
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/crypto/hash"
|
"github.com/prysmaticlabs/prysm/crypto/hash"
|
||||||
@@ -46,7 +46,7 @@ func (b *BeaconState) SetGenesisTime(val uint64) error {
|
|||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
b.genesisTime = val
|
b.genesisTime = val
|
||||||
b.markFieldAsDirty(genesisTime)
|
b.markFieldAsDirty(nativetypes.GenesisTime)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ func (b *BeaconState) SetGenesisValidatorsRoot(val []byte) error {
|
|||||||
return errors.New("incorrect validators root length")
|
return errors.New("incorrect validators root length")
|
||||||
}
|
}
|
||||||
b.genesisValidatorsRoot = bytesutil.ToBytes32(val)
|
b.genesisValidatorsRoot = bytesutil.ToBytes32(val)
|
||||||
b.markFieldAsDirty(genesisValidatorsRoot)
|
b.markFieldAsDirty(nativetypes.GenesisValidatorsRoot)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ func (b *BeaconState) SetSlot(val types.Slot) error {
|
|||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
b.slot = val
|
b.slot = val
|
||||||
b.markFieldAsDirty(slot)
|
b.markFieldAsDirty(nativetypes.Slot)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ func (b *BeaconState) SetFork(val *ethpb.Fork) error {
|
|||||||
return errors.New("proto.Clone did not return a fork proto")
|
return errors.New("proto.Clone did not return a fork proto")
|
||||||
}
|
}
|
||||||
b.fork = fk
|
b.fork = fk
|
||||||
b.markFieldAsDirty(fork)
|
b.markFieldAsDirty(nativetypes.Fork)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,15 +93,15 @@ func (b *BeaconState) SetHistoricalRoots(val [][]byte) error {
|
|||||||
b.lock.Lock()
|
b.lock.Lock()
|
||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
b.sharedFieldReferences[historicalRoots].MinusRef()
|
b.sharedFieldReferences[nativetypes.HistoricalRoots].MinusRef()
|
||||||
b.sharedFieldReferences[historicalRoots] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.HistoricalRoots] = stateutil.NewRef(1)
|
||||||
|
|
||||||
roots := make([][32]byte, len(val))
|
roots := make([][32]byte, len(val))
|
||||||
for i, r := range val {
|
for i, r := range val {
|
||||||
copy(roots[i][:], r)
|
copy(roots[i][:], r)
|
||||||
}
|
}
|
||||||
b.historicalRoots = roots
|
b.historicalRoots = roots
|
||||||
b.markFieldAsDirty(historicalRoots)
|
b.markFieldAsDirty(nativetypes.HistoricalRoots)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,15 +112,15 @@ func (b *BeaconState) AppendHistoricalRoots(root [32]byte) error {
|
|||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
roots := b.historicalRoots
|
roots := b.historicalRoots
|
||||||
if b.sharedFieldReferences[historicalRoots].Refs() > 1 {
|
if b.sharedFieldReferences[nativetypes.HistoricalRoots].Refs() > 1 {
|
||||||
roots = make([][32]byte, len(b.historicalRoots))
|
roots = make([][32]byte, len(b.historicalRoots))
|
||||||
copy(roots, b.historicalRoots)
|
copy(roots, b.historicalRoots)
|
||||||
b.sharedFieldReferences[historicalRoots].MinusRef()
|
b.sharedFieldReferences[nativetypes.HistoricalRoots].MinusRef()
|
||||||
b.sharedFieldReferences[historicalRoots] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.HistoricalRoots] = stateutil.NewRef(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
b.historicalRoots = append(roots, root)
|
b.historicalRoots = append(roots, root)
|
||||||
b.markFieldAsDirty(historicalRoots)
|
b.markFieldAsDirty(nativetypes.HistoricalRoots)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,13 +159,13 @@ func (b *BeaconState) recomputeRoot(idx int) {
|
|||||||
b.merkleLayers = layers
|
b.merkleLayers = layers
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BeaconState) markFieldAsDirty(field stateTypes.FieldIndex) {
|
func (b *BeaconState) markFieldAsDirty(field nativetypes.FieldIndex) {
|
||||||
b.dirtyFields[field] = true
|
b.dirtyFields[field] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// addDirtyIndices adds the relevant dirty field indices, so that they
|
// addDirtyIndices adds the relevant dirty field indices, so that they
|
||||||
// can be recomputed.
|
// can be recomputed.
|
||||||
func (b *BeaconState) addDirtyIndices(index stateTypes.FieldIndex, indices []uint64) {
|
func (b *BeaconState) addDirtyIndices(index nativetypes.FieldIndex, indices []uint64) {
|
||||||
if b.rebuildTrie[index] {
|
if b.rebuildTrie[index] {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
165
beacon-chain/state/state-native/setters_participation.go
Normal file
165
beacon-chain/state/state-native/setters_participation.go
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
package state_native
|
||||||
|
|
||||||
|
import (
|
||||||
|
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
||||||
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetPreviousParticipationBits for the beacon state. Updates the entire
|
||||||
|
// list to a new value by overwriting the previous one.
|
||||||
|
func (b *BeaconState) SetPreviousParticipationBits(val []byte) error {
|
||||||
|
b.lock.Lock()
|
||||||
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
|
if b.version == version.Phase0 {
|
||||||
|
return errNotSupported("SetPreviousParticipationBits", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.sharedFieldReferences[nativetypes.PreviousEpochParticipationBits].MinusRef()
|
||||||
|
b.sharedFieldReferences[nativetypes.PreviousEpochParticipationBits] = stateutil.NewRef(1)
|
||||||
|
|
||||||
|
b.previousEpochParticipation = val
|
||||||
|
b.markFieldAsDirty(nativetypes.PreviousEpochParticipationBits)
|
||||||
|
b.rebuildTrie[nativetypes.PreviousEpochParticipationBits] = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCurrentParticipationBits for the beacon state. Updates the entire
|
||||||
|
// list to a new value by overwriting the previous one.
|
||||||
|
func (b *BeaconState) SetCurrentParticipationBits(val []byte) error {
|
||||||
|
b.lock.Lock()
|
||||||
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
|
if b.version == version.Phase0 {
|
||||||
|
return errNotSupported("SetCurrentParticipationBits", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.sharedFieldReferences[nativetypes.CurrentEpochParticipationBits].MinusRef()
|
||||||
|
b.sharedFieldReferences[nativetypes.CurrentEpochParticipationBits] = stateutil.NewRef(1)
|
||||||
|
|
||||||
|
b.currentEpochParticipation = val
|
||||||
|
b.markFieldAsDirty(nativetypes.CurrentEpochParticipationBits)
|
||||||
|
b.rebuildTrie[nativetypes.CurrentEpochParticipationBits] = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendCurrentParticipationBits for the beacon state. Appends the new value
|
||||||
|
// to the the end of list.
|
||||||
|
func (b *BeaconState) AppendCurrentParticipationBits(val byte) error {
|
||||||
|
b.lock.Lock()
|
||||||
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
|
if b.version == version.Phase0 {
|
||||||
|
return errNotSupported("AppendCurrentParticipationBits", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
|
participation := b.currentEpochParticipation
|
||||||
|
if b.sharedFieldReferences[nativetypes.CurrentEpochParticipationBits].Refs() > 1 {
|
||||||
|
// Copy elements in underlying array by reference.
|
||||||
|
participation = make([]byte, len(b.currentEpochParticipation))
|
||||||
|
copy(participation, b.currentEpochParticipation)
|
||||||
|
b.sharedFieldReferences[nativetypes.CurrentEpochParticipationBits].MinusRef()
|
||||||
|
b.sharedFieldReferences[nativetypes.CurrentEpochParticipationBits] = stateutil.NewRef(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.currentEpochParticipation = append(participation, val)
|
||||||
|
b.markFieldAsDirty(nativetypes.CurrentEpochParticipationBits)
|
||||||
|
b.addDirtyIndices(nativetypes.CurrentEpochParticipationBits, []uint64{uint64(len(b.currentEpochParticipation) - 1)})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendPreviousParticipationBits for the beacon state. Appends the new value
|
||||||
|
// to the the end of list.
|
||||||
|
func (b *BeaconState) AppendPreviousParticipationBits(val byte) error {
|
||||||
|
b.lock.Lock()
|
||||||
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
|
if b.version == version.Phase0 {
|
||||||
|
return errNotSupported("AppendPreviousParticipationBits", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
|
bits := b.previousEpochParticipation
|
||||||
|
if b.sharedFieldReferences[nativetypes.PreviousEpochParticipationBits].Refs() > 1 {
|
||||||
|
bits = make([]byte, len(b.previousEpochParticipation))
|
||||||
|
copy(bits, b.previousEpochParticipation)
|
||||||
|
b.sharedFieldReferences[nativetypes.PreviousEpochParticipationBits].MinusRef()
|
||||||
|
b.sharedFieldReferences[nativetypes.PreviousEpochParticipationBits] = stateutil.NewRef(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.previousEpochParticipation = append(bits, val)
|
||||||
|
b.markFieldAsDirty(nativetypes.PreviousEpochParticipationBits)
|
||||||
|
b.addDirtyIndices(nativetypes.PreviousEpochParticipationBits, []uint64{uint64(len(b.previousEpochParticipation) - 1)})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModifyPreviousParticipationBits modifies the previous participation bitfield via
|
||||||
|
// the provided mutator function.
|
||||||
|
func (b *BeaconState) ModifyPreviousParticipationBits(mutator func(val []byte) ([]byte, error)) error {
|
||||||
|
b.lock.Lock()
|
||||||
|
|
||||||
|
if b.version == version.Phase0 {
|
||||||
|
b.lock.Unlock()
|
||||||
|
return errNotSupported("ModifyPreviousParticipationBits", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
|
participation := b.previousEpochParticipation
|
||||||
|
if b.sharedFieldReferences[nativetypes.PreviousEpochParticipationBits].Refs() > 1 {
|
||||||
|
// Copy elements in underlying array by reference.
|
||||||
|
participation = make([]byte, len(b.previousEpochParticipation))
|
||||||
|
copy(participation, b.previousEpochParticipation)
|
||||||
|
b.sharedFieldReferences[nativetypes.PreviousEpochParticipationBits].MinusRef()
|
||||||
|
b.sharedFieldReferences[nativetypes.PreviousEpochParticipationBits] = stateutil.NewRef(1)
|
||||||
|
}
|
||||||
|
// Lock is released so that mutator can
|
||||||
|
// acquire it.
|
||||||
|
b.lock.Unlock()
|
||||||
|
|
||||||
|
var err error
|
||||||
|
participation, err = mutator(participation)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
b.lock.Lock()
|
||||||
|
defer b.lock.Unlock()
|
||||||
|
b.previousEpochParticipation = participation
|
||||||
|
b.markFieldAsDirty(nativetypes.PreviousEpochParticipationBits)
|
||||||
|
b.rebuildTrie[nativetypes.PreviousEpochParticipationBits] = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModifyCurrentParticipationBits modifies the current participation bitfield via
|
||||||
|
// the provided mutator function.
|
||||||
|
func (b *BeaconState) ModifyCurrentParticipationBits(mutator func(val []byte) ([]byte, error)) error {
|
||||||
|
b.lock.Lock()
|
||||||
|
|
||||||
|
if b.version == version.Phase0 {
|
||||||
|
b.lock.Unlock()
|
||||||
|
return errNotSupported("ModifyCurrentParticipationBits", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
|
participation := b.currentEpochParticipation
|
||||||
|
if b.sharedFieldReferences[nativetypes.CurrentEpochParticipationBits].Refs() > 1 {
|
||||||
|
// Copy elements in underlying array by reference.
|
||||||
|
participation = make([]byte, len(b.currentEpochParticipation))
|
||||||
|
copy(participation, b.currentEpochParticipation)
|
||||||
|
b.sharedFieldReferences[nativetypes.CurrentEpochParticipationBits].MinusRef()
|
||||||
|
b.sharedFieldReferences[nativetypes.CurrentEpochParticipationBits] = stateutil.NewRef(1)
|
||||||
|
}
|
||||||
|
// Lock is released so that mutator can
|
||||||
|
// acquire it.
|
||||||
|
b.lock.Unlock()
|
||||||
|
|
||||||
|
var err error
|
||||||
|
participation, err = mutator(participation)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
b.lock.Lock()
|
||||||
|
defer b.lock.Unlock()
|
||||||
|
b.currentEpochParticipation = participation
|
||||||
|
b.markFieldAsDirty(nativetypes.CurrentEpochParticipationBits)
|
||||||
|
b.rebuildTrie[nativetypes.CurrentEpochParticipationBits] = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
21
beacon-chain/state/state-native/setters_payload_header.go
Normal file
21
beacon-chain/state/state-native/setters_payload_header.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package state_native
|
||||||
|
|
||||||
|
import (
|
||||||
|
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
|
||||||
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetLatestExecutionPayloadHeader for the beacon state.
|
||||||
|
func (b *BeaconState) SetLatestExecutionPayloadHeader(val *ethpb.ExecutionPayloadHeader) error {
|
||||||
|
b.lock.Lock()
|
||||||
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
|
if b.version == version.Phase0 || b.version == version.Altair {
|
||||||
|
return errNotSupported("SetLatestExecutionPayloadHeader", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.latestExecutionPayloadHeader = val
|
||||||
|
b.markFieldAsDirty(nativetypes.LatestExecutionPayloadHeader)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
package v1
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types"
|
customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types"
|
||||||
|
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
@@ -14,8 +15,8 @@ func (b *BeaconState) SetRandaoMixes(val [][]byte) error {
|
|||||||
b.lock.Lock()
|
b.lock.Lock()
|
||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
b.sharedFieldReferences[randaoMixes].MinusRef()
|
b.sharedFieldReferences[nativetypes.RandaoMixes].MinusRef()
|
||||||
b.sharedFieldReferences[randaoMixes] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.RandaoMixes] = stateutil.NewRef(1)
|
||||||
|
|
||||||
var mixesArr [fieldparams.RandaoMixesLength][32]byte
|
var mixesArr [fieldparams.RandaoMixesLength][32]byte
|
||||||
for i := 0; i < len(mixesArr); i++ {
|
for i := 0; i < len(mixesArr); i++ {
|
||||||
@@ -23,8 +24,8 @@ func (b *BeaconState) SetRandaoMixes(val [][]byte) error {
|
|||||||
}
|
}
|
||||||
mixes := customtypes.RandaoMixes(mixesArr)
|
mixes := customtypes.RandaoMixes(mixesArr)
|
||||||
b.randaoMixes = &mixes
|
b.randaoMixes = &mixes
|
||||||
b.markFieldAsDirty(randaoMixes)
|
b.markFieldAsDirty(nativetypes.RandaoMixes)
|
||||||
b.rebuildTrie[randaoMixes] = true
|
b.rebuildTrie[nativetypes.RandaoMixes] = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,19 +39,19 @@ func (b *BeaconState) UpdateRandaoMixesAtIndex(idx uint64, val []byte) error {
|
|||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
mixes := b.randaoMixes
|
mixes := b.randaoMixes
|
||||||
if refs := b.sharedFieldReferences[randaoMixes].Refs(); refs > 1 {
|
if refs := b.sharedFieldReferences[nativetypes.RandaoMixes].Refs(); refs > 1 {
|
||||||
// Copy elements in underlying array by reference.
|
// Copy elements in underlying array by reference.
|
||||||
m := *b.randaoMixes
|
m := *b.randaoMixes
|
||||||
mCopy := m
|
mCopy := m
|
||||||
mixes = &mCopy
|
mixes = &mCopy
|
||||||
b.sharedFieldReferences[randaoMixes].MinusRef()
|
b.sharedFieldReferences[nativetypes.RandaoMixes].MinusRef()
|
||||||
b.sharedFieldReferences[randaoMixes] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.RandaoMixes] = stateutil.NewRef(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
mixes[idx] = bytesutil.ToBytes32(val)
|
mixes[idx] = bytesutil.ToBytes32(val)
|
||||||
b.randaoMixes = mixes
|
b.randaoMixes = mixes
|
||||||
b.markFieldAsDirty(randaoMixes)
|
b.markFieldAsDirty(nativetypes.RandaoMixes)
|
||||||
b.addDirtyIndices(randaoMixes, []uint64{idx})
|
b.addDirtyIndices(nativetypes.RandaoMixes, []uint64{idx})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
package v1
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types"
|
customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types"
|
||||||
|
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
)
|
)
|
||||||
@@ -13,8 +14,8 @@ func (b *BeaconState) SetStateRoots(val [][]byte) error {
|
|||||||
b.lock.Lock()
|
b.lock.Lock()
|
||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
b.sharedFieldReferences[stateRoots].MinusRef()
|
b.sharedFieldReferences[nativetypes.StateRoots].MinusRef()
|
||||||
b.sharedFieldReferences[stateRoots] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.StateRoots] = stateutil.NewRef(1)
|
||||||
|
|
||||||
var rootsArr [fieldparams.StateRootsLength][32]byte
|
var rootsArr [fieldparams.StateRootsLength][32]byte
|
||||||
for i := 0; i < len(rootsArr); i++ {
|
for i := 0; i < len(rootsArr); i++ {
|
||||||
@@ -22,8 +23,8 @@ func (b *BeaconState) SetStateRoots(val [][]byte) error {
|
|||||||
}
|
}
|
||||||
roots := customtypes.StateRoots(rootsArr)
|
roots := customtypes.StateRoots(rootsArr)
|
||||||
b.stateRoots = &roots
|
b.stateRoots = &roots
|
||||||
b.markFieldAsDirty(stateRoots)
|
b.markFieldAsDirty(nativetypes.StateRoots)
|
||||||
b.rebuildTrie[stateRoots] = true
|
b.rebuildTrie[nativetypes.StateRoots] = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,19 +43,19 @@ func (b *BeaconState) UpdateStateRootAtIndex(idx uint64, stateRoot [32]byte) err
|
|||||||
|
|
||||||
// Check if we hold the only reference to the shared state roots slice.
|
// Check if we hold the only reference to the shared state roots slice.
|
||||||
r := b.stateRoots
|
r := b.stateRoots
|
||||||
if ref := b.sharedFieldReferences[stateRoots]; ref.Refs() > 1 {
|
if ref := b.sharedFieldReferences[nativetypes.StateRoots]; ref.Refs() > 1 {
|
||||||
// Copy elements in underlying array by reference.
|
// Copy elements in underlying array by reference.
|
||||||
roots := *b.stateRoots
|
roots := *b.stateRoots
|
||||||
rootsCopy := roots
|
rootsCopy := roots
|
||||||
r = &rootsCopy
|
r = &rootsCopy
|
||||||
ref.MinusRef()
|
ref.MinusRef()
|
||||||
b.sharedFieldReferences[stateRoots] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.StateRoots] = stateutil.NewRef(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
r[idx] = stateRoot
|
r[idx] = stateRoot
|
||||||
b.stateRoots = r
|
b.stateRoots = r
|
||||||
|
|
||||||
b.markFieldAsDirty(stateRoots)
|
b.markFieldAsDirty(nativetypes.StateRoots)
|
||||||
b.addDirtyIndices(stateRoots, []uint64{idx})
|
b.addDirtyIndices(nativetypes.StateRoots, []uint64{idx})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
package v3
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetCurrentSyncCommittee for the beacon state.
|
// SetCurrentSyncCommittee for the beacon state.
|
||||||
@@ -9,8 +11,12 @@ func (b *BeaconState) SetCurrentSyncCommittee(val *ethpb.SyncCommittee) error {
|
|||||||
b.lock.Lock()
|
b.lock.Lock()
|
||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
|
if b.version == version.Phase0 {
|
||||||
|
return errNotSupported("SetCurrentSyncCommittee", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
b.currentSyncCommittee = val
|
b.currentSyncCommittee = val
|
||||||
b.markFieldAsDirty(currentSyncCommittee)
|
b.markFieldAsDirty(nativetypes.CurrentSyncCommittee)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -19,7 +25,11 @@ func (b *BeaconState) SetNextSyncCommittee(val *ethpb.SyncCommittee) error {
|
|||||||
b.lock.Lock()
|
b.lock.Lock()
|
||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
|
if b.version == version.Phase0 {
|
||||||
|
return errNotSupported("SetNextSyncCommittee", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
b.nextSyncCommittee = val
|
b.nextSyncCommittee = val
|
||||||
b.markFieldAsDirty(nextSyncCommittee)
|
b.markFieldAsDirty(nativetypes.NextSyncCommittee)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
package v3
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
||||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetValidators for the beacon state. Updates the entire
|
// SetValidators for the beacon state. Updates the entire
|
||||||
@@ -15,10 +17,10 @@ func (b *BeaconState) SetValidators(val []*ethpb.Validator) error {
|
|||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
b.validators = val
|
b.validators = val
|
||||||
b.sharedFieldReferences[validators].MinusRef()
|
b.sharedFieldReferences[nativetypes.Validators].MinusRef()
|
||||||
b.sharedFieldReferences[validators] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.Validators] = stateutil.NewRef(1)
|
||||||
b.markFieldAsDirty(validators)
|
b.markFieldAsDirty(nativetypes.Validators)
|
||||||
b.rebuildTrie[validators] = true
|
b.rebuildTrie[nativetypes.Validators] = true
|
||||||
b.valMapHandler = stateutil.NewValMapHandler(b.validators)
|
b.valMapHandler = stateutil.NewValMapHandler(b.validators)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -28,10 +30,10 @@ func (b *BeaconState) SetValidators(val []*ethpb.Validator) error {
|
|||||||
func (b *BeaconState) ApplyToEveryValidator(f func(idx int, val *ethpb.Validator) (bool, *ethpb.Validator, error)) error {
|
func (b *BeaconState) ApplyToEveryValidator(f func(idx int, val *ethpb.Validator) (bool, *ethpb.Validator, error)) error {
|
||||||
b.lock.Lock()
|
b.lock.Lock()
|
||||||
v := b.validators
|
v := b.validators
|
||||||
if ref := b.sharedFieldReferences[validators]; ref.Refs() > 1 {
|
if ref := b.sharedFieldReferences[nativetypes.Validators]; ref.Refs() > 1 {
|
||||||
v = b.validatorsReferences()
|
v = b.validatorsReferences()
|
||||||
ref.MinusRef()
|
ref.MinusRef()
|
||||||
b.sharedFieldReferences[validators] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.Validators] = stateutil.NewRef(1)
|
||||||
}
|
}
|
||||||
b.lock.Unlock()
|
b.lock.Unlock()
|
||||||
var changedVals []uint64
|
var changedVals []uint64
|
||||||
@@ -50,8 +52,8 @@ func (b *BeaconState) ApplyToEveryValidator(f func(idx int, val *ethpb.Validator
|
|||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
b.validators = v
|
b.validators = v
|
||||||
b.markFieldAsDirty(validators)
|
b.markFieldAsDirty(nativetypes.Validators)
|
||||||
b.addDirtyIndices(validators, changedVals)
|
b.addDirtyIndices(nativetypes.Validators, changedVals)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -66,16 +68,16 @@ func (b *BeaconState) UpdateValidatorAtIndex(idx types.ValidatorIndex, val *ethp
|
|||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
v := b.validators
|
v := b.validators
|
||||||
if ref := b.sharedFieldReferences[validators]; ref.Refs() > 1 {
|
if ref := b.sharedFieldReferences[nativetypes.Validators]; ref.Refs() > 1 {
|
||||||
v = b.validatorsReferences()
|
v = b.validatorsReferences()
|
||||||
ref.MinusRef()
|
ref.MinusRef()
|
||||||
b.sharedFieldReferences[validators] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.Validators] = stateutil.NewRef(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
v[idx] = val
|
v[idx] = val
|
||||||
b.validators = v
|
b.validators = v
|
||||||
b.markFieldAsDirty(validators)
|
b.markFieldAsDirty(nativetypes.Validators)
|
||||||
b.addDirtyIndices(validators, []uint64{uint64(idx)})
|
b.addDirtyIndices(nativetypes.Validators, []uint64{uint64(idx)})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -86,12 +88,12 @@ func (b *BeaconState) SetBalances(val []uint64) error {
|
|||||||
b.lock.Lock()
|
b.lock.Lock()
|
||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
b.sharedFieldReferences[balances].MinusRef()
|
b.sharedFieldReferences[nativetypes.Balances].MinusRef()
|
||||||
b.sharedFieldReferences[balances] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.Balances] = stateutil.NewRef(1)
|
||||||
|
|
||||||
b.balances = val
|
b.balances = val
|
||||||
b.markFieldAsDirty(balances)
|
b.markFieldAsDirty(nativetypes.Balances)
|
||||||
b.rebuildTrie[balances] = true
|
b.rebuildTrie[nativetypes.Balances] = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,16 +107,16 @@ func (b *BeaconState) UpdateBalancesAtIndex(idx types.ValidatorIndex, val uint64
|
|||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
bals := b.balances
|
bals := b.balances
|
||||||
if b.sharedFieldReferences[balances].Refs() > 1 {
|
if b.sharedFieldReferences[nativetypes.Balances].Refs() > 1 {
|
||||||
bals = b.balancesVal()
|
bals = b.balancesVal()
|
||||||
b.sharedFieldReferences[balances].MinusRef()
|
b.sharedFieldReferences[nativetypes.Balances].MinusRef()
|
||||||
b.sharedFieldReferences[balances] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.Balances] = stateutil.NewRef(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
bals[idx] = val
|
bals[idx] = val
|
||||||
b.balances = bals
|
b.balances = bals
|
||||||
b.markFieldAsDirty(balances)
|
b.markFieldAsDirty(nativetypes.Balances)
|
||||||
b.addDirtyIndices(balances, []uint64{uint64(idx)})
|
b.addDirtyIndices(nativetypes.Balances, []uint64{uint64(idx)})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,11 +126,11 @@ func (b *BeaconState) SetSlashings(val []uint64) error {
|
|||||||
b.lock.Lock()
|
b.lock.Lock()
|
||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
b.sharedFieldReferences[slashings].MinusRef()
|
b.sharedFieldReferences[nativetypes.Slashings].MinusRef()
|
||||||
b.sharedFieldReferences[slashings] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.Slashings] = stateutil.NewRef(1)
|
||||||
|
|
||||||
b.slashings = val
|
b.slashings = val
|
||||||
b.markFieldAsDirty(slashings)
|
b.markFieldAsDirty(nativetypes.Slashings)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,17 +144,17 @@ func (b *BeaconState) UpdateSlashingsAtIndex(idx, val uint64) error {
|
|||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
s := b.slashings
|
s := b.slashings
|
||||||
if b.sharedFieldReferences[slashings].Refs() > 1 {
|
if b.sharedFieldReferences[nativetypes.Slashings].Refs() > 1 {
|
||||||
s = b.slashingsVal()
|
s = b.slashingsVal()
|
||||||
b.sharedFieldReferences[slashings].MinusRef()
|
b.sharedFieldReferences[nativetypes.Slashings].MinusRef()
|
||||||
b.sharedFieldReferences[slashings] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.Slashings] = stateutil.NewRef(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
s[idx] = val
|
s[idx] = val
|
||||||
|
|
||||||
b.slashings = s
|
b.slashings = s
|
||||||
|
|
||||||
b.markFieldAsDirty(slashings)
|
b.markFieldAsDirty(nativetypes.Slashings)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,10 +165,10 @@ func (b *BeaconState) AppendValidator(val *ethpb.Validator) error {
|
|||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
vals := b.validators
|
vals := b.validators
|
||||||
if b.sharedFieldReferences[validators].Refs() > 1 {
|
if b.sharedFieldReferences[nativetypes.Validators].Refs() > 1 {
|
||||||
vals = b.validatorsReferences()
|
vals = b.validatorsReferences()
|
||||||
b.sharedFieldReferences[validators].MinusRef()
|
b.sharedFieldReferences[nativetypes.Validators].MinusRef()
|
||||||
b.sharedFieldReferences[validators] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.Validators] = stateutil.NewRef(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// append validator to slice
|
// append validator to slice
|
||||||
@@ -175,8 +177,8 @@ func (b *BeaconState) AppendValidator(val *ethpb.Validator) error {
|
|||||||
|
|
||||||
b.valMapHandler.Set(bytesutil.ToBytes48(val.PublicKey), valIdx)
|
b.valMapHandler.Set(bytesutil.ToBytes48(val.PublicKey), valIdx)
|
||||||
|
|
||||||
b.markFieldAsDirty(validators)
|
b.markFieldAsDirty(nativetypes.Validators)
|
||||||
b.addDirtyIndices(validators, []uint64{uint64(valIdx)})
|
b.addDirtyIndices(nativetypes.Validators, []uint64{uint64(valIdx)})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,16 +189,16 @@ func (b *BeaconState) AppendBalance(bal uint64) error {
|
|||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
bals := b.balances
|
bals := b.balances
|
||||||
if b.sharedFieldReferences[balances].Refs() > 1 {
|
if b.sharedFieldReferences[nativetypes.Balances].Refs() > 1 {
|
||||||
bals = b.balancesVal()
|
bals = b.balancesVal()
|
||||||
b.sharedFieldReferences[balances].MinusRef()
|
b.sharedFieldReferences[nativetypes.Balances].MinusRef()
|
||||||
b.sharedFieldReferences[balances] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.Balances] = stateutil.NewRef(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
b.balances = append(bals, bal)
|
b.balances = append(bals, bal)
|
||||||
balIdx := len(b.balances) - 1
|
balIdx := len(b.balances) - 1
|
||||||
b.markFieldAsDirty(balances)
|
b.markFieldAsDirty(nativetypes.Balances)
|
||||||
b.addDirtyIndices(balances, []uint64{uint64(balIdx)})
|
b.addDirtyIndices(nativetypes.Balances, []uint64{uint64(balIdx)})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,15 +207,19 @@ func (b *BeaconState) AppendInactivityScore(s uint64) error {
|
|||||||
b.lock.Lock()
|
b.lock.Lock()
|
||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
|
if b.version == version.Phase0 {
|
||||||
|
return errNotSupported("AppendInactivityScore", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
scores := b.inactivityScores
|
scores := b.inactivityScores
|
||||||
if b.sharedFieldReferences[inactivityScores].Refs() > 1 {
|
if b.sharedFieldReferences[nativetypes.InactivityScores].Refs() > 1 {
|
||||||
scores = b.inactivityScoresVal()
|
scores = b.inactivityScoresVal()
|
||||||
b.sharedFieldReferences[inactivityScores].MinusRef()
|
b.sharedFieldReferences[nativetypes.InactivityScores].MinusRef()
|
||||||
b.sharedFieldReferences[inactivityScores] = stateutil.NewRef(1)
|
b.sharedFieldReferences[nativetypes.InactivityScores] = stateutil.NewRef(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
b.inactivityScores = append(scores, s)
|
b.inactivityScores = append(scores, s)
|
||||||
b.markFieldAsDirty(inactivityScores)
|
b.markFieldAsDirty(nativetypes.InactivityScores)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,10 +229,14 @@ func (b *BeaconState) SetInactivityScores(val []uint64) error {
|
|||||||
b.lock.Lock()
|
b.lock.Lock()
|
||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
|
|
||||||
b.sharedFieldReferences[inactivityScores].MinusRef()
|
if b.version == version.Phase0 {
|
||||||
b.sharedFieldReferences[inactivityScores] = stateutil.NewRef(1)
|
return errNotSupported("SetInactivityScores", b.version)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.sharedFieldReferences[nativetypes.InactivityScores].MinusRef()
|
||||||
|
b.sharedFieldReferences[nativetypes.InactivityScores] = stateutil.NewRef(1)
|
||||||
|
|
||||||
b.inactivityScores = val
|
b.inactivityScores = val
|
||||||
b.markFieldAsDirty(inactivityScores)
|
b.markFieldAsDirty(nativetypes.InactivityScores)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
36
beacon-chain/state/state-native/ssz.go
Normal file
36
beacon-chain/state/state-native/ssz.go
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
package state_native
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
|
)
|
||||||
|
|
||||||
|
var errAssertionFailed = errors.New("failed to convert interface to proto state")
|
||||||
|
var errUnsupportedVersion = errors.New("unsupported beacon state version")
|
||||||
|
|
||||||
|
func (b *BeaconState) MarshalSSZ() ([]byte, error) {
|
||||||
|
proto := b.ToProto()
|
||||||
|
switch b.Version() {
|
||||||
|
case version.Phase0:
|
||||||
|
s, ok := proto.(*ethpb.BeaconState)
|
||||||
|
if !ok {
|
||||||
|
return nil, errAssertionFailed
|
||||||
|
}
|
||||||
|
return s.MarshalSSZ()
|
||||||
|
case version.Altair:
|
||||||
|
s, ok := proto.(*ethpb.BeaconStateAltair)
|
||||||
|
if !ok {
|
||||||
|
return nil, errAssertionFailed
|
||||||
|
}
|
||||||
|
return s.MarshalSSZ()
|
||||||
|
case version.Bellatrix:
|
||||||
|
s, ok := proto.(*ethpb.BeaconStateBellatrix)
|
||||||
|
if !ok {
|
||||||
|
return nil, errAssertionFailed
|
||||||
|
}
|
||||||
|
return s.MarshalSSZ()
|
||||||
|
default:
|
||||||
|
return nil, errUnsupportedVersion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package v1
|
package state_native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/prysmaticlabs/go-bitfield"
|
"github.com/prysmaticlabs/go-bitfield"
|
||||||
|
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
@@ -45,7 +46,7 @@ func TestValidatorMap_DistinctCopy(t *testing.T) {
|
|||||||
assert.NotEqual(t, val1, val2, "Values are supposed to be unequal due to copy")
|
assert.NotEqual(t, val1, val2, "Values are supposed to be unequal due to copy")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBeaconState_NoDeadlock(t *testing.T) {
|
func TestBeaconState_NoDeadlock_Phase0(t *testing.T) {
|
||||||
count := uint64(100)
|
count := uint64(100)
|
||||||
vals := make([]*ethpb.Validator, 0, count)
|
vals := make([]*ethpb.Validator, 0, count)
|
||||||
for i := uint64(1); i < count; i++ {
|
for i := uint64(1); i < count; i++ {
|
||||||
@@ -64,7 +65,63 @@ func TestBeaconState_NoDeadlock(t *testing.T) {
|
|||||||
WithdrawableEpoch: 1,
|
WithdrawableEpoch: 1,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
st, err := InitializeFromProtoUnsafe(ðpb.BeaconState{
|
newState, err := InitializeFromProtoUnsafePhase0(ðpb.BeaconState{
|
||||||
|
Validators: vals,
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
st, ok := newState.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
|
||||||
|
wg := new(sync.WaitGroup)
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
// Continuously lock and unlock the state
|
||||||
|
// by acquiring the lock.
|
||||||
|
for i := 0; i < 1000; i++ {
|
||||||
|
for _, f := range st.stateFieldLeaves {
|
||||||
|
f.Lock()
|
||||||
|
if f.Empty() {
|
||||||
|
f.InsertFieldLayer(make([][]*[32]byte, 10))
|
||||||
|
}
|
||||||
|
f.Unlock()
|
||||||
|
f.FieldReference().AddRef()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
// Constantly read from the offending portion
|
||||||
|
// of the code to ensure there is no possible
|
||||||
|
// recursive read locking.
|
||||||
|
for i := 0; i < 1000; i++ {
|
||||||
|
go func() {
|
||||||
|
_ = st.FieldReferencesCount()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// Test will not terminate in the event of a deadlock.
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconState_NoDeadlock_Altair(t *testing.T) {
|
||||||
|
count := uint64(100)
|
||||||
|
vals := make([]*ethpb.Validator, 0, count)
|
||||||
|
for i := uint64(1); i < count; i++ {
|
||||||
|
someRoot := [32]byte{}
|
||||||
|
someKey := [fieldparams.BLSPubkeyLength]byte{}
|
||||||
|
copy(someRoot[:], strconv.Itoa(int(i)))
|
||||||
|
copy(someKey[:], strconv.Itoa(int(i)))
|
||||||
|
vals = append(vals, ðpb.Validator{
|
||||||
|
PublicKey: someKey[:],
|
||||||
|
WithdrawalCredentials: someRoot[:],
|
||||||
|
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
|
||||||
|
Slashed: false,
|
||||||
|
ActivationEligibilityEpoch: 1,
|
||||||
|
ActivationEpoch: 1,
|
||||||
|
ExitEpoch: 1,
|
||||||
|
WithdrawableEpoch: 1,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
st, err := InitializeFromProtoUnsafeAltair(ðpb.BeaconStateAltair{
|
||||||
Validators: vals,
|
Validators: vals,
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@@ -101,9 +158,60 @@ func TestBeaconState_NoDeadlock(t *testing.T) {
|
|||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStateTrie_IsNil(t *testing.T) {
|
func TestBeaconState_NoDeadlock_Bellatrix(t *testing.T) {
|
||||||
var emptyState *BeaconState
|
count := uint64(100)
|
||||||
assert.Equal(t, true, emptyState.IsNil())
|
vals := make([]*ethpb.Validator, 0, count)
|
||||||
|
for i := uint64(1); i < count; i++ {
|
||||||
|
someRoot := [32]byte{}
|
||||||
|
someKey := [fieldparams.BLSPubkeyLength]byte{}
|
||||||
|
copy(someRoot[:], strconv.Itoa(int(i)))
|
||||||
|
copy(someKey[:], strconv.Itoa(int(i)))
|
||||||
|
vals = append(vals, ðpb.Validator{
|
||||||
|
PublicKey: someKey[:],
|
||||||
|
WithdrawalCredentials: someRoot[:],
|
||||||
|
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
|
||||||
|
Slashed: false,
|
||||||
|
ActivationEligibilityEpoch: 1,
|
||||||
|
ActivationEpoch: 1,
|
||||||
|
ExitEpoch: 1,
|
||||||
|
WithdrawableEpoch: 1,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
st, err := InitializeFromProtoUnsafeBellatrix(ðpb.BeaconStateBellatrix{
|
||||||
|
Validators: vals,
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
s, ok := st.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
|
|
||||||
|
wg := new(sync.WaitGroup)
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
// Continuously lock and unlock the state
|
||||||
|
// by acquiring the lock.
|
||||||
|
for i := 0; i < 1000; i++ {
|
||||||
|
for _, f := range s.stateFieldLeaves {
|
||||||
|
f.Lock()
|
||||||
|
if f.Empty() {
|
||||||
|
f.InsertFieldLayer(make([][]*[32]byte, 10))
|
||||||
|
}
|
||||||
|
f.Unlock()
|
||||||
|
f.FieldReference().AddRef()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
// Constantly read from the offending portion
|
||||||
|
// of the code to ensure there is no possible
|
||||||
|
// recursive read locking.
|
||||||
|
for i := 0; i < 1000; i++ {
|
||||||
|
go func() {
|
||||||
|
_ = st.FieldReferencesCount()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// Test will not terminate in the event of a deadlock.
|
||||||
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBeaconState_AppendBalanceWithTrie(t *testing.T) {
|
func TestBeaconState_AppendBalanceWithTrie(t *testing.T) {
|
||||||
@@ -141,7 +249,7 @@ func TestBeaconState_AppendBalanceWithTrie(t *testing.T) {
|
|||||||
for i := 0; i < len(mockrandaoMixes); i++ {
|
for i := 0; i < len(mockrandaoMixes); i++ {
|
||||||
mockrandaoMixes[i] = zeroHash[:]
|
mockrandaoMixes[i] = zeroHash[:]
|
||||||
}
|
}
|
||||||
st, err := InitializeFromProto(ðpb.BeaconState{
|
newState, err := InitializeFromProtoPhase0(ðpb.BeaconState{
|
||||||
Slot: 1,
|
Slot: 1,
|
||||||
GenesisValidatorsRoot: make([]byte, 32),
|
GenesisValidatorsRoot: make([]byte, 32),
|
||||||
Fork: ðpb.Fork{
|
Fork: ðpb.Fork{
|
||||||
@@ -170,6 +278,8 @@ func TestBeaconState_AppendBalanceWithTrie(t *testing.T) {
|
|||||||
Slashings: make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector),
|
Slashings: make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector),
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
st, ok := newState.(*BeaconState)
|
||||||
|
require.Equal(t, true, ok)
|
||||||
_, err = st.HashTreeRoot(context.Background())
|
_, err = st.HashTreeRoot(context.Background())
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
@@ -183,26 +293,24 @@ func TestBeaconState_AppendBalanceWithTrie(t *testing.T) {
|
|||||||
}
|
}
|
||||||
_, err = st.HashTreeRoot(context.Background())
|
_, err = st.HashTreeRoot(context.Background())
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
s, ok := st.(*BeaconState)
|
newRt := bytesutil.ToBytes32(st.merkleLayers[0][nativetypes.Balances])
|
||||||
require.Equal(t, true, ok)
|
wantedRt, err := stateutil.Uint64ListRootWithRegistryLimit(st.Balances())
|
||||||
newRt := bytesutil.ToBytes32(s.merkleLayers[0][balances])
|
|
||||||
wantedRt, err := stateutil.Uint64ListRootWithRegistryLimit(s.Balances())
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, wantedRt, newRt, "state roots are unequal")
|
assert.Equal(t, wantedRt, newRt, "state roots are unequal")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBeaconState_ModifyPreviousParticipationBits(t *testing.T) {
|
func TestBeaconState_ModifyPreviousParticipationBits(t *testing.T) {
|
||||||
st, err := InitializeFromProtoUnsafe(ðpb.BeaconState{})
|
st, err := InitializeFromProtoUnsafePhase0(ðpb.BeaconState{})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.ErrorContains(t, "ModifyPreviousParticipationBits is not supported for phase 0 beacon state", st.ModifyPreviousParticipationBits(func(val []byte) ([]byte, error) {
|
assert.ErrorContains(t, "ModifyPreviousParticipationBits is not supported", st.ModifyPreviousParticipationBits(func(val []byte) ([]byte, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBeaconState_ModifyCurrentParticipationBits(t *testing.T) {
|
func TestBeaconState_ModifyCurrentParticipationBits(t *testing.T) {
|
||||||
st, err := InitializeFromProtoUnsafe(ðpb.BeaconState{})
|
st, err := InitializeFromProtoUnsafePhase0(ðpb.BeaconState{})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.ErrorContains(t, "ModifyCurrentParticipationBits is not supported for phase 0 beacon state", st.ModifyCurrentParticipationBits(func(val []byte) ([]byte, error) {
|
assert.ErrorContains(t, "ModifyCurrentParticipationBits is not supported", st.ModifyCurrentParticipationBits(func(val []byte) ([]byte, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
792
beacon-chain/state/state-native/state_trie.go
Normal file
792
beacon-chain/state/state-native/state_trie.go
Normal file
@@ -0,0 +1,792 @@
|
|||||||
|
package state_native
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"runtime"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/fieldtrie"
|
||||||
|
customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types"
|
||||||
|
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/types"
|
||||||
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/container/slice"
|
||||||
|
"github.com/prysmaticlabs/prysm/crypto/hash"
|
||||||
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
|
"github.com/prysmaticlabs/prysm/encoding/ssz"
|
||||||
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
|
"go.opencensus.io/trace"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
var phase0Fields = []nativetypes.FieldIndex{
|
||||||
|
nativetypes.GenesisTime,
|
||||||
|
nativetypes.GenesisValidatorsRoot,
|
||||||
|
nativetypes.Slot,
|
||||||
|
nativetypes.Fork,
|
||||||
|
nativetypes.LatestBlockHeader,
|
||||||
|
nativetypes.BlockRoots,
|
||||||
|
nativetypes.StateRoots,
|
||||||
|
nativetypes.HistoricalRoots,
|
||||||
|
nativetypes.Eth1Data,
|
||||||
|
nativetypes.Eth1DataVotes,
|
||||||
|
nativetypes.Eth1DepositIndex,
|
||||||
|
nativetypes.Validators,
|
||||||
|
nativetypes.Balances,
|
||||||
|
nativetypes.RandaoMixes,
|
||||||
|
nativetypes.Slashings,
|
||||||
|
nativetypes.PreviousEpochAttestations,
|
||||||
|
nativetypes.CurrentEpochAttestations,
|
||||||
|
nativetypes.JustificationBits,
|
||||||
|
nativetypes.PreviousJustifiedCheckpoint,
|
||||||
|
nativetypes.CurrentJustifiedCheckpoint,
|
||||||
|
nativetypes.FinalizedCheckpoint,
|
||||||
|
}
|
||||||
|
|
||||||
|
var altairFields = []nativetypes.FieldIndex{
|
||||||
|
nativetypes.GenesisTime,
|
||||||
|
nativetypes.GenesisValidatorsRoot,
|
||||||
|
nativetypes.Slot,
|
||||||
|
nativetypes.Fork,
|
||||||
|
nativetypes.LatestBlockHeader,
|
||||||
|
nativetypes.BlockRoots,
|
||||||
|
nativetypes.StateRoots,
|
||||||
|
nativetypes.HistoricalRoots,
|
||||||
|
nativetypes.Eth1Data,
|
||||||
|
nativetypes.Eth1DataVotes,
|
||||||
|
nativetypes.Eth1DepositIndex,
|
||||||
|
nativetypes.Validators,
|
||||||
|
nativetypes.Balances,
|
||||||
|
nativetypes.RandaoMixes,
|
||||||
|
nativetypes.Slashings,
|
||||||
|
nativetypes.PreviousEpochParticipationBits,
|
||||||
|
nativetypes.CurrentEpochParticipationBits,
|
||||||
|
nativetypes.JustificationBits,
|
||||||
|
nativetypes.PreviousJustifiedCheckpoint,
|
||||||
|
nativetypes.CurrentJustifiedCheckpoint,
|
||||||
|
nativetypes.FinalizedCheckpoint,
|
||||||
|
nativetypes.InactivityScores,
|
||||||
|
nativetypes.CurrentSyncCommittee,
|
||||||
|
nativetypes.NextSyncCommittee,
|
||||||
|
}
|
||||||
|
|
||||||
|
var bellatrixFields = []nativetypes.FieldIndex{
|
||||||
|
nativetypes.GenesisTime,
|
||||||
|
nativetypes.GenesisValidatorsRoot,
|
||||||
|
nativetypes.Slot,
|
||||||
|
nativetypes.Fork,
|
||||||
|
nativetypes.LatestBlockHeader,
|
||||||
|
nativetypes.BlockRoots,
|
||||||
|
nativetypes.StateRoots,
|
||||||
|
nativetypes.HistoricalRoots,
|
||||||
|
nativetypes.Eth1Data,
|
||||||
|
nativetypes.Eth1DataVotes,
|
||||||
|
nativetypes.Eth1DepositIndex,
|
||||||
|
nativetypes.Validators,
|
||||||
|
nativetypes.Balances,
|
||||||
|
nativetypes.RandaoMixes,
|
||||||
|
nativetypes.Slashings,
|
||||||
|
nativetypes.PreviousEpochParticipationBits,
|
||||||
|
nativetypes.CurrentEpochParticipationBits,
|
||||||
|
nativetypes.JustificationBits,
|
||||||
|
nativetypes.PreviousJustifiedCheckpoint,
|
||||||
|
nativetypes.CurrentJustifiedCheckpoint,
|
||||||
|
nativetypes.FinalizedCheckpoint,
|
||||||
|
nativetypes.InactivityScores,
|
||||||
|
nativetypes.CurrentSyncCommittee,
|
||||||
|
nativetypes.NextSyncCommittee,
|
||||||
|
nativetypes.LatestExecutionPayloadHeader,
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitializeFromProtoPhase0 the beacon state from a protobuf representation.
|
||||||
|
func InitializeFromProtoPhase0(st *ethpb.BeaconState) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafePhase0(proto.Clone(st).(*ethpb.BeaconState))
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitializeFromProtoAltair the beacon state from a protobuf representation.
|
||||||
|
func InitializeFromProtoAltair(st *ethpb.BeaconStateAltair) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafeAltair(proto.Clone(st).(*ethpb.BeaconStateAltair))
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitializeFromProtoBellatrix the beacon state from a protobuf representation.
|
||||||
|
func InitializeFromProtoBellatrix(st *ethpb.BeaconStateBellatrix) (state.BeaconState, error) {
|
||||||
|
return InitializeFromProtoUnsafeBellatrix(proto.Clone(st).(*ethpb.BeaconStateBellatrix))
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitializeFromProtoUnsafePhase0 directly uses the beacon state protobuf fields
|
||||||
|
// and sets them as fields of the BeaconState type.
|
||||||
|
func InitializeFromProtoUnsafePhase0(st *ethpb.BeaconState) (state.BeaconState, error) {
|
||||||
|
if st == nil {
|
||||||
|
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{
|
||||||
|
version: version.Phase0,
|
||||||
|
genesisTime: st.GenesisTime,
|
||||||
|
genesisValidatorsRoot: bytesutil.ToBytes32(st.GenesisValidatorsRoot),
|
||||||
|
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,
|
||||||
|
justificationBits: st.JustificationBits,
|
||||||
|
previousJustifiedCheckpoint: st.PreviousJustifiedCheckpoint,
|
||||||
|
currentJustifiedCheckpoint: st.CurrentJustifiedCheckpoint,
|
||||||
|
finalizedCheckpoint: st.FinalizedCheckpoint,
|
||||||
|
|
||||||
|
dirtyFields: make(map[nativetypes.FieldIndex]bool, fieldCount),
|
||||||
|
dirtyIndices: make(map[nativetypes.FieldIndex][]uint64, fieldCount),
|
||||||
|
stateFieldLeaves: make(map[nativetypes.FieldIndex]*fieldtrie.FieldTrie, fieldCount),
|
||||||
|
sharedFieldReferences: make(map[nativetypes.FieldIndex]*stateutil.Reference, 10),
|
||||||
|
rebuildTrie: make(map[nativetypes.FieldIndex]bool, fieldCount),
|
||||||
|
valMapHandler: stateutil.NewValMapHandler(st.Validators),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range phase0Fields {
|
||||||
|
b.dirtyFields[f] = true
|
||||||
|
b.rebuildTrie[f] = true
|
||||||
|
b.dirtyIndices[f] = []uint64{}
|
||||||
|
trie, err := fieldtrie.NewFieldTrie(f, types.BasicArray, nil, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
b.stateFieldLeaves[f] = trie
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize field reference tracking for shared data.
|
||||||
|
b.sharedFieldReferences[nativetypes.BlockRoots] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.StateRoots] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.HistoricalRoots] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.Eth1DataVotes] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.Validators] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.Balances] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.RandaoMixes] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.Slashings] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.PreviousEpochAttestations] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.CurrentEpochAttestations] = stateutil.NewRef(1)
|
||||||
|
|
||||||
|
state.StateCount.Inc()
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitializeFromProtoUnsafeAltair directly uses the beacon state protobuf fields
|
||||||
|
// and sets them as fields of the BeaconState type.
|
||||||
|
func InitializeFromProtoUnsafeAltair(st *ethpb.BeaconStateAltair) (state.BeaconStateAltair, error) {
|
||||||
|
if st == nil {
|
||||||
|
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{
|
||||||
|
version: version.Altair,
|
||||||
|
genesisTime: st.GenesisTime,
|
||||||
|
genesisValidatorsRoot: bytesutil.ToBytes32(st.GenesisValidatorsRoot),
|
||||||
|
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,
|
||||||
|
justificationBits: st.JustificationBits,
|
||||||
|
previousJustifiedCheckpoint: st.PreviousJustifiedCheckpoint,
|
||||||
|
currentJustifiedCheckpoint: st.CurrentJustifiedCheckpoint,
|
||||||
|
finalizedCheckpoint: st.FinalizedCheckpoint,
|
||||||
|
inactivityScores: st.InactivityScores,
|
||||||
|
currentSyncCommittee: st.CurrentSyncCommittee,
|
||||||
|
nextSyncCommittee: st.NextSyncCommittee,
|
||||||
|
|
||||||
|
dirtyFields: make(map[nativetypes.FieldIndex]bool, fieldCount),
|
||||||
|
dirtyIndices: make(map[nativetypes.FieldIndex][]uint64, fieldCount),
|
||||||
|
stateFieldLeaves: make(map[nativetypes.FieldIndex]*fieldtrie.FieldTrie, fieldCount),
|
||||||
|
sharedFieldReferences: make(map[nativetypes.FieldIndex]*stateutil.Reference, 11),
|
||||||
|
rebuildTrie: make(map[nativetypes.FieldIndex]bool, fieldCount),
|
||||||
|
valMapHandler: stateutil.NewValMapHandler(st.Validators),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range altairFields {
|
||||||
|
b.dirtyFields[f] = true
|
||||||
|
b.rebuildTrie[f] = true
|
||||||
|
b.dirtyIndices[f] = []uint64{}
|
||||||
|
trie, err := fieldtrie.NewFieldTrie(f, types.BasicArray, nil, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
b.stateFieldLeaves[f] = trie
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize field reference tracking for shared data.
|
||||||
|
b.sharedFieldReferences[nativetypes.BlockRoots] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.StateRoots] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.HistoricalRoots] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.Eth1DataVotes] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.Validators] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.Balances] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.RandaoMixes] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.Slashings] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.PreviousEpochParticipationBits] = stateutil.NewRef(1) // New in Altair.
|
||||||
|
b.sharedFieldReferences[nativetypes.CurrentEpochParticipationBits] = stateutil.NewRef(1) // New in Altair.
|
||||||
|
b.sharedFieldReferences[nativetypes.InactivityScores] = stateutil.NewRef(1) // New in Altair.
|
||||||
|
|
||||||
|
state.StateCount.Inc()
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitializeFromProtoUnsafeBellatrix directly uses the beacon state protobuf fields
|
||||||
|
// and sets them as fields of the BeaconState type.
|
||||||
|
func InitializeFromProtoUnsafeBellatrix(st *ethpb.BeaconStateBellatrix) (state.BeaconStateBellatrix, error) {
|
||||||
|
if st == nil {
|
||||||
|
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{
|
||||||
|
version: version.Bellatrix,
|
||||||
|
genesisTime: st.GenesisTime,
|
||||||
|
genesisValidatorsRoot: bytesutil.ToBytes32(st.GenesisValidatorsRoot),
|
||||||
|
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,
|
||||||
|
justificationBits: st.JustificationBits,
|
||||||
|
previousJustifiedCheckpoint: st.PreviousJustifiedCheckpoint,
|
||||||
|
currentJustifiedCheckpoint: st.CurrentJustifiedCheckpoint,
|
||||||
|
finalizedCheckpoint: st.FinalizedCheckpoint,
|
||||||
|
inactivityScores: st.InactivityScores,
|
||||||
|
currentSyncCommittee: st.CurrentSyncCommittee,
|
||||||
|
nextSyncCommittee: st.NextSyncCommittee,
|
||||||
|
latestExecutionPayloadHeader: st.LatestExecutionPayloadHeader,
|
||||||
|
|
||||||
|
dirtyFields: make(map[nativetypes.FieldIndex]bool, fieldCount),
|
||||||
|
dirtyIndices: make(map[nativetypes.FieldIndex][]uint64, fieldCount),
|
||||||
|
stateFieldLeaves: make(map[nativetypes.FieldIndex]*fieldtrie.FieldTrie, fieldCount),
|
||||||
|
sharedFieldReferences: make(map[nativetypes.FieldIndex]*stateutil.Reference, 11),
|
||||||
|
rebuildTrie: make(map[nativetypes.FieldIndex]bool, fieldCount),
|
||||||
|
valMapHandler: stateutil.NewValMapHandler(st.Validators),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range bellatrixFields {
|
||||||
|
b.dirtyFields[f] = true
|
||||||
|
b.rebuildTrie[f] = true
|
||||||
|
b.dirtyIndices[f] = []uint64{}
|
||||||
|
trie, err := fieldtrie.NewFieldTrie(f, types.BasicArray, nil, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
b.stateFieldLeaves[f] = trie
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize field reference tracking for shared data.
|
||||||
|
b.sharedFieldReferences[nativetypes.BlockRoots] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.StateRoots] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.HistoricalRoots] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.Eth1DataVotes] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.Validators] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.Balances] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.RandaoMixes] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.Slashings] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.PreviousEpochParticipationBits] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.CurrentEpochParticipationBits] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.InactivityScores] = stateutil.NewRef(1)
|
||||||
|
b.sharedFieldReferences[nativetypes.LatestExecutionPayloadHeader] = stateutil.NewRef(1) // New in Bellatrix.
|
||||||
|
|
||||||
|
state.StateCount.Inc()
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy returns a deep copy of the beacon state.
|
||||||
|
func (b *BeaconState) Copy() state.BeaconState {
|
||||||
|
b.lock.RLock()
|
||||||
|
defer b.lock.RUnlock()
|
||||||
|
|
||||||
|
var fieldCount int
|
||||||
|
switch b.version {
|
||||||
|
case version.Phase0:
|
||||||
|
fieldCount = params.BeaconConfig().BeaconStateFieldCount
|
||||||
|
case version.Altair:
|
||||||
|
fieldCount = params.BeaconConfig().BeaconStateAltairFieldCount
|
||||||
|
case version.Bellatrix:
|
||||||
|
fieldCount = params.BeaconConfig().BeaconStateBellatrixFieldCount
|
||||||
|
}
|
||||||
|
|
||||||
|
dst := &BeaconState{
|
||||||
|
version: b.version,
|
||||||
|
|
||||||
|
// Primitive nativetypes, safe to copy.
|
||||||
|
genesisTime: b.genesisTime,
|
||||||
|
slot: b.slot,
|
||||||
|
eth1DepositIndex: b.eth1DepositIndex,
|
||||||
|
|
||||||
|
// Large arrays, infrequently changed, constant size.
|
||||||
|
blockRoots: b.blockRoots,
|
||||||
|
stateRoots: b.stateRoots,
|
||||||
|
randaoMixes: b.randaoMixes,
|
||||||
|
previousEpochAttestations: b.previousEpochAttestations,
|
||||||
|
currentEpochAttestations: b.currentEpochAttestations,
|
||||||
|
eth1DataVotes: b.eth1DataVotes,
|
||||||
|
slashings: b.slashings,
|
||||||
|
|
||||||
|
// Large arrays, increases over time.
|
||||||
|
balances: b.balances,
|
||||||
|
historicalRoots: b.historicalRoots,
|
||||||
|
validators: b.validators,
|
||||||
|
previousEpochParticipation: b.previousEpochParticipation,
|
||||||
|
currentEpochParticipation: b.currentEpochParticipation,
|
||||||
|
inactivityScores: b.inactivityScores,
|
||||||
|
|
||||||
|
// Everything else, too small to be concerned about, constant size.
|
||||||
|
genesisValidatorsRoot: b.genesisValidatorsRoot,
|
||||||
|
justificationBits: b.justificationBitsVal(),
|
||||||
|
fork: b.forkVal(),
|
||||||
|
latestBlockHeader: b.latestBlockHeaderVal(),
|
||||||
|
eth1Data: b.eth1DataVal(),
|
||||||
|
previousJustifiedCheckpoint: b.previousJustifiedCheckpointVal(),
|
||||||
|
currentJustifiedCheckpoint: b.currentJustifiedCheckpointVal(),
|
||||||
|
finalizedCheckpoint: b.finalizedCheckpointVal(),
|
||||||
|
currentSyncCommittee: b.currentSyncCommitteeVal(),
|
||||||
|
nextSyncCommittee: b.nextSyncCommitteeVal(),
|
||||||
|
latestExecutionPayloadHeader: b.latestExecutionPayloadHeaderVal(),
|
||||||
|
|
||||||
|
dirtyFields: make(map[nativetypes.FieldIndex]bool, fieldCount),
|
||||||
|
dirtyIndices: make(map[nativetypes.FieldIndex][]uint64, fieldCount),
|
||||||
|
rebuildTrie: make(map[nativetypes.FieldIndex]bool, fieldCount),
|
||||||
|
stateFieldLeaves: make(map[nativetypes.FieldIndex]*fieldtrie.FieldTrie, fieldCount),
|
||||||
|
|
||||||
|
// Share the reference to validator index map.
|
||||||
|
valMapHandler: b.valMapHandler,
|
||||||
|
}
|
||||||
|
|
||||||
|
switch b.version {
|
||||||
|
case version.Phase0:
|
||||||
|
dst.sharedFieldReferences = make(map[nativetypes.FieldIndex]*stateutil.Reference, 10)
|
||||||
|
case version.Altair:
|
||||||
|
dst.sharedFieldReferences = make(map[nativetypes.FieldIndex]*stateutil.Reference, 11)
|
||||||
|
case version.Bellatrix:
|
||||||
|
dst.sharedFieldReferences = make(map[nativetypes.FieldIndex]*stateutil.Reference, 11)
|
||||||
|
}
|
||||||
|
|
||||||
|
for field, ref := range b.sharedFieldReferences {
|
||||||
|
ref.AddRef()
|
||||||
|
dst.sharedFieldReferences[field] = ref
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment ref for validator map
|
||||||
|
b.valMapHandler.AddRef()
|
||||||
|
|
||||||
|
for i := range b.dirtyFields {
|
||||||
|
dst.dirtyFields[i] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range b.dirtyIndices {
|
||||||
|
indices := make([]uint64, len(b.dirtyIndices[i]))
|
||||||
|
copy(indices, b.dirtyIndices[i])
|
||||||
|
dst.dirtyIndices[i] = indices
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range b.rebuildTrie {
|
||||||
|
dst.rebuildTrie[i] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
for fldIdx, fieldTrie := range b.stateFieldLeaves {
|
||||||
|
dst.stateFieldLeaves[fldIdx] = fieldTrie
|
||||||
|
if fieldTrie.FieldReference() != nil {
|
||||||
|
fieldTrie.Lock()
|
||||||
|
fieldTrie.FieldReference().AddRef()
|
||||||
|
fieldTrie.Unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.merkleLayers != nil {
|
||||||
|
dst.merkleLayers = make([][][]byte, len(b.merkleLayers))
|
||||||
|
for i, layer := range b.merkleLayers {
|
||||||
|
dst.merkleLayers[i] = make([][]byte, len(layer))
|
||||||
|
for j, content := range layer {
|
||||||
|
dst.merkleLayers[i][j] = make([]byte, len(content))
|
||||||
|
copy(dst.merkleLayers[i][j], content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
state.StateCount.Inc()
|
||||||
|
// Finalizer runs when dst is being destroyed in garbage collection.
|
||||||
|
runtime.SetFinalizer(dst, func(b *BeaconState) {
|
||||||
|
for field, v := range b.sharedFieldReferences {
|
||||||
|
v.MinusRef()
|
||||||
|
if b.stateFieldLeaves[field].FieldReference() != nil {
|
||||||
|
b.stateFieldLeaves[field].FieldReference().MinusRef()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
for i := range b.dirtyFields {
|
||||||
|
delete(b.dirtyFields, i)
|
||||||
|
}
|
||||||
|
for i := range b.rebuildTrie {
|
||||||
|
delete(b.rebuildTrie, i)
|
||||||
|
}
|
||||||
|
for i := range b.dirtyIndices {
|
||||||
|
delete(b.dirtyIndices, i)
|
||||||
|
}
|
||||||
|
for i := range b.sharedFieldReferences {
|
||||||
|
delete(b.sharedFieldReferences, i)
|
||||||
|
}
|
||||||
|
for i := range b.stateFieldLeaves {
|
||||||
|
delete(b.stateFieldLeaves, i)
|
||||||
|
}
|
||||||
|
state.StateCount.Sub(1)
|
||||||
|
})
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// HashTreeRoot of the beacon state retrieves the Merkle root of the trie
|
||||||
|
// representation of the beacon state based on the Ethereum Simple Serialize specification.
|
||||||
|
func (b *BeaconState) HashTreeRoot(ctx context.Context) ([32]byte, error) {
|
||||||
|
ctx, span := trace.StartSpan(ctx, "beaconState.HashTreeRoot")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
b.lock.Lock()
|
||||||
|
defer b.lock.Unlock()
|
||||||
|
if err := b.initializeMerkleLayers(ctx); err != nil {
|
||||||
|
return [32]byte{}, err
|
||||||
|
}
|
||||||
|
if err := b.recomputeDirtyFields(ctx); err != nil {
|
||||||
|
return [32]byte{}, err
|
||||||
|
}
|
||||||
|
return bytesutil.ToBytes32(b.merkleLayers[len(b.merkleLayers)-1][0]), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initializes the Merkle layers for the beacon state if they are empty.
|
||||||
|
// WARNING: Caller must acquire the mutex before using.
|
||||||
|
func (b *BeaconState) initializeMerkleLayers(ctx context.Context) error {
|
||||||
|
if len(b.merkleLayers) > 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
fieldRoots, err := ComputeFieldRootsWithHasher(ctx, b)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
layers := stateutil.Merkleize(fieldRoots)
|
||||||
|
b.merkleLayers = layers
|
||||||
|
switch b.version {
|
||||||
|
case version.Phase0:
|
||||||
|
b.dirtyFields = make(map[nativetypes.FieldIndex]bool, params.BeaconConfig().BeaconStateFieldCount)
|
||||||
|
case version.Altair:
|
||||||
|
b.dirtyFields = make(map[nativetypes.FieldIndex]bool, params.BeaconConfig().BeaconStateAltairFieldCount)
|
||||||
|
case version.Bellatrix:
|
||||||
|
b.dirtyFields = make(map[nativetypes.FieldIndex]bool, params.BeaconConfig().BeaconStateBellatrixFieldCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recomputes the Merkle layers for the dirty fields in the state.
|
||||||
|
// WARNING: Caller must acquire the mutex before using.
|
||||||
|
func (b *BeaconState) recomputeDirtyFields(ctx context.Context) error {
|
||||||
|
for field := range b.dirtyFields {
|
||||||
|
root, err := b.rootSelector(ctx, field)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
idx := field.RealPosition()
|
||||||
|
b.merkleLayers[0][idx] = root[:]
|
||||||
|
b.recomputeRoot(idx)
|
||||||
|
delete(b.dirtyFields, field)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FieldReferencesCount returns the reference count held by each field. This
|
||||||
|
// also includes the field trie held by each field.
|
||||||
|
func (b *BeaconState) FieldReferencesCount() map[string]uint64 {
|
||||||
|
refMap := make(map[string]uint64)
|
||||||
|
b.lock.RLock()
|
||||||
|
defer b.lock.RUnlock()
|
||||||
|
for i, f := range b.sharedFieldReferences {
|
||||||
|
refMap[i.String(b.version)] = uint64(f.Refs())
|
||||||
|
}
|
||||||
|
for i, f := range b.stateFieldLeaves {
|
||||||
|
numOfRefs := uint64(f.FieldReference().Refs())
|
||||||
|
f.RLock()
|
||||||
|
if !f.Empty() {
|
||||||
|
refMap[i.String(b.version)+"_trie"] = numOfRefs
|
||||||
|
}
|
||||||
|
f.RUnlock()
|
||||||
|
}
|
||||||
|
return refMap
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNil checks if the state and the underlying proto
|
||||||
|
// object are nil.
|
||||||
|
func (b *BeaconState) IsNil() bool {
|
||||||
|
return b == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BeaconState) rootSelector(ctx context.Context, field nativetypes.FieldIndex) ([32]byte, error) {
|
||||||
|
_, span := trace.StartSpan(ctx, "beaconState.rootSelector")
|
||||||
|
defer span.End()
|
||||||
|
span.AddAttributes(trace.StringAttribute("field", field.String(b.version)))
|
||||||
|
|
||||||
|
hasher := hash.CustomSHA256Hasher()
|
||||||
|
switch field {
|
||||||
|
case nativetypes.GenesisTime:
|
||||||
|
return ssz.Uint64Root(b.genesisTime), nil
|
||||||
|
case nativetypes.GenesisValidatorsRoot:
|
||||||
|
return b.genesisValidatorsRoot, nil
|
||||||
|
case nativetypes.Slot:
|
||||||
|
return ssz.Uint64Root(uint64(b.slot)), nil
|
||||||
|
case nativetypes.Eth1DepositIndex:
|
||||||
|
return ssz.Uint64Root(b.eth1DepositIndex), nil
|
||||||
|
case nativetypes.Fork:
|
||||||
|
return ssz.ForkRoot(b.fork)
|
||||||
|
case nativetypes.LatestBlockHeader:
|
||||||
|
return stateutil.BlockHeaderRoot(b.latestBlockHeader)
|
||||||
|
case nativetypes.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)
|
||||||
|
case nativetypes.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)
|
||||||
|
case nativetypes.HistoricalRoots:
|
||||||
|
hRoots := make([][]byte, len(b.historicalRoots))
|
||||||
|
for i := range hRoots {
|
||||||
|
hRoots[i] = b.historicalRoots[i][:]
|
||||||
|
}
|
||||||
|
return ssz.ByteArrayRootWithLimit(hRoots, fieldparams.HistoricalRootsLength)
|
||||||
|
case nativetypes.Eth1Data:
|
||||||
|
return stateutil.Eth1Root(hasher, b.eth1Data)
|
||||||
|
case nativetypes.Eth1DataVotes:
|
||||||
|
if b.rebuildTrie[field] {
|
||||||
|
err := b.resetFieldTrie(
|
||||||
|
field,
|
||||||
|
b.eth1DataVotes,
|
||||||
|
fieldparams.Eth1DataVotesLength,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return [32]byte{}, err
|
||||||
|
}
|
||||||
|
delete(b.rebuildTrie, field)
|
||||||
|
return b.stateFieldLeaves[field].TrieRoot()
|
||||||
|
}
|
||||||
|
return b.recomputeFieldTrie(field, b.eth1DataVotes)
|
||||||
|
case nativetypes.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)
|
||||||
|
case nativetypes.Balances:
|
||||||
|
if b.rebuildTrie[field] {
|
||||||
|
maxBalCap := uint64(fieldparams.ValidatorRegistryLimit)
|
||||||
|
elemSize := uint64(8)
|
||||||
|
balLimit := (maxBalCap*elemSize + 31) / 32
|
||||||
|
err := b.resetFieldTrie(field, b.balances, balLimit)
|
||||||
|
if err != nil {
|
||||||
|
return [32]byte{}, err
|
||||||
|
}
|
||||||
|
delete(b.rebuildTrie, field)
|
||||||
|
return b.stateFieldLeaves[field].TrieRoot()
|
||||||
|
}
|
||||||
|
return b.recomputeFieldTrie(12, b.balances)
|
||||||
|
case nativetypes.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)
|
||||||
|
case nativetypes.Slashings:
|
||||||
|
return ssz.SlashingsRoot(b.slashings)
|
||||||
|
case nativetypes.PreviousEpochAttestations:
|
||||||
|
if b.rebuildTrie[field] {
|
||||||
|
err := b.resetFieldTrie(
|
||||||
|
field,
|
||||||
|
b.previousEpochAttestations,
|
||||||
|
fieldparams.PreviousEpochAttestationsLength,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return [32]byte{}, err
|
||||||
|
}
|
||||||
|
delete(b.rebuildTrie, field)
|
||||||
|
return b.stateFieldLeaves[field].TrieRoot()
|
||||||
|
}
|
||||||
|
return b.recomputeFieldTrie(field, b.previousEpochAttestations)
|
||||||
|
case nativetypes.CurrentEpochAttestations:
|
||||||
|
if b.rebuildTrie[field] {
|
||||||
|
err := b.resetFieldTrie(
|
||||||
|
field,
|
||||||
|
b.currentEpochAttestations,
|
||||||
|
fieldparams.CurrentEpochAttestationsLength,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return [32]byte{}, err
|
||||||
|
}
|
||||||
|
delete(b.rebuildTrie, field)
|
||||||
|
return b.stateFieldLeaves[field].TrieRoot()
|
||||||
|
}
|
||||||
|
return b.recomputeFieldTrie(field, b.currentEpochAttestations)
|
||||||
|
case nativetypes.PreviousEpochParticipationBits:
|
||||||
|
return stateutil.ParticipationBitsRoot(b.previousEpochParticipation)
|
||||||
|
case nativetypes.CurrentEpochParticipationBits:
|
||||||
|
return stateutil.ParticipationBitsRoot(b.currentEpochParticipation)
|
||||||
|
case nativetypes.JustificationBits:
|
||||||
|
return bytesutil.ToBytes32(b.justificationBits), nil
|
||||||
|
case nativetypes.PreviousJustifiedCheckpoint:
|
||||||
|
return ssz.CheckpointRoot(hasher, b.previousJustifiedCheckpoint)
|
||||||
|
case nativetypes.CurrentJustifiedCheckpoint:
|
||||||
|
return ssz.CheckpointRoot(hasher, b.currentJustifiedCheckpoint)
|
||||||
|
case nativetypes.FinalizedCheckpoint:
|
||||||
|
return ssz.CheckpointRoot(hasher, b.finalizedCheckpoint)
|
||||||
|
case nativetypes.InactivityScores:
|
||||||
|
return stateutil.Uint64ListRootWithRegistryLimit(b.inactivityScores)
|
||||||
|
case nativetypes.CurrentSyncCommittee:
|
||||||
|
return stateutil.SyncCommitteeRoot(b.currentSyncCommittee)
|
||||||
|
case nativetypes.NextSyncCommittee:
|
||||||
|
return stateutil.SyncCommitteeRoot(b.nextSyncCommittee)
|
||||||
|
case nativetypes.LatestExecutionPayloadHeader:
|
||||||
|
return b.latestExecutionPayloadHeader.HashTreeRoot()
|
||||||
|
}
|
||||||
|
return [32]byte{}, errors.New("invalid field index provided")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BeaconState) recomputeFieldTrie(index nativetypes.FieldIndex, elements interface{}) ([32]byte, error) {
|
||||||
|
fTrie := b.stateFieldLeaves[index]
|
||||||
|
// We can't lock the trie directly because the trie's variable gets reassigned,
|
||||||
|
// and therefore we would call Unlock() on a different object.
|
||||||
|
fTrieMutex := fTrie.RWMutex
|
||||||
|
if fTrie.FieldReference().Refs() > 1 {
|
||||||
|
fTrieMutex.Lock()
|
||||||
|
fTrie.FieldReference().MinusRef()
|
||||||
|
newTrie := fTrie.CopyTrie()
|
||||||
|
b.stateFieldLeaves[index] = newTrie
|
||||||
|
fTrie = newTrie
|
||||||
|
fTrieMutex.Unlock()
|
||||||
|
}
|
||||||
|
// remove duplicate indexes
|
||||||
|
b.dirtyIndices[index] = slice.SetUint64(b.dirtyIndices[index])
|
||||||
|
// sort indexes again
|
||||||
|
sort.Slice(b.dirtyIndices[index], func(i int, j int) bool {
|
||||||
|
return b.dirtyIndices[index][i] < b.dirtyIndices[index][j]
|
||||||
|
})
|
||||||
|
root, err := fTrie.RecomputeTrie(b.dirtyIndices[index], elements)
|
||||||
|
if err != nil {
|
||||||
|
return [32]byte{}, err
|
||||||
|
}
|
||||||
|
b.dirtyIndices[index] = []uint64{}
|
||||||
|
return root, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BeaconState) resetFieldTrie(index nativetypes.FieldIndex, elements interface{}, length uint64) error {
|
||||||
|
fTrie, err := fieldtrie.NewFieldTrie(index, fieldMap[index], elements, length)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
b.stateFieldLeaves[index] = fTrie
|
||||||
|
b.dirtyIndices[index] = []uint64{}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package v1_test
|
package state_native_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/v1"
|
statenative "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||||
@@ -15,9 +15,9 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestInitializeFromProto(t *testing.T) {
|
func TestInitializeFromProto_Phase0(t *testing.T) {
|
||||||
testState, _ := util.DeterministicGenesisState(t, 64)
|
testState, _ := util.DeterministicGenesisState(t, 64)
|
||||||
pbState, err := v1.ProtobufBeaconState(testState.InnerStateUnsafe())
|
pbState, err := statenative.ProtobufBeaconStatePhase0(testState.InnerStateUnsafe())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
type test struct {
|
type test struct {
|
||||||
name string
|
name string
|
||||||
@@ -48,7 +48,7 @@ func TestInitializeFromProto(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, tt := range initTests {
|
for _, tt := range initTests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
_, err := v1.InitializeFromProto(tt.state)
|
_, err := statenative.InitializeFromProtoUnsafePhase0(tt.state)
|
||||||
if tt.error != "" {
|
if tt.error != "" {
|
||||||
assert.ErrorContains(t, tt.error, err)
|
assert.ErrorContains(t, tt.error, err)
|
||||||
} else {
|
} else {
|
||||||
@@ -58,13 +58,10 @@ func TestInitializeFromProto(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInitializeFromProtoUnsafe(t *testing.T) {
|
func TestInitializeFromProto_Altair(t *testing.T) {
|
||||||
testState, _ := util.DeterministicGenesisState(t, 64)
|
|
||||||
pbState, err := v1.ProtobufBeaconState(testState.InnerStateUnsafe())
|
|
||||||
require.NoError(t, err)
|
|
||||||
type test struct {
|
type test struct {
|
||||||
name string
|
name string
|
||||||
state *ethpb.BeaconState
|
state *ethpb.BeaconStateAltair
|
||||||
error string
|
error string
|
||||||
}
|
}
|
||||||
initTests := []test{
|
initTests := []test{
|
||||||
@@ -73,6 +70,77 @@ func TestInitializeFromProtoUnsafe(t *testing.T) {
|
|||||||
state: nil,
|
state: nil,
|
||||||
error: "received nil state",
|
error: "received nil state",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "nil validators",
|
||||||
|
state: ðpb.BeaconStateAltair{
|
||||||
|
Slot: 4,
|
||||||
|
Validators: nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty state",
|
||||||
|
state: ðpb.BeaconStateAltair{},
|
||||||
|
},
|
||||||
|
// TODO: Add full state. Blocked by testutil migration.
|
||||||
|
}
|
||||||
|
for _, tt := range initTests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
_, err := statenative.InitializeFromProtoAltair(tt.state)
|
||||||
|
if tt.error != "" {
|
||||||
|
require.ErrorContains(t, tt.error, err)
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInitializeFromProto_Bellatrix(t *testing.T) {
|
||||||
|
type test struct {
|
||||||
|
name string
|
||||||
|
state *ethpb.BeaconStateBellatrix
|
||||||
|
error string
|
||||||
|
}
|
||||||
|
initTests := []test{
|
||||||
|
{
|
||||||
|
name: "nil state",
|
||||||
|
state: nil,
|
||||||
|
error: "received nil state",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "nil validators",
|
||||||
|
state: ðpb.BeaconStateBellatrix{
|
||||||
|
Slot: 4,
|
||||||
|
Validators: nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty state",
|
||||||
|
state: ðpb.BeaconStateBellatrix{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range initTests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
_, err := statenative.InitializeFromProtoBellatrix(tt.state)
|
||||||
|
if tt.error != "" {
|
||||||
|
require.ErrorContains(t, tt.error, err)
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInitializeFromProtoUnsafe_Phase0(t *testing.T) {
|
||||||
|
testState, _ := util.DeterministicGenesisState(t, 64)
|
||||||
|
pbState, err := statenative.ProtobufBeaconStatePhase0(testState.InnerStateUnsafe())
|
||||||
|
require.NoError(t, err)
|
||||||
|
type test struct {
|
||||||
|
name string
|
||||||
|
state *ethpb.BeaconState
|
||||||
|
error string
|
||||||
|
}
|
||||||
|
initTests := []test{
|
||||||
{
|
{
|
||||||
name: "nil validators",
|
name: "nil validators",
|
||||||
state: ðpb.BeaconState{
|
state: ðpb.BeaconState{
|
||||||
@@ -91,7 +159,7 @@ func TestInitializeFromProtoUnsafe(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, tt := range initTests {
|
for _, tt := range initTests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
_, err := v1.InitializeFromProtoUnsafe(tt.state)
|
_, err := statenative.InitializeFromProtoUnsafePhase0(tt.state)
|
||||||
if tt.error != "" {
|
if tt.error != "" {
|
||||||
assert.ErrorContains(t, tt.error, err)
|
assert.ErrorContains(t, tt.error, err)
|
||||||
} else {
|
} else {
|
||||||
@@ -101,6 +169,52 @@ func TestInitializeFromProtoUnsafe(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestInitializeFromProtoUnsafe_Altair(t *testing.T) {
|
||||||
|
type test struct {
|
||||||
|
name string
|
||||||
|
state *ethpb.BeaconStateAltair
|
||||||
|
error string
|
||||||
|
}
|
||||||
|
initTests := []test{
|
||||||
|
{
|
||||||
|
name: "nil validators",
|
||||||
|
state: ðpb.BeaconStateAltair{
|
||||||
|
Slot: 4,
|
||||||
|
Validators: nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty state",
|
||||||
|
state: ðpb.BeaconStateAltair{},
|
||||||
|
},
|
||||||
|
// TODO: Add full state. Blocked by testutil migration.
|
||||||
|
}
|
||||||
|
_ = initTests
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInitializeFromProtoUnsafe_Bellatrix(t *testing.T) {
|
||||||
|
type test struct {
|
||||||
|
name string
|
||||||
|
state *ethpb.BeaconStateBellatrix
|
||||||
|
error string
|
||||||
|
}
|
||||||
|
initTests := []test{
|
||||||
|
{
|
||||||
|
name: "nil validators",
|
||||||
|
state: ðpb.BeaconStateBellatrix{
|
||||||
|
Slot: 4,
|
||||||
|
Validators: nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty state",
|
||||||
|
state: ðpb.BeaconStateBellatrix{},
|
||||||
|
},
|
||||||
|
// TODO: Add full state. Blocked by testutil migration.
|
||||||
|
}
|
||||||
|
_ = initTests
|
||||||
|
}
|
||||||
|
|
||||||
func TestBeaconState_HashTreeRoot(t *testing.T) {
|
func TestBeaconState_HashTreeRoot(t *testing.T) {
|
||||||
testState, _ := util.DeterministicGenesisState(t, 64)
|
testState, _ := util.DeterministicGenesisState(t, 64)
|
||||||
|
|
||||||
@@ -154,7 +268,7 @@ func TestBeaconState_HashTreeRoot(t *testing.T) {
|
|||||||
if err == nil && tt.error != "" {
|
if err == nil && tt.error != "" {
|
||||||
t.Errorf("Expected error, expected %v, recevied %v", tt.error, err)
|
t.Errorf("Expected error, expected %v, recevied %v", tt.error, err)
|
||||||
}
|
}
|
||||||
pbState, err := v1.ProtobufBeaconState(testState.InnerStateUnsafe())
|
pbState, err := statenative.ProtobufBeaconStatePhase0(testState.InnerStateUnsafe())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
genericHTR, err := pbState.HashTreeRoot()
|
genericHTR, err := pbState.HashTreeRoot()
|
||||||
if err == nil && tt.error != "" {
|
if err == nil && tt.error != "" {
|
||||||
@@ -170,6 +284,24 @@ func TestBeaconState_HashTreeRoot(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkBeaconState(b *testing.B) {
|
||||||
|
testState, _ := util.DeterministicGenesisState(b, 16000)
|
||||||
|
pbState, err := statenative.ProtobufBeaconStatePhase0(testState.InnerStateUnsafe())
|
||||||
|
require.NoError(b, err)
|
||||||
|
|
||||||
|
b.Run("Vectorized SHA256", func(b *testing.B) {
|
||||||
|
st, err := statenative.InitializeFromProtoUnsafePhase0(pbState)
|
||||||
|
require.NoError(b, err)
|
||||||
|
_, err = st.HashTreeRoot(context.Background())
|
||||||
|
assert.NoError(b, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
b.Run("Current SHA256", func(b *testing.B) {
|
||||||
|
_, err := pbState.HashTreeRoot()
|
||||||
|
require.NoError(b, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestBeaconState_HashTreeRoot_FieldTrie(t *testing.T) {
|
func TestBeaconState_HashTreeRoot_FieldTrie(t *testing.T) {
|
||||||
testState, _ := util.DeterministicGenesisState(t, 64)
|
testState, _ := util.DeterministicGenesisState(t, 64)
|
||||||
|
|
||||||
@@ -223,7 +355,7 @@ func TestBeaconState_HashTreeRoot_FieldTrie(t *testing.T) {
|
|||||||
if err == nil && tt.error != "" {
|
if err == nil && tt.error != "" {
|
||||||
t.Errorf("Expected error, expected %v, recevied %v", tt.error, err)
|
t.Errorf("Expected error, expected %v, recevied %v", tt.error, err)
|
||||||
}
|
}
|
||||||
pbState, err := v1.ProtobufBeaconState(testState.InnerStateUnsafe())
|
pbState, err := statenative.ProtobufBeaconStatePhase0(testState.InnerStateUnsafe())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
genericHTR, err := pbState.HashTreeRoot()
|
genericHTR, err := pbState.HashTreeRoot()
|
||||||
if err == nil && tt.error != "" {
|
if err == nil && tt.error != "" {
|
||||||
@@ -251,21 +383,3 @@ func TestBeaconState_AppendValidator_DoesntMutateCopy(t *testing.T) {
|
|||||||
_, ok := st1.ValidatorIndexByPubkey(bytesutil.ToBytes48(val.PublicKey))
|
_, ok := st1.ValidatorIndexByPubkey(bytesutil.ToBytes48(val.PublicKey))
|
||||||
assert.Equal(t, false, ok, "Expected no validator index to be present in st1 for the newly inserted pubkey")
|
assert.Equal(t, false, ok, "Expected no validator index to be present in st1 for the newly inserted pubkey")
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkBeaconState(b *testing.B) {
|
|
||||||
testState, _ := util.DeterministicGenesisState(b, 16000)
|
|
||||||
pbState, err := v1.ProtobufBeaconState(testState.InnerStateUnsafe())
|
|
||||||
require.NoError(b, err)
|
|
||||||
|
|
||||||
b.Run("Vectorized SHA256", func(b *testing.B) {
|
|
||||||
st, err := v1.InitializeFromProtoUnsafe(pbState)
|
|
||||||
require.NoError(b, err)
|
|
||||||
_, err = st.HashTreeRoot(context.Background())
|
|
||||||
assert.NoError(b, err)
|
|
||||||
})
|
|
||||||
|
|
||||||
b.Run("Current SHA256", func(b *testing.B) {
|
|
||||||
_, err := pbState.HashTreeRoot()
|
|
||||||
require.NoError(b, err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
36
beacon-chain/state/state-native/types.go
Normal file
36
beacon-chain/state/state-native/types.go
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
package state_native
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||||
|
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
|
||||||
|
"github.com/prysmaticlabs/prysm/beacon-chain/state/types"
|
||||||
|
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Ensure type BeaconState below implements BeaconState interface.
|
||||||
|
var _ state.BeaconState = (*BeaconState)(nil)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
fieldMap = make(map[nativetypes.FieldIndex]types.DataType)
|
||||||
|
// Initialize the fixed sized arrays.
|
||||||
|
fieldMap[nativetypes.BlockRoots] = types.BasicArray
|
||||||
|
fieldMap[nativetypes.StateRoots] = types.BasicArray
|
||||||
|
fieldMap[nativetypes.RandaoMixes] = types.BasicArray
|
||||||
|
|
||||||
|
// Initialize the composite arrays.
|
||||||
|
fieldMap[nativetypes.Eth1DataVotes] = types.CompositeArray
|
||||||
|
fieldMap[nativetypes.Validators] = types.CompositeArray
|
||||||
|
fieldMap[nativetypes.PreviousEpochAttestations] = types.CompositeArray
|
||||||
|
fieldMap[nativetypes.CurrentEpochAttestations] = types.CompositeArray
|
||||||
|
fieldMap[nativetypes.Balances] = types.CompressedArray
|
||||||
|
}
|
||||||
|
|
||||||
|
// fieldMap keeps track of each field
|
||||||
|
// to its corresponding data type.
|
||||||
|
var fieldMap map[nativetypes.FieldIndex]types.DataType
|
||||||
|
|
||||||
|
func errNotSupported(funcName string, ver int) error {
|
||||||
|
return fmt.Errorf("%s is not supported for %s", funcName, version.String(ver))
|
||||||
|
}
|
||||||
9
beacon-chain/state/state-native/types/BUILD.bazel
Normal file
9
beacon-chain/state/state-native/types/BUILD.bazel
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
load("@prysm//tools/go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = ["types.go"],
|
||||||
|
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = ["@com_github_pkg_errors//:go_default_library"],
|
||||||
|
)
|
||||||
181
beacon-chain/state/state-native/types/types.go
Normal file
181
beacon-chain/state/state-native/types/types.go
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FieldIndex represents the relevant field position in the
|
||||||
|
// state struct for a field.
|
||||||
|
type FieldIndex int
|
||||||
|
|
||||||
|
// String returns the name of the field index.
|
||||||
|
func (f FieldIndex) String(_ int) string {
|
||||||
|
switch f {
|
||||||
|
case GenesisTime:
|
||||||
|
return "genesisTime"
|
||||||
|
case GenesisValidatorsRoot:
|
||||||
|
return "genesisValidatorsRoot"
|
||||||
|
case Slot:
|
||||||
|
return "slot"
|
||||||
|
case Fork:
|
||||||
|
return "fork"
|
||||||
|
case LatestBlockHeader:
|
||||||
|
return "latestBlockHeader"
|
||||||
|
case BlockRoots:
|
||||||
|
return "blockRoots"
|
||||||
|
case StateRoots:
|
||||||
|
return "stateRoots"
|
||||||
|
case HistoricalRoots:
|
||||||
|
return "historicalRoots"
|
||||||
|
case Eth1Data:
|
||||||
|
return "eth1Data"
|
||||||
|
case Eth1DataVotes:
|
||||||
|
return "eth1DataVotes"
|
||||||
|
case Eth1DepositIndex:
|
||||||
|
return "eth1DepositIndex"
|
||||||
|
case Validators:
|
||||||
|
return "validators"
|
||||||
|
case Balances:
|
||||||
|
return "balances"
|
||||||
|
case RandaoMixes:
|
||||||
|
return "randaoMixes"
|
||||||
|
case Slashings:
|
||||||
|
return "slashings"
|
||||||
|
case PreviousEpochAttestations:
|
||||||
|
return "previousEpochAttestations"
|
||||||
|
case CurrentEpochAttestations:
|
||||||
|
return "currentEpochAttestations"
|
||||||
|
case PreviousEpochParticipationBits:
|
||||||
|
return "previousEpochParticipationBits"
|
||||||
|
case CurrentEpochParticipationBits:
|
||||||
|
return "currentEpochParticipationBits"
|
||||||
|
case JustificationBits:
|
||||||
|
return "justificationBits"
|
||||||
|
case PreviousJustifiedCheckpoint:
|
||||||
|
return "previousJustifiedCheckpoint"
|
||||||
|
case CurrentJustifiedCheckpoint:
|
||||||
|
return "currentJustifiedCheckpoint"
|
||||||
|
case FinalizedCheckpoint:
|
||||||
|
return "finalizedCheckpoint"
|
||||||
|
case InactivityScores:
|
||||||
|
return "inactivityScores"
|
||||||
|
case CurrentSyncCommittee:
|
||||||
|
return "currentSyncCommittee"
|
||||||
|
case NextSyncCommittee:
|
||||||
|
return "nextSyncCommittee"
|
||||||
|
case LatestExecutionPayloadHeader:
|
||||||
|
return "latestExecutionPayloadHeader"
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RealPosition denotes the position of the field in the beacon state.
|
||||||
|
// The value might differ for different state versions.
|
||||||
|
func (f FieldIndex) RealPosition() int {
|
||||||
|
switch f {
|
||||||
|
case GenesisTime:
|
||||||
|
return 0
|
||||||
|
case GenesisValidatorsRoot:
|
||||||
|
return 1
|
||||||
|
case Slot:
|
||||||
|
return 2
|
||||||
|
case Fork:
|
||||||
|
return 3
|
||||||
|
case LatestBlockHeader:
|
||||||
|
return 4
|
||||||
|
case BlockRoots:
|
||||||
|
return 5
|
||||||
|
case StateRoots:
|
||||||
|
return 6
|
||||||
|
case HistoricalRoots:
|
||||||
|
return 7
|
||||||
|
case Eth1Data:
|
||||||
|
return 8
|
||||||
|
case Eth1DataVotes:
|
||||||
|
return 9
|
||||||
|
case Eth1DepositIndex:
|
||||||
|
return 10
|
||||||
|
case Validators:
|
||||||
|
return 11
|
||||||
|
case Balances:
|
||||||
|
return 12
|
||||||
|
case RandaoMixes:
|
||||||
|
return 13
|
||||||
|
case Slashings:
|
||||||
|
return 14
|
||||||
|
case PreviousEpochAttestations, PreviousEpochParticipationBits:
|
||||||
|
return 15
|
||||||
|
case CurrentEpochAttestations, CurrentEpochParticipationBits:
|
||||||
|
return 16
|
||||||
|
case JustificationBits:
|
||||||
|
return 17
|
||||||
|
case PreviousJustifiedCheckpoint:
|
||||||
|
return 18
|
||||||
|
case CurrentJustifiedCheckpoint:
|
||||||
|
return 19
|
||||||
|
case FinalizedCheckpoint:
|
||||||
|
return 20
|
||||||
|
case InactivityScores:
|
||||||
|
return 21
|
||||||
|
case CurrentSyncCommittee:
|
||||||
|
return 22
|
||||||
|
case NextSyncCommittee:
|
||||||
|
return 23
|
||||||
|
case LatestExecutionPayloadHeader:
|
||||||
|
return 24
|
||||||
|
default:
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ElemsInChunk returns the number of elements in the chunk (number of
|
||||||
|
// elements that are able to be packed).
|
||||||
|
func (f FieldIndex) ElemsInChunk() (uint64, error) {
|
||||||
|
switch f {
|
||||||
|
case Balances:
|
||||||
|
return 4, nil
|
||||||
|
default:
|
||||||
|
return 0, errors.Errorf("field %d doesn't support element compression", f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (FieldIndex) Native() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Below we define a set of useful enum values for the field
|
||||||
|
// indices of the beacon state. For example, genesisTime is the
|
||||||
|
// 0th field of the beacon state. This is helpful when we are
|
||||||
|
// updating the Merkle branches up the trie representation
|
||||||
|
// of the beacon state. The below field indexes correspond
|
||||||
|
// to the state.
|
||||||
|
const (
|
||||||
|
GenesisTime FieldIndex = iota
|
||||||
|
GenesisValidatorsRoot
|
||||||
|
Slot
|
||||||
|
Fork
|
||||||
|
LatestBlockHeader
|
||||||
|
BlockRoots
|
||||||
|
StateRoots
|
||||||
|
HistoricalRoots
|
||||||
|
Eth1Data
|
||||||
|
Eth1DataVotes
|
||||||
|
Eth1DepositIndex
|
||||||
|
Validators
|
||||||
|
Balances
|
||||||
|
RandaoMixes
|
||||||
|
Slashings
|
||||||
|
PreviousEpochAttestations
|
||||||
|
CurrentEpochAttestations
|
||||||
|
PreviousEpochParticipationBits
|
||||||
|
CurrentEpochParticipationBits
|
||||||
|
JustificationBits
|
||||||
|
PreviousJustifiedCheckpoint
|
||||||
|
CurrentJustifiedCheckpoint
|
||||||
|
FinalizedCheckpoint
|
||||||
|
InactivityScores
|
||||||
|
CurrentSyncCommittee
|
||||||
|
NextSyncCommittee
|
||||||
|
LatestExecutionPayloadHeader
|
||||||
|
)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package v1_test
|
package state_native_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/v1"
|
statenative "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native"
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||||
@@ -20,14 +20,9 @@ import (
|
|||||||
|
|
||||||
func TestBeaconState_ProtoBeaconStateCompatibility(t *testing.T) {
|
func TestBeaconState_ProtoBeaconStateCompatibility(t *testing.T) {
|
||||||
params.SetupTestConfigCleanup(t)
|
params.SetupTestConfigCleanup(t)
|
||||||
cfg := params.MinimalSpecConfig()
|
|
||||||
cfg.SlotsPerHistoricalRoot = fieldparams.BlockRootsLength
|
|
||||||
cfg.EpochsPerHistoricalVector = fieldparams.RandaoMixesLength
|
|
||||||
params.OverrideBeaconConfig(cfg)
|
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
genesis := setupGenesisState(t, 64)
|
genesis := setupGenesisState(t, 64)
|
||||||
customState, err := v1.InitializeFromProto(genesis)
|
customState, err := statenative.InitializeFromProtoPhase0(genesis)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
cloned, ok := proto.Clone(genesis).(*ethpb.BeaconState)
|
cloned, ok := proto.Clone(genesis).(*ethpb.BeaconState)
|
||||||
assert.Equal(t, true, ok, "Object is not of type *ethpb.BeaconState")
|
assert.Equal(t, true, ok, "Object is not of type *ethpb.BeaconState")
|
||||||
@@ -36,7 +31,7 @@ func TestBeaconState_ProtoBeaconStateCompatibility(t *testing.T) {
|
|||||||
|
|
||||||
r1, err := customState.HashTreeRoot(ctx)
|
r1, err := customState.HashTreeRoot(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
beaconState, err := v1.InitializeFromProto(genesis)
|
beaconState, err := statenative.InitializeFromProtoPhase0(genesis)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
r2, err := beaconState.HashTreeRoot(context.Background())
|
r2, err := beaconState.HashTreeRoot(context.Background())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -49,7 +44,7 @@ func TestBeaconState_ProtoBeaconStateCompatibility(t *testing.T) {
|
|||||||
r1, err = customState.HashTreeRoot(ctx)
|
r1, err = customState.HashTreeRoot(ctx)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
genesis.Balances = balances
|
genesis.Balances = balances
|
||||||
beaconState, err = v1.InitializeFromProto(genesis)
|
beaconState, err = statenative.InitializeFromProtoPhase0(genesis)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
r2, err = beaconState.HashTreeRoot(context.Background())
|
r2, err = beaconState.HashTreeRoot(context.Background())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -142,7 +137,7 @@ func BenchmarkStateClone_Manual(b *testing.B) {
|
|||||||
params.SetupTestConfigCleanup(b)
|
params.SetupTestConfigCleanup(b)
|
||||||
params.OverrideBeaconConfig(params.MinimalSpecConfig())
|
params.OverrideBeaconConfig(params.MinimalSpecConfig())
|
||||||
genesis := setupGenesisState(b, 64)
|
genesis := setupGenesisState(b, 64)
|
||||||
st, err := v1.InitializeFromProto(genesis)
|
st, err := statenative.InitializeFromProtoPhase0(genesis)
|
||||||
require.NoError(b, err)
|
require.NoError(b, err)
|
||||||
b.StartTimer()
|
b.StartTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
@@ -184,7 +179,7 @@ func TestBeaconState_ImmutabilityWithSharedResources(t *testing.T) {
|
|||||||
params.SetupTestConfigCleanup(t)
|
params.SetupTestConfigCleanup(t)
|
||||||
params.OverrideBeaconConfig(params.MinimalSpecConfig())
|
params.OverrideBeaconConfig(params.MinimalSpecConfig())
|
||||||
genesis := setupGenesisState(t, 64)
|
genesis := setupGenesisState(t, 64)
|
||||||
a, err := v1.InitializeFromProto(genesis)
|
a, err := statenative.InitializeFromProtoPhase0(genesis)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
b := a.Copy()
|
b := a.Copy()
|
||||||
|
|
||||||
@@ -221,7 +216,7 @@ func TestForkManualCopy_OK(t *testing.T) {
|
|||||||
params.SetupTestConfigCleanup(t)
|
params.SetupTestConfigCleanup(t)
|
||||||
params.OverrideBeaconConfig(params.MinimalSpecConfig())
|
params.OverrideBeaconConfig(params.MinimalSpecConfig())
|
||||||
genesis := setupGenesisState(t, 64)
|
genesis := setupGenesisState(t, 64)
|
||||||
a, err := v1.InitializeFromProto(genesis)
|
a, err := statenative.InitializeFromProtoPhase0(genesis)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
wantedFork := ðpb.Fork{
|
wantedFork := ðpb.Fork{
|
||||||
PreviousVersion: []byte{'a', 'b', 'c'},
|
PreviousVersion: []byte{'a', 'b', 'c'},
|
||||||
@@ -230,7 +225,7 @@ func TestForkManualCopy_OK(t *testing.T) {
|
|||||||
}
|
}
|
||||||
require.NoError(t, a.SetFork(wantedFork))
|
require.NoError(t, a.SetFork(wantedFork))
|
||||||
|
|
||||||
pbState, err := v1.ProtobufBeaconState(a.InnerStateUnsafe())
|
pbState, err := statenative.ProtobufBeaconStatePhase0(a.InnerStateUnsafe())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.DeepEqual(t, pbState.Fork, wantedFork)
|
require.DeepEqual(t, pbState.Fork, wantedFork)
|
||||||
}
|
}
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
//go:build !minimal
|
|
||||||
// +build !minimal
|
|
||||||
|
|
||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/prysmaticlabs/go-bitfield"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/fieldtrie"
|
|
||||||
customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/types"
|
|
||||||
eth2types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// BeaconState defines a struct containing utilities for the Ethereum Beacon Chain state, defining
|
|
||||||
// getters and setters for its respective values and helpful functions such as HashTreeRoot().
|
|
||||||
type BeaconState struct {
|
|
||||||
genesisTime uint64 `ssz-gen:"true"`
|
|
||||||
genesisValidatorsRoot customtypes.Byte32 `ssz-gen:"true" ssz-size:"32"`
|
|
||||||
slot eth2types.Slot `ssz-gen:"true"`
|
|
||||||
fork *ethpb.Fork `ssz-gen:"true"`
|
|
||||||
latestBlockHeader *ethpb.BeaconBlockHeader `ssz-gen:"true"`
|
|
||||||
blockRoots *customtypes.BlockRoots `ssz-gen:"true" ssz-size:"8192,32"`
|
|
||||||
stateRoots *customtypes.StateRoots `ssz-gen:"true" ssz-size:"8192,32"`
|
|
||||||
historicalRoots customtypes.HistoricalRoots `ssz-gen:"true" ssz-size:"?,32" ssz-max:"16777216"`
|
|
||||||
eth1Data *ethpb.Eth1Data `ssz-gen:"true"`
|
|
||||||
eth1DataVotes []*ethpb.Eth1Data `ssz-gen:"true" ssz-max:"2048"`
|
|
||||||
eth1DepositIndex uint64 `ssz-gen:"true"`
|
|
||||||
validators []*ethpb.Validator `ssz-gen:"true" ssz-max:"1099511627776"`
|
|
||||||
balances []uint64 `ssz-gen:"true" ssz-max:"1099511627776"`
|
|
||||||
randaoMixes *customtypes.RandaoMixes `ssz-gen:"true" ssz-size:"65536,32"`
|
|
||||||
slashings []uint64 `ssz-gen:"true" ssz-size:"8192"`
|
|
||||||
previousEpochAttestations []*ethpb.PendingAttestation `ssz-gen:"true" ssz-max:"4096"`
|
|
||||||
currentEpochAttestations []*ethpb.PendingAttestation `ssz-gen:"true" ssz-max:"4096"`
|
|
||||||
justificationBits bitfield.Bitvector4 `ssz-gen:"true" ssz-size:"1"`
|
|
||||||
previousJustifiedCheckpoint *ethpb.Checkpoint `ssz-gen:"true"`
|
|
||||||
currentJustifiedCheckpoint *ethpb.Checkpoint `ssz-gen:"true"`
|
|
||||||
finalizedCheckpoint *ethpb.Checkpoint `ssz-gen:"true"`
|
|
||||||
|
|
||||||
lock sync.RWMutex
|
|
||||||
dirtyFields map[types.FieldIndex]bool
|
|
||||||
dirtyIndices map[types.FieldIndex][]uint64
|
|
||||||
stateFieldLeaves map[types.FieldIndex]*fieldtrie.FieldTrie
|
|
||||||
rebuildTrie map[types.FieldIndex]bool
|
|
||||||
valMapHandler *stateutil.ValidatorMapHandler
|
|
||||||
merkleLayers [][][]byte
|
|
||||||
sharedFieldReferences map[types.FieldIndex]*stateutil.Reference
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
//go:build minimal
|
|
||||||
// +build minimal
|
|
||||||
|
|
||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/prysmaticlabs/go-bitfield"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/fieldtrie"
|
|
||||||
customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/types"
|
|
||||||
eth2types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// BeaconState defines a struct containing utilities for the Ethereum Beacon Chain state, defining
|
|
||||||
// getters and setters for its respective values and helpful functions such as HashTreeRoot().
|
|
||||||
type BeaconState struct {
|
|
||||||
genesisTime uint64 `ssz-gen:"true"`
|
|
||||||
genesisValidatorsRoot customtypes.Byte32 `ssz-gen:"true" ssz-size:"32"`
|
|
||||||
slot eth2types.Slot `ssz-gen:"true"`
|
|
||||||
fork *ethpb.Fork `ssz-gen:"true"`
|
|
||||||
latestBlockHeader *ethpb.BeaconBlockHeader `ssz-gen:"true"`
|
|
||||||
blockRoots *customtypes.BlockRoots `ssz-gen:"true" ssz-size:"64,32"`
|
|
||||||
stateRoots *customtypes.StateRoots `ssz-gen:"true" ssz-size:"64,32"`
|
|
||||||
historicalRoots customtypes.HistoricalRoots `ssz-gen:"true" ssz-size:"?,32" ssz-max:"16777216"`
|
|
||||||
eth1Data *ethpb.Eth1Data `ssz-gen:"true"`
|
|
||||||
eth1DataVotes []*ethpb.Eth1Data `ssz-gen:"true" ssz-max:"32"`
|
|
||||||
eth1DepositIndex uint64 `ssz-gen:"true"`
|
|
||||||
validators []*ethpb.Validator `ssz-gen:"true" ssz-max:"1099511627776"`
|
|
||||||
balances []uint64 `ssz-gen:"true" ssz-max:"1099511627776"`
|
|
||||||
randaoMixes *customtypes.RandaoMixes `ssz-gen:"true" ssz-size:"64,32"`
|
|
||||||
slashings []uint64 `ssz-gen:"true" ssz-size:"64"`
|
|
||||||
previousEpochAttestations []*ethpb.PendingAttestation `ssz-gen:"true" ssz-max:"1024"`
|
|
||||||
currentEpochAttestations []*ethpb.PendingAttestation `ssz-gen:"true" ssz-max:"1024"`
|
|
||||||
justificationBits bitfield.Bitvector4 `ssz-gen:"true" ssz-size:"1"`
|
|
||||||
previousJustifiedCheckpoint *ethpb.Checkpoint `ssz-gen:"true"`
|
|
||||||
currentJustifiedCheckpoint *ethpb.Checkpoint `ssz-gen:"true"`
|
|
||||||
finalizedCheckpoint *ethpb.Checkpoint `ssz-gen:"true"`
|
|
||||||
|
|
||||||
lock sync.RWMutex
|
|
||||||
dirtyFields map[types.FieldIndex]bool
|
|
||||||
dirtyIndices map[types.FieldIndex][]uint64
|
|
||||||
stateFieldLeaves map[types.FieldIndex]*fieldtrie.FieldTrie
|
|
||||||
rebuildTrie map[types.FieldIndex]bool
|
|
||||||
valMapHandler *stateutil.ValidatorMapHandler
|
|
||||||
merkleLayers [][][]byte
|
|
||||||
sharedFieldReferences map[types.FieldIndex]*stateutil.Reference
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// computeFieldRoots returns the hash tree root computations of every field in
|
|
||||||
// the beacon state as a list of 32 byte roots.
|
|
||||||
func computeFieldRoots(ctx context.Context, state *ethpb.BeaconState) ([][]byte, error) {
|
|
||||||
return stateutil.ComputeFieldRootsWithHasherPhase0(ctx, state)
|
|
||||||
}
|
|
||||||
@@ -1,493 +0,0 @@
|
|||||||
// Code generated by fastssz. DO NOT EDIT.
|
|
||||||
// Hash: fcd8a2db8c7071e198d2acf714243a3f8875b92cdc1a3a085134db7c47f01ce6
|
|
||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
ssz "github.com/ferranbt/fastssz"
|
|
||||||
eth2types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MarshalSSZ ssz marshals the BeaconState object
|
|
||||||
func (b *BeaconState) MarshalSSZ() ([]byte, error) {
|
|
||||||
return ssz.MarshalSSZ(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalSSZTo ssz marshals the BeaconState object to a target array
|
|
||||||
func (b *BeaconState) MarshalSSZTo(buf []byte) (dst []byte, err error) {
|
|
||||||
dst = buf
|
|
||||||
offset := int(2687377)
|
|
||||||
|
|
||||||
// Field (0) 'genesisTime'
|
|
||||||
dst = ssz.MarshalUint64(dst, b.genesisTime)
|
|
||||||
|
|
||||||
// Field (1) 'genesisValidatorsRoot'
|
|
||||||
dst = append(dst, b.genesisValidatorsRoot[:]...)
|
|
||||||
|
|
||||||
// Field (2) 'slot'
|
|
||||||
dst = ssz.MarshalUint64(dst, uint64(b.slot))
|
|
||||||
|
|
||||||
// Field (3) 'fork'
|
|
||||||
if b.fork == nil {
|
|
||||||
b.fork = new(ethpb.Fork)
|
|
||||||
}
|
|
||||||
if dst, err = b.fork.MarshalSSZTo(dst); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (4) 'latestBlockHeader'
|
|
||||||
if b.latestBlockHeader == nil {
|
|
||||||
b.latestBlockHeader = new(ethpb.BeaconBlockHeader)
|
|
||||||
}
|
|
||||||
if dst, err = b.latestBlockHeader.MarshalSSZTo(dst); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (5) 'blockRoots'
|
|
||||||
for ii := 0; ii < 8192; ii++ {
|
|
||||||
dst = append(dst, b.blockRoots[ii][:]...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (6) 'stateRoots'
|
|
||||||
for ii := 0; ii < 8192; ii++ {
|
|
||||||
dst = append(dst, b.stateRoots[ii][:]...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset (7) 'historicalRoots'
|
|
||||||
dst = ssz.WriteOffset(dst, offset)
|
|
||||||
offset += len(b.historicalRoots) * 32
|
|
||||||
|
|
||||||
// Field (8) 'eth1Data'
|
|
||||||
if b.eth1Data == nil {
|
|
||||||
b.eth1Data = new(ethpb.Eth1Data)
|
|
||||||
}
|
|
||||||
if dst, err = b.eth1Data.MarshalSSZTo(dst); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset (9) 'eth1DataVotes'
|
|
||||||
dst = ssz.WriteOffset(dst, offset)
|
|
||||||
offset += len(b.eth1DataVotes) * 72
|
|
||||||
|
|
||||||
// Field (10) 'eth1DepositIndex'
|
|
||||||
dst = ssz.MarshalUint64(dst, b.eth1DepositIndex)
|
|
||||||
|
|
||||||
// Offset (11) 'validators'
|
|
||||||
dst = ssz.WriteOffset(dst, offset)
|
|
||||||
offset += len(b.validators) * 121
|
|
||||||
|
|
||||||
// Offset (12) 'balances'
|
|
||||||
dst = ssz.WriteOffset(dst, offset)
|
|
||||||
offset += len(b.balances) * 8
|
|
||||||
|
|
||||||
// Field (13) 'randaoMixes'
|
|
||||||
for ii := 0; ii < 65536; ii++ {
|
|
||||||
dst = append(dst, b.randaoMixes[ii][:]...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (14) 'slashings'
|
|
||||||
if len(b.slashings) != 8192 {
|
|
||||||
err = ssz.ErrVectorLength
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for ii := 0; ii < 8192; ii++ {
|
|
||||||
dst = ssz.MarshalUint64(dst, b.slashings[ii])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset (15) 'previousEpochAttestations'
|
|
||||||
dst = ssz.WriteOffset(dst, offset)
|
|
||||||
for ii := 0; ii < len(b.previousEpochAttestations); ii++ {
|
|
||||||
offset += 4
|
|
||||||
offset += b.previousEpochAttestations[ii].SizeSSZ()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset (16) 'currentEpochAttestations'
|
|
||||||
dst = ssz.WriteOffset(dst, offset)
|
|
||||||
for ii := 0; ii < len(b.currentEpochAttestations); ii++ {
|
|
||||||
offset += 4
|
|
||||||
offset += b.currentEpochAttestations[ii].SizeSSZ()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (17) 'justificationBits'
|
|
||||||
if len(b.justificationBits) != 1 {
|
|
||||||
err = ssz.ErrBytesLength
|
|
||||||
return
|
|
||||||
}
|
|
||||||
dst = append(dst, b.justificationBits...)
|
|
||||||
|
|
||||||
// Field (18) 'previousJustifiedCheckpoint'
|
|
||||||
if b.previousJustifiedCheckpoint == nil {
|
|
||||||
b.previousJustifiedCheckpoint = new(ethpb.Checkpoint)
|
|
||||||
}
|
|
||||||
if dst, err = b.previousJustifiedCheckpoint.MarshalSSZTo(dst); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (19) 'currentJustifiedCheckpoint'
|
|
||||||
if b.currentJustifiedCheckpoint == nil {
|
|
||||||
b.currentJustifiedCheckpoint = new(ethpb.Checkpoint)
|
|
||||||
}
|
|
||||||
if dst, err = b.currentJustifiedCheckpoint.MarshalSSZTo(dst); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (20) 'finalizedCheckpoint'
|
|
||||||
if b.finalizedCheckpoint == nil {
|
|
||||||
b.finalizedCheckpoint = new(ethpb.Checkpoint)
|
|
||||||
}
|
|
||||||
if dst, err = b.finalizedCheckpoint.MarshalSSZTo(dst); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (7) 'historicalRoots'
|
|
||||||
if len(b.historicalRoots) > 16777216 {
|
|
||||||
err = ssz.ErrListTooBig
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for ii := 0; ii < len(b.historicalRoots); ii++ {
|
|
||||||
dst = append(dst, b.historicalRoots[ii][:]...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (9) 'eth1DataVotes'
|
|
||||||
if len(b.eth1DataVotes) > 2048 {
|
|
||||||
err = ssz.ErrListTooBig
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for ii := 0; ii < len(b.eth1DataVotes); ii++ {
|
|
||||||
if dst, err = b.eth1DataVotes[ii].MarshalSSZTo(dst); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (11) 'validators'
|
|
||||||
if len(b.validators) > 1099511627776 {
|
|
||||||
err = ssz.ErrListTooBig
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for ii := 0; ii < len(b.validators); ii++ {
|
|
||||||
if dst, err = b.validators[ii].MarshalSSZTo(dst); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (12) 'balances'
|
|
||||||
if len(b.balances) > 1099511627776 {
|
|
||||||
err = ssz.ErrListTooBig
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for ii := 0; ii < len(b.balances); ii++ {
|
|
||||||
dst = ssz.MarshalUint64(dst, b.balances[ii])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (15) 'previousEpochAttestations'
|
|
||||||
if len(b.previousEpochAttestations) > 4096 {
|
|
||||||
err = ssz.ErrListTooBig
|
|
||||||
return
|
|
||||||
}
|
|
||||||
{
|
|
||||||
offset = 4 * len(b.previousEpochAttestations)
|
|
||||||
for ii := 0; ii < len(b.previousEpochAttestations); ii++ {
|
|
||||||
dst = ssz.WriteOffset(dst, offset)
|
|
||||||
offset += b.previousEpochAttestations[ii].SizeSSZ()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for ii := 0; ii < len(b.previousEpochAttestations); ii++ {
|
|
||||||
if dst, err = b.previousEpochAttestations[ii].MarshalSSZTo(dst); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (16) 'currentEpochAttestations'
|
|
||||||
if len(b.currentEpochAttestations) > 4096 {
|
|
||||||
err = ssz.ErrListTooBig
|
|
||||||
return
|
|
||||||
}
|
|
||||||
{
|
|
||||||
offset = 4 * len(b.currentEpochAttestations)
|
|
||||||
for ii := 0; ii < len(b.currentEpochAttestations); ii++ {
|
|
||||||
dst = ssz.WriteOffset(dst, offset)
|
|
||||||
offset += b.currentEpochAttestations[ii].SizeSSZ()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for ii := 0; ii < len(b.currentEpochAttestations); ii++ {
|
|
||||||
if dst, err = b.currentEpochAttestations[ii].MarshalSSZTo(dst); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalSSZ ssz unmarshals the BeaconState object
|
|
||||||
func (b *BeaconState) UnmarshalSSZ(buf []byte) error {
|
|
||||||
var err error
|
|
||||||
size := uint64(len(buf))
|
|
||||||
if size < 2687377 {
|
|
||||||
return ssz.ErrSize
|
|
||||||
}
|
|
||||||
|
|
||||||
tail := buf
|
|
||||||
var o7, o9, o11, o12, o15, o16 uint64
|
|
||||||
|
|
||||||
// Field (0) 'genesisTime'
|
|
||||||
b.genesisTime = ssz.UnmarshallUint64(buf[0:8])
|
|
||||||
|
|
||||||
// Field (1) 'genesisValidatorsRoot'
|
|
||||||
copy(b.genesisValidatorsRoot[:], buf[8:40])
|
|
||||||
|
|
||||||
// Field (2) 'slot'
|
|
||||||
b.slot = eth2types.Slot(ssz.UnmarshallUint64(buf[40:48]))
|
|
||||||
|
|
||||||
// Field (3) 'fork'
|
|
||||||
if b.fork == nil {
|
|
||||||
b.fork = new(ethpb.Fork)
|
|
||||||
}
|
|
||||||
if err = b.fork.UnmarshalSSZ(buf[48:64]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (4) 'latestBlockHeader'
|
|
||||||
if b.latestBlockHeader == nil {
|
|
||||||
b.latestBlockHeader = new(ethpb.BeaconBlockHeader)
|
|
||||||
}
|
|
||||||
if err = b.latestBlockHeader.UnmarshalSSZ(buf[64:176]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (5) 'blockRoots'
|
|
||||||
|
|
||||||
for ii := 0; ii < 8192; ii++ {
|
|
||||||
copy(b.blockRoots[ii][:], buf[176:262320][ii*32:(ii+1)*32])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (6) 'stateRoots'
|
|
||||||
|
|
||||||
for ii := 0; ii < 8192; ii++ {
|
|
||||||
copy(b.stateRoots[ii][:], buf[262320:524464][ii*32:(ii+1)*32])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset (7) 'historicalRoots'
|
|
||||||
if o7 = ssz.ReadOffset(buf[524464:524468]); o7 > size {
|
|
||||||
return ssz.ErrOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
if o7 < 2687377 {
|
|
||||||
return ssz.ErrInvalidVariableOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (8) 'eth1Data'
|
|
||||||
if b.eth1Data == nil {
|
|
||||||
b.eth1Data = new(ethpb.Eth1Data)
|
|
||||||
}
|
|
||||||
if err = b.eth1Data.UnmarshalSSZ(buf[524468:524540]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset (9) 'eth1DataVotes'
|
|
||||||
if o9 = ssz.ReadOffset(buf[524540:524544]); o9 > size || o7 > o9 {
|
|
||||||
return ssz.ErrOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (10) 'eth1DepositIndex'
|
|
||||||
b.eth1DepositIndex = ssz.UnmarshallUint64(buf[524544:524552])
|
|
||||||
|
|
||||||
// Offset (11) 'validators'
|
|
||||||
if o11 = ssz.ReadOffset(buf[524552:524556]); o11 > size || o9 > o11 {
|
|
||||||
return ssz.ErrOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset (12) 'balances'
|
|
||||||
if o12 = ssz.ReadOffset(buf[524556:524560]); o12 > size || o11 > o12 {
|
|
||||||
return ssz.ErrOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (13) 'randaoMixes'
|
|
||||||
|
|
||||||
for ii := 0; ii < 65536; ii++ {
|
|
||||||
copy(b.randaoMixes[ii][:], buf[524560:2621712][ii*32:(ii+1)*32])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (14) 'slashings'
|
|
||||||
b.slashings = ssz.ExtendUint64(b.slashings, 8192)
|
|
||||||
for ii := 0; ii < 8192; ii++ {
|
|
||||||
b.slashings[ii] = ssz.UnmarshallUint64(buf[2621712:2687248][ii*8 : (ii+1)*8])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset (15) 'previousEpochAttestations'
|
|
||||||
if o15 = ssz.ReadOffset(buf[2687248:2687252]); o15 > size || o12 > o15 {
|
|
||||||
return ssz.ErrOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset (16) 'currentEpochAttestations'
|
|
||||||
if o16 = ssz.ReadOffset(buf[2687252:2687256]); o16 > size || o15 > o16 {
|
|
||||||
return ssz.ErrOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (17) 'justificationBits'
|
|
||||||
if cap(b.justificationBits) == 0 {
|
|
||||||
b.justificationBits = make([]byte, 0, len(buf[2687256:2687257]))
|
|
||||||
}
|
|
||||||
b.justificationBits = append(b.justificationBits, buf[2687256:2687257]...)
|
|
||||||
|
|
||||||
// Field (18) 'previousJustifiedCheckpoint'
|
|
||||||
if b.previousJustifiedCheckpoint == nil {
|
|
||||||
b.previousJustifiedCheckpoint = new(ethpb.Checkpoint)
|
|
||||||
}
|
|
||||||
if err = b.previousJustifiedCheckpoint.UnmarshalSSZ(buf[2687257:2687297]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (19) 'currentJustifiedCheckpoint'
|
|
||||||
if b.currentJustifiedCheckpoint == nil {
|
|
||||||
b.currentJustifiedCheckpoint = new(ethpb.Checkpoint)
|
|
||||||
}
|
|
||||||
if err = b.currentJustifiedCheckpoint.UnmarshalSSZ(buf[2687297:2687337]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (20) 'finalizedCheckpoint'
|
|
||||||
if b.finalizedCheckpoint == nil {
|
|
||||||
b.finalizedCheckpoint = new(ethpb.Checkpoint)
|
|
||||||
}
|
|
||||||
if err = b.finalizedCheckpoint.UnmarshalSSZ(buf[2687337:2687377]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (7) 'historicalRoots'
|
|
||||||
{
|
|
||||||
buf = tail[o7:o9]
|
|
||||||
num, err := ssz.DivideInt2(len(buf), 32, 16777216)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
b.historicalRoots = make([][32]byte, num)
|
|
||||||
for ii := 0; ii < num; ii++ {
|
|
||||||
copy(b.historicalRoots[ii][:], buf[ii*32:(ii+1)*32])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (9) 'eth1DataVotes'
|
|
||||||
{
|
|
||||||
buf = tail[o9:o11]
|
|
||||||
num, err := ssz.DivideInt2(len(buf), 72, 2048)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
b.eth1DataVotes = make([]*ethpb.Eth1Data, num)
|
|
||||||
for ii := 0; ii < num; ii++ {
|
|
||||||
if b.eth1DataVotes[ii] == nil {
|
|
||||||
b.eth1DataVotes[ii] = new(ethpb.Eth1Data)
|
|
||||||
}
|
|
||||||
if err = b.eth1DataVotes[ii].UnmarshalSSZ(buf[ii*72 : (ii+1)*72]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (11) 'validators'
|
|
||||||
{
|
|
||||||
buf = tail[o11:o12]
|
|
||||||
num, err := ssz.DivideInt2(len(buf), 121, 1099511627776)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
b.validators = make([]*ethpb.Validator, num)
|
|
||||||
for ii := 0; ii < num; ii++ {
|
|
||||||
if b.validators[ii] == nil {
|
|
||||||
b.validators[ii] = new(ethpb.Validator)
|
|
||||||
}
|
|
||||||
if err = b.validators[ii].UnmarshalSSZ(buf[ii*121 : (ii+1)*121]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (12) 'balances'
|
|
||||||
{
|
|
||||||
buf = tail[o12:o15]
|
|
||||||
num, err := ssz.DivideInt2(len(buf), 8, 1099511627776)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
b.balances = ssz.ExtendUint64(b.balances, num)
|
|
||||||
for ii := 0; ii < num; ii++ {
|
|
||||||
b.balances[ii] = ssz.UnmarshallUint64(buf[ii*8 : (ii+1)*8])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (15) 'previousEpochAttestations'
|
|
||||||
{
|
|
||||||
buf = tail[o15:o16]
|
|
||||||
num, err := ssz.DecodeDynamicLength(buf, 4096)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
b.previousEpochAttestations = make([]*ethpb.PendingAttestation, num)
|
|
||||||
err = ssz.UnmarshalDynamic(buf, num, func(indx int, buf []byte) (err error) {
|
|
||||||
if b.previousEpochAttestations[indx] == nil {
|
|
||||||
b.previousEpochAttestations[indx] = new(ethpb.PendingAttestation)
|
|
||||||
}
|
|
||||||
if err = b.previousEpochAttestations[indx].UnmarshalSSZ(buf); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (16) 'currentEpochAttestations'
|
|
||||||
{
|
|
||||||
buf = tail[o16:]
|
|
||||||
num, err := ssz.DecodeDynamicLength(buf, 4096)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
b.currentEpochAttestations = make([]*ethpb.PendingAttestation, num)
|
|
||||||
err = ssz.UnmarshalDynamic(buf, num, func(indx int, buf []byte) (err error) {
|
|
||||||
if b.currentEpochAttestations[indx] == nil {
|
|
||||||
b.currentEpochAttestations[indx] = new(ethpb.PendingAttestation)
|
|
||||||
}
|
|
||||||
if err = b.currentEpochAttestations[indx].UnmarshalSSZ(buf); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// SizeSSZ returns the ssz encoded size in bytes for the BeaconState object
|
|
||||||
func (b *BeaconState) SizeSSZ() (size int) {
|
|
||||||
size = 2687377
|
|
||||||
|
|
||||||
// Field (7) 'historicalRoots'
|
|
||||||
size += len(b.historicalRoots) * 32
|
|
||||||
|
|
||||||
// Field (9) 'eth1DataVotes'
|
|
||||||
size += len(b.eth1DataVotes) * 72
|
|
||||||
|
|
||||||
// Field (11) 'validators'
|
|
||||||
size += len(b.validators) * 121
|
|
||||||
|
|
||||||
// Field (12) 'balances'
|
|
||||||
size += len(b.balances) * 8
|
|
||||||
|
|
||||||
// Field (15) 'previousEpochAttestations'
|
|
||||||
for ii := 0; ii < len(b.previousEpochAttestations); ii++ {
|
|
||||||
size += 4
|
|
||||||
size += b.previousEpochAttestations[ii].SizeSSZ()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (16) 'currentEpochAttestations'
|
|
||||||
for ii := 0; ii < len(b.currentEpochAttestations); ii++ {
|
|
||||||
size += 4
|
|
||||||
size += b.currentEpochAttestations[ii].SizeSSZ()
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
|
||||||
testtmpl "github.com/prysmaticlabs/prysm/beacon-chain/state/testing"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestBeaconState_LatestBlockHeader(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateLatestBlockHeader(
|
|
||||||
t,
|
|
||||||
func() (state.BeaconState, error) {
|
|
||||||
return InitializeFromProto(ðpb.BeaconState{})
|
|
||||||
},
|
|
||||||
func(BH *ethpb.BeaconBlockHeader) (state.BeaconState, error) {
|
|
||||||
return InitializeFromProto(ðpb.BeaconState{LatestBlockHeader: BH})
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_BlockRoots(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateBlockRootsNative(
|
|
||||||
t,
|
|
||||||
func() (state.BeaconState, error) {
|
|
||||||
return InitializeFromProto(ðpb.BeaconState{})
|
|
||||||
},
|
|
||||||
func(BR [][]byte) (state.BeaconState, error) {
|
|
||||||
return InitializeFromProto(ðpb.BeaconState{BlockRoots: BR})
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_BlockRootAtIndex(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateBlockRootAtIndexNative(
|
|
||||||
t,
|
|
||||||
func() (state.BeaconState, error) {
|
|
||||||
return InitializeFromProto(ðpb.BeaconState{})
|
|
||||||
},
|
|
||||||
func(BR [][]byte) (state.BeaconState, error) {
|
|
||||||
return InitializeFromProto(ðpb.BeaconState{BlockRoots: BR})
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
|
|
||||||
"github.com/prysmaticlabs/go-bitfield"
|
|
||||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// JustificationBits marking which epochs have been justified in the beacon chain.
|
|
||||||
func (b *BeaconState) JustificationBits() bitfield.Bitvector4 {
|
|
||||||
if b.justificationBits == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.justificationBitsVal()
|
|
||||||
}
|
|
||||||
|
|
||||||
// justificationBitsVal marking which epochs have been justified in the beacon chain.
|
|
||||||
// This assumes that a lock is already held on BeaconState.
|
|
||||||
func (b *BeaconState) justificationBitsVal() bitfield.Bitvector4 {
|
|
||||||
if b.justificationBits == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
res := make([]byte, len(b.justificationBits.Bytes()))
|
|
||||||
copy(res, b.justificationBits.Bytes())
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// PreviousJustifiedCheckpoint denoting an epoch and block root.
|
|
||||||
func (b *BeaconState) PreviousJustifiedCheckpoint() *ethpb.Checkpoint {
|
|
||||||
if b.previousJustifiedCheckpoint == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.previousJustifiedCheckpointVal()
|
|
||||||
}
|
|
||||||
|
|
||||||
// previousJustifiedCheckpointVal denoting an epoch and block root.
|
|
||||||
// This assumes that a lock is already held on BeaconState.
|
|
||||||
func (b *BeaconState) previousJustifiedCheckpointVal() *ethpb.Checkpoint {
|
|
||||||
return ethpb.CopyCheckpoint(b.previousJustifiedCheckpoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CurrentJustifiedCheckpoint denoting an epoch and block root.
|
|
||||||
func (b *BeaconState) CurrentJustifiedCheckpoint() *ethpb.Checkpoint {
|
|
||||||
if b.currentJustifiedCheckpoint == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.currentJustifiedCheckpointVal()
|
|
||||||
}
|
|
||||||
|
|
||||||
// currentJustifiedCheckpointVal denoting an epoch and block root.
|
|
||||||
// This assumes that a lock is already held on BeaconState.
|
|
||||||
func (b *BeaconState) currentJustifiedCheckpointVal() *ethpb.Checkpoint {
|
|
||||||
return ethpb.CopyCheckpoint(b.currentJustifiedCheckpoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MatchCurrentJustifiedCheckpoint returns true if input justified checkpoint matches
|
|
||||||
// the current justified checkpoint in state.
|
|
||||||
func (b *BeaconState) MatchCurrentJustifiedCheckpoint(c *ethpb.Checkpoint) bool {
|
|
||||||
if b.currentJustifiedCheckpoint == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.Epoch != b.currentJustifiedCheckpoint.Epoch {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return bytes.Equal(c.Root, b.currentJustifiedCheckpoint.Root)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MatchPreviousJustifiedCheckpoint returns true if the input justified checkpoint matches
|
|
||||||
// the previous justified checkpoint in state.
|
|
||||||
func (b *BeaconState) MatchPreviousJustifiedCheckpoint(c *ethpb.Checkpoint) bool {
|
|
||||||
if b.previousJustifiedCheckpoint == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.Epoch != b.previousJustifiedCheckpoint.Epoch {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return bytes.Equal(c.Root, b.previousJustifiedCheckpoint.Root)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FinalizedCheckpoint denoting an epoch and block root.
|
|
||||||
func (b *BeaconState) FinalizedCheckpoint() *ethpb.Checkpoint {
|
|
||||||
if b.finalizedCheckpoint == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.finalizedCheckpointVal()
|
|
||||||
}
|
|
||||||
|
|
||||||
// finalizedCheckpointVal denoting an epoch and block root.
|
|
||||||
// This assumes that a lock is already held on BeaconState.
|
|
||||||
func (b *BeaconState) finalizedCheckpointVal() *ethpb.Checkpoint {
|
|
||||||
return ethpb.CopyCheckpoint(b.finalizedCheckpoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FinalizedCheckpointEpoch returns the epoch value of the finalized checkpoint.
|
|
||||||
func (b *BeaconState) FinalizedCheckpointEpoch() types.Epoch {
|
|
||||||
if b.finalizedCheckpoint == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.finalizedCheckpoint.Epoch
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/prysmaticlabs/go-bitfield"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
|
||||||
testtmpl "github.com/prysmaticlabs/prysm/beacon-chain/state/testing"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestBeaconState_JustificationBitsNil(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateJustificationBitsNil(
|
|
||||||
t,
|
|
||||||
func() (state.BeaconState, error) {
|
|
||||||
return InitializeFromProtoUnsafe(ðpb.BeaconState{})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_JustificationBits(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateJustificationBits(
|
|
||||||
t,
|
|
||||||
func(bits bitfield.Bitvector4) (state.BeaconState, error) {
|
|
||||||
return InitializeFromProtoUnsafe(ðpb.BeaconState{JustificationBits: bits})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_PreviousJustifiedCheckpointNil(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStatePreviousJustifiedCheckpointNil(
|
|
||||||
t,
|
|
||||||
func() (state.BeaconState, error) {
|
|
||||||
return InitializeFromProtoUnsafe(ðpb.BeaconState{})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_PreviousJustifiedCheckpoint(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStatePreviousJustifiedCheckpoint(
|
|
||||||
t,
|
|
||||||
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
|
||||||
return InitializeFromProtoUnsafe(ðpb.BeaconState{PreviousJustifiedCheckpoint: cp})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_CurrentJustifiedCheckpointNil(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateCurrentJustifiedCheckpointNil(
|
|
||||||
t,
|
|
||||||
func() (state.BeaconState, error) {
|
|
||||||
return InitializeFromProtoUnsafe(ðpb.BeaconState{})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_CurrentJustifiedCheckpoint(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateCurrentJustifiedCheckpoint(
|
|
||||||
t,
|
|
||||||
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
|
||||||
return InitializeFromProtoUnsafe(ðpb.BeaconState{CurrentJustifiedCheckpoint: cp})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_FinalizedCheckpointNil(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateFinalizedCheckpointNil(
|
|
||||||
t,
|
|
||||||
func() (state.BeaconState, error) {
|
|
||||||
return InitializeFromProtoUnsafe(ðpb.BeaconState{})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_FinalizedCheckpoint(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateFinalizedCheckpoint(
|
|
||||||
t,
|
|
||||||
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
|
||||||
return InitializeFromProtoUnsafe(ðpb.BeaconState{FinalizedCheckpoint: cp})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Eth1Data corresponding to the proof-of-work chain information stored in the beacon state.
|
|
||||||
func (b *BeaconState) Eth1Data() *ethpb.Eth1Data {
|
|
||||||
if b.eth1Data == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.eth1DataVal()
|
|
||||||
}
|
|
||||||
|
|
||||||
// eth1DataVal corresponding to the proof-of-work chain information stored in the beacon state.
|
|
||||||
// This assumes that a lock is already held on BeaconState.
|
|
||||||
func (b *BeaconState) eth1DataVal() *ethpb.Eth1Data {
|
|
||||||
if b.eth1Data == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return ethpb.CopyETH1Data(b.eth1Data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Eth1DataVotes corresponds to votes from Ethereum on the canonical proof-of-work chain
|
|
||||||
// data retrieved from eth1.
|
|
||||||
func (b *BeaconState) Eth1DataVotes() []*ethpb.Eth1Data {
|
|
||||||
if b.eth1DataVotes == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.eth1DataVotesVal()
|
|
||||||
}
|
|
||||||
|
|
||||||
// eth1DataVotesVal corresponds to votes from Ethereum on the canonical proof-of-work chain
|
|
||||||
// data retrieved from eth1.
|
|
||||||
// This assumes that a lock is already held on BeaconState.
|
|
||||||
func (b *BeaconState) eth1DataVotesVal() []*ethpb.Eth1Data {
|
|
||||||
if b.eth1DataVotes == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
res := make([]*ethpb.Eth1Data, len(b.eth1DataVotes))
|
|
||||||
for i := 0; i < len(res); i++ {
|
|
||||||
res[i] = ethpb.CopyETH1Data(b.eth1DataVotes[i])
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// Eth1DepositIndex corresponds to the index of the deposit made to the
|
|
||||||
// validator deposit contract at the time of this state's eth1 data.
|
|
||||||
func (b *BeaconState) Eth1DepositIndex() uint64 {
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.eth1DepositIndex
|
|
||||||
}
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GenesisTime of the beacon state as a uint64.
|
|
||||||
func (b *BeaconState) GenesisTime() uint64 {
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.genesisTime
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenesisValidatorsRoot of the beacon state.
|
|
||||||
func (b *BeaconState) GenesisValidatorsRoot() []byte {
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.genesisValidatorsRoot[:]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Version of the beacon state. This method
|
|
||||||
// is strictly meant to be used without a lock
|
|
||||||
// internally.
|
|
||||||
func (_ *BeaconState) Version() int {
|
|
||||||
return version.Phase0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Slot of the current beacon chain state.
|
|
||||||
func (b *BeaconState) Slot() types.Slot {
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.slot
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fork version of the beacon chain.
|
|
||||||
func (b *BeaconState) Fork() *ethpb.Fork {
|
|
||||||
if b.fork == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.forkVal()
|
|
||||||
}
|
|
||||||
|
|
||||||
// forkVal version of the beacon chain.
|
|
||||||
// This assumes that a lock is already held on BeaconState.
|
|
||||||
func (b *BeaconState) forkVal() *ethpb.Fork {
|
|
||||||
if b.fork == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
prevVersion := make([]byte, len(b.fork.PreviousVersion))
|
|
||||||
copy(prevVersion, b.fork.PreviousVersion)
|
|
||||||
currVersion := make([]byte, len(b.fork.CurrentVersion))
|
|
||||||
copy(currVersion, b.fork.CurrentVersion)
|
|
||||||
return ðpb.Fork{
|
|
||||||
PreviousVersion: prevVersion,
|
|
||||||
CurrentVersion: currVersion,
|
|
||||||
Epoch: b.fork.Epoch,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HistoricalRoots based on epochs stored in the beacon state.
|
|
||||||
func (b *BeaconState) HistoricalRoots() [][]byte {
|
|
||||||
if b.historicalRoots == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.historicalRoots.Slice()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
|
|
||||||
m, err := b.randaoMixAtIndex(idx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return m[:], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// randaoMixAtIndex retrieves a specific block root based on an
|
|
||||||
// input index value.
|
|
||||||
// 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 b.randaoMixes[idx], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 b.randaoMixes == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return len(b.randaoMixes)
|
|
||||||
}
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ToProtoUnsafe returns the pointer value of the underlying
|
|
||||||
// beacon state proto object, bypassing immutability. Use with care.
|
|
||||||
func (b *BeaconState) ToProtoUnsafe() interface{} {
|
|
||||||
if b == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
gvrCopy := b.genesisValidatorsRoot
|
|
||||||
|
|
||||||
return ðpb.BeaconState{
|
|
||||||
GenesisTime: b.genesisTime,
|
|
||||||
GenesisValidatorsRoot: gvrCopy[:],
|
|
||||||
Slot: b.slot,
|
|
||||||
Fork: b.fork,
|
|
||||||
LatestBlockHeader: b.latestBlockHeader,
|
|
||||||
BlockRoots: b.blockRoots.Slice(),
|
|
||||||
StateRoots: b.stateRoots.Slice(),
|
|
||||||
HistoricalRoots: b.historicalRoots.Slice(),
|
|
||||||
Eth1Data: b.eth1Data,
|
|
||||||
Eth1DataVotes: b.eth1DataVotes,
|
|
||||||
Eth1DepositIndex: b.eth1DepositIndex,
|
|
||||||
Validators: b.validators,
|
|
||||||
Balances: b.balances,
|
|
||||||
RandaoMixes: b.randaoMixes.Slice(),
|
|
||||||
Slashings: b.slashings,
|
|
||||||
PreviousEpochAttestations: b.previousEpochAttestations,
|
|
||||||
CurrentEpochAttestations: b.currentEpochAttestations,
|
|
||||||
JustificationBits: b.justificationBits,
|
|
||||||
PreviousJustifiedCheckpoint: b.previousJustifiedCheckpoint,
|
|
||||||
CurrentJustifiedCheckpoint: b.currentJustifiedCheckpoint,
|
|
||||||
FinalizedCheckpoint: b.finalizedCheckpoint,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToProto the beacon state into a protobuf for usage.
|
|
||||||
func (b *BeaconState) ToProto() interface{} {
|
|
||||||
if b == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
gvrCopy := b.genesisValidatorsRoot
|
|
||||||
|
|
||||||
return ðpb.BeaconState{
|
|
||||||
GenesisTime: b.genesisTime,
|
|
||||||
GenesisValidatorsRoot: gvrCopy[:],
|
|
||||||
Slot: b.slot,
|
|
||||||
Fork: b.forkVal(),
|
|
||||||
LatestBlockHeader: b.latestBlockHeaderVal(),
|
|
||||||
BlockRoots: b.blockRoots.Slice(),
|
|
||||||
StateRoots: b.stateRoots.Slice(),
|
|
||||||
HistoricalRoots: b.historicalRoots.Slice(),
|
|
||||||
Eth1Data: b.eth1DataVal(),
|
|
||||||
Eth1DataVotes: b.eth1DataVotesVal(),
|
|
||||||
Eth1DepositIndex: b.eth1DepositIndex,
|
|
||||||
Validators: b.validatorsVal(),
|
|
||||||
Balances: b.balancesVal(),
|
|
||||||
RandaoMixes: b.randaoMixes.Slice(),
|
|
||||||
Slashings: b.slashingsVal(),
|
|
||||||
PreviousEpochAttestations: b.previousEpochAttestationsVal(),
|
|
||||||
CurrentEpochAttestations: b.currentEpochAttestationsVal(),
|
|
||||||
JustificationBits: b.justificationBitsVal(),
|
|
||||||
PreviousJustifiedCheckpoint: b.previousJustifiedCheckpointVal(),
|
|
||||||
CurrentJustifiedCheckpoint: b.currentJustifiedCheckpointVal(),
|
|
||||||
FinalizedCheckpoint: b.finalizedCheckpointVal(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
|
|
||||||
r, err := b.stateRootAtIndex(idx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return r[:], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// stateRootAtIndex retrieves a specific state root based on an
|
|
||||||
// input index value.
|
|
||||||
// This assumes that a lock is already held on BeaconState.
|
|
||||||
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 b.stateRoots[idx], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProtobufBeaconState transforms an input into beacon state in the form of protobuf.
|
|
||||||
// Error is returned if the input is not type protobuf beacon state.
|
|
||||||
func ProtobufBeaconState(s interface{}) (*ethpb.BeaconState, error) {
|
|
||||||
pbState, ok := s.(*ethpb.BeaconState)
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("input is not type ethpb.BeaconState")
|
|
||||||
}
|
|
||||||
return pbState, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// InnerStateUnsafe returns the pointer value of the underlying
|
|
||||||
// beacon state proto object, bypassing immutability. Use with care.
|
|
||||||
func (b *BeaconState) InnerStateUnsafe() interface{} {
|
|
||||||
return b.ToProtoUnsafe()
|
|
||||||
}
|
|
||||||
|
|
||||||
// CloneInnerState the beacon state into a protobuf for usage.
|
|
||||||
func (b *BeaconState) CloneInnerState() interface{} {
|
|
||||||
return b.ToProto()
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
|
||||||
testtmpl "github.com/prysmaticlabs/prysm/beacon-chain/state/testing"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestBeaconState_SlotDataRace(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateSlotDataRace(t, func() (state.BeaconState, error) {
|
|
||||||
return InitializeFromProto(ðpb.BeaconState{Slot: 1})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_MatchCurrentJustifiedCheckpt(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateMatchCurrentJustifiedCheckptNative(
|
|
||||||
t,
|
|
||||||
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
|
||||||
return InitializeFromProto(ðpb.BeaconState{CurrentJustifiedCheckpoint: cp})
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_MatchPreviousJustifiedCheckpt(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateMatchPreviousJustifiedCheckptNative(
|
|
||||||
t,
|
|
||||||
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
|
||||||
return InitializeFromProto(ðpb.BeaconState{PreviousJustifiedCheckpoint: cp})
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_ValidatorByPubkey(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateValidatorByPubkey(t, func() (state.BeaconState, error) {
|
|
||||||
return InitializeFromProto(ðpb.BeaconState{})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,250 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
|
||||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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 types.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
|
|
||||||
}
|
|
||||||
|
|
||||||
res := make([]*ethpb.Validator, len(b.validators))
|
|
||||||
for i := 0; i < len(res); i++ {
|
|
||||||
val := b.validators[i]
|
|
||||||
if val == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
res[i] = ethpb.CopyValidator(val)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// references of validators participating in consensus on the beacon chain.
|
|
||||||
// This assumes that a lock is already held on BeaconState. This does not
|
|
||||||
// copy fully and instead just copies the reference.
|
|
||||||
func (b *BeaconState) validatorsReferences() []*ethpb.Validator {
|
|
||||||
if b.validators == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
res := make([]*ethpb.Validator, len(b.validators))
|
|
||||||
for i := 0; i < len(res); i++ {
|
|
||||||
validator := b.validators[i]
|
|
||||||
if validator == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// copy validator reference instead.
|
|
||||||
res[i] = validator
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValidatorAtIndex is the validator at the provided index.
|
|
||||||
func (b *BeaconState) ValidatorAtIndex(idx types.ValidatorIndex) (*ethpb.Validator, error) {
|
|
||||||
if b.validators == nil {
|
|
||||||
return ðpb.Validator{}, nil
|
|
||||||
}
|
|
||||||
if uint64(len(b.validators)) <= uint64(idx) {
|
|
||||||
e := NewValidatorIndexOutOfRangeError(idx)
|
|
||||||
return nil, &e
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
val := b.validators[idx]
|
|
||||||
return ethpb.CopyValidator(val), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValidatorAtIndexReadOnly is the validator at the provided index. This method
|
|
||||||
// doesn't clone the validator.
|
|
||||||
func (b *BeaconState) ValidatorAtIndexReadOnly(idx types.ValidatorIndex) (state.ReadOnlyValidator, error) {
|
|
||||||
if b.validators == nil {
|
|
||||||
return nil, state.ErrNilValidatorsInState
|
|
||||||
}
|
|
||||||
if uint64(len(b.validators)) <= uint64(idx) {
|
|
||||||
e := NewValidatorIndexOutOfRangeError(idx)
|
|
||||||
return nil, &e
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return NewValidator(b.validators[idx])
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValidatorIndexByPubkey returns a given validator by its 48-byte public key.
|
|
||||||
func (b *BeaconState) ValidatorIndexByPubkey(key [fieldparams.BLSPubkeyLength]byte) (types.ValidatorIndex, bool) {
|
|
||||||
if b == nil || b.valMapHandler == nil || b.valMapHandler.IsNil() {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
numOfVals := len(b.validators)
|
|
||||||
|
|
||||||
idx, ok := b.valMapHandler.Get(key)
|
|
||||||
if ok && types.ValidatorIndex(numOfVals) <= idx {
|
|
||||||
return types.ValidatorIndex(0), false
|
|
||||||
}
|
|
||||||
return idx, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// PubkeyAtIndex returns the pubkey at the given
|
|
||||||
// validator index.
|
|
||||||
func (b *BeaconState) PubkeyAtIndex(idx types.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 {
|
|
||||||
return [fieldparams.BLSPubkeyLength]byte{}
|
|
||||||
}
|
|
||||||
return bytesutil.ToBytes48(b.validators[idx].PublicKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NumValidators returns the size of the validator registry.
|
|
||||||
func (b *BeaconState) NumValidators() int {
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return len(b.validators)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
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 {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
}
|
|
||||||
|
|
||||||
// balances 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 b.balances == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
res := make([]uint64, len(b.balances))
|
|
||||||
copy(res, b.balances)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// BalanceAtIndex of validator with the provided index.
|
|
||||||
func (b *BeaconState) BalanceAtIndex(idx types.ValidatorIndex) (uint64, error) {
|
|
||||||
if b.balances == nil {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
if uint64(len(b.balances)) <= uint64(idx) {
|
|
||||||
return 0, fmt.Errorf("index of %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()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Slashings of validators on the beacon chain.
|
|
||||||
func (b *BeaconState) Slashings() []uint64 {
|
|
||||||
if b.slashings == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.slashingsVal()
|
|
||||||
}
|
|
||||||
|
|
||||||
// slashings of validators on the beacon chain.
|
|
||||||
// This assumes that a lock is already held on BeaconState.
|
|
||||||
func (b *BeaconState) slashingsVal() []uint64 {
|
|
||||||
if b.slashings == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
res := make([]uint64, len(b.slashings))
|
|
||||||
copy(res, b.slashings)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package v1_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
|
||||||
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/v1"
|
|
||||||
testtmpl "github.com/prysmaticlabs/prysm/beacon-chain/state/testing"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestBeaconState_ValidatorAtIndexReadOnly_HandlesNilSlice(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateValidatorAtIndexReadOnlyHandlesNilSlice(t, func() (state.BeaconState, error) {
|
|
||||||
return v1.InitializeFromProtoUnsafe(ðpb.BeaconState{
|
|
||||||
Validators: nil,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/binary"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/fieldtrie"
|
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
finalizedRootIndex = uint64(105) // Precomputed value.
|
|
||||||
)
|
|
||||||
|
|
||||||
// FinalizedRootGeneralizedIndex for the beacon state.
|
|
||||||
func FinalizedRootGeneralizedIndex() uint64 {
|
|
||||||
return finalizedRootIndex
|
|
||||||
}
|
|
||||||
|
|
||||||
// CurrentSyncCommitteeProof from the state's Merkle trie representation.
|
|
||||||
func (*BeaconState) CurrentSyncCommitteeProof(_ context.Context) ([][]byte, error) {
|
|
||||||
return nil, errors.New("CurrentSyncCommitteeProof() unsupported for v1 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// NextSyncCommitteeProof from the state's Merkle trie representation.
|
|
||||||
func (*BeaconState) NextSyncCommitteeProof(_ context.Context) ([][]byte, error) {
|
|
||||||
return nil, errors.New("NextSyncCommitteeProof() unsupported for v1 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// FinalizedRootProof crafts a Merkle proof for the finalized root
|
|
||||||
// contained within the finalized checkpoint of a beacon state.
|
|
||||||
func (b *BeaconState) FinalizedRootProof(ctx context.Context) ([][]byte, error) {
|
|
||||||
b.lock.Lock()
|
|
||||||
defer b.lock.Unlock()
|
|
||||||
if err := b.initializeMerkleLayers(ctx); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := b.recomputeDirtyFields(ctx); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
cpt := b.finalizedCheckpoint
|
|
||||||
// The epoch field of a finalized checkpoint is the neighbor
|
|
||||||
// index of the finalized root field in its Merkle tree representation
|
|
||||||
// of the checkpoint. This neighbor is the first element added to the proof.
|
|
||||||
epochBuf := make([]byte, 8)
|
|
||||||
binary.LittleEndian.PutUint64(epochBuf, uint64(cpt.Epoch))
|
|
||||||
epochRoot := bytesutil.ToBytes32(epochBuf)
|
|
||||||
proof := make([][]byte, 0)
|
|
||||||
proof = append(proof, epochRoot[:])
|
|
||||||
branch := fieldtrie.ProofFromMerkleLayers(b.merkleLayers, finalizedCheckpoint)
|
|
||||||
proof = append(proof, branch...)
|
|
||||||
return proof, nil
|
|
||||||
}
|
|
||||||
@@ -1,393 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
"runtime"
|
|
||||||
"runtime/debug"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/prysmaticlabs/go-bitfield"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/types"
|
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestStateReferenceSharing_Finalizer(t *testing.T) {
|
|
||||||
// This test showcases the logic on a the RandaoMixes field with the GC finalizer.
|
|
||||||
|
|
||||||
a, err := InitializeFromProtoUnsafe(ðpb.BeaconState{RandaoMixes: [][]byte{[]byte("foo")}})
|
|
||||||
require.NoError(t, err)
|
|
||||||
s, ok := a.(*BeaconState)
|
|
||||||
require.Equal(t, true, ok)
|
|
||||||
assert.Equal(t, uint(1), s.sharedFieldReferences[randaoMixes].Refs(), "Expected a single reference for RANDAO mixes")
|
|
||||||
|
|
||||||
func() {
|
|
||||||
// Create object in a different scope for GC
|
|
||||||
b := a.Copy()
|
|
||||||
assert.Equal(t, uint(2), s.sharedFieldReferences[randaoMixes].Refs(), "Expected 2 references to RANDAO mixes")
|
|
||||||
_ = b
|
|
||||||
}()
|
|
||||||
|
|
||||||
runtime.GC() // Should run finalizer on object b
|
|
||||||
assert.Equal(t, uint(1), s.sharedFieldReferences[randaoMixes].Refs(), "Expected 1 shared reference to RANDAO mixes!")
|
|
||||||
|
|
||||||
copied := a.Copy()
|
|
||||||
b, ok := copied.(*BeaconState)
|
|
||||||
require.Equal(t, true, ok)
|
|
||||||
assert.Equal(t, uint(2), b.sharedFieldReferences[randaoMixes].Refs(), "Expected 2 shared references to RANDAO mixes")
|
|
||||||
require.NoError(t, b.UpdateRandaoMixesAtIndex(0, []byte("bar")))
|
|
||||||
if b.sharedFieldReferences[randaoMixes].Refs() != 1 || s.sharedFieldReferences[randaoMixes].Refs() != 1 {
|
|
||||||
t.Error("Expected 1 shared reference to RANDAO mix for both a and b")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStateReferenceCopy_NoUnexpectedRootsMutation(t *testing.T) {
|
|
||||||
root1, root2 := bytesutil.ToBytes32([]byte("foo")), bytesutil.ToBytes32([]byte("bar"))
|
|
||||||
a, err := InitializeFromProtoUnsafe(ðpb.BeaconState{
|
|
||||||
BlockRoots: [][]byte{
|
|
||||||
root1[:],
|
|
||||||
},
|
|
||||||
StateRoots: [][]byte{
|
|
||||||
root1[:],
|
|
||||||
},
|
|
||||||
})
|
|
||||||
require.NoError(t, err)
|
|
||||||
s, ok := a.(*BeaconState)
|
|
||||||
require.Equal(t, true, ok)
|
|
||||||
assertRefCount(t, s, blockRoots, 1)
|
|
||||||
assertRefCount(t, s, stateRoots, 1)
|
|
||||||
|
|
||||||
// Copy, increases reference count.
|
|
||||||
copied := a.Copy()
|
|
||||||
b, ok := copied.(*BeaconState)
|
|
||||||
require.Equal(t, true, ok)
|
|
||||||
assertRefCount(t, s, blockRoots, 2)
|
|
||||||
assertRefCount(t, s, stateRoots, 2)
|
|
||||||
assertRefCount(t, b, blockRoots, 2)
|
|
||||||
assertRefCount(t, b, stateRoots, 2)
|
|
||||||
assert.Equal(t, 8192, len(b.BlockRoots()), "Wrong number of block roots found")
|
|
||||||
assert.Equal(t, 8192, len(b.StateRoots()), "Wrong number of state roots found")
|
|
||||||
|
|
||||||
// Assert shared state.
|
|
||||||
blockRootsA := a.BlockRoots()
|
|
||||||
stateRootsA := a.StateRoots()
|
|
||||||
blockRootsB := b.BlockRoots()
|
|
||||||
stateRootsB := b.StateRoots()
|
|
||||||
if len(blockRootsA) != len(blockRootsB) || len(blockRootsA) < 1 {
|
|
||||||
t.Errorf("Unexpected number of block roots, want: %v", 1)
|
|
||||||
}
|
|
||||||
if len(stateRootsA) != len(stateRootsB) || len(stateRootsA) < 1 {
|
|
||||||
t.Errorf("Unexpected number of state roots, want: %v", 1)
|
|
||||||
}
|
|
||||||
assertValFound(t, blockRootsA, root1[:])
|
|
||||||
assertValFound(t, blockRootsB, root1[:])
|
|
||||||
assertValFound(t, stateRootsA, root1[:])
|
|
||||||
assertValFound(t, stateRootsB, root1[:])
|
|
||||||
|
|
||||||
// Mutator should only affect calling state: a.
|
|
||||||
require.NoError(t, a.UpdateBlockRootAtIndex(0, root2))
|
|
||||||
require.NoError(t, a.UpdateStateRootAtIndex(0, root2))
|
|
||||||
|
|
||||||
// Assert no shared state mutation occurred only on state a (copy on write).
|
|
||||||
assertValNotFound(t, a.BlockRoots(), root1[:])
|
|
||||||
assertValNotFound(t, a.StateRoots(), root1[:])
|
|
||||||
assertValFound(t, a.BlockRoots(), root2[:])
|
|
||||||
assertValFound(t, a.StateRoots(), root2[:])
|
|
||||||
assertValFound(t, b.BlockRoots(), root1[:])
|
|
||||||
assertValFound(t, b.StateRoots(), root1[:])
|
|
||||||
if len(blockRootsA) != len(blockRootsB) || len(blockRootsA) < 1 {
|
|
||||||
t.Errorf("Unexpected number of block roots, want: %v", 1)
|
|
||||||
}
|
|
||||||
if len(stateRootsA) != len(stateRootsB) || len(stateRootsA) < 1 {
|
|
||||||
t.Errorf("Unexpected number of state roots, want: %v", 1)
|
|
||||||
}
|
|
||||||
assert.DeepEqual(t, root2[:], a.BlockRoots()[0], "Expected mutation not found")
|
|
||||||
assert.DeepEqual(t, root2[:], a.StateRoots()[0], "Expected mutation not found")
|
|
||||||
assert.DeepEqual(t, root1[:], blockRootsB[0], "Unexpected mutation found")
|
|
||||||
assert.DeepEqual(t, root1[:], stateRootsB[0], "Unexpected mutation found")
|
|
||||||
|
|
||||||
// Copy on write happened, reference counters are reset.
|
|
||||||
assertRefCount(t, s, blockRoots, 1)
|
|
||||||
assertRefCount(t, s, stateRoots, 1)
|
|
||||||
assertRefCount(t, b, blockRoots, 1)
|
|
||||||
assertRefCount(t, b, stateRoots, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStateReferenceCopy_NoUnexpectedRandaoMutation(t *testing.T) {
|
|
||||||
|
|
||||||
val1, val2 := bytesutil.PadTo([]byte("foo"), 32), bytesutil.PadTo([]byte("bar"), 32)
|
|
||||||
a, err := InitializeFromProtoUnsafe(ðpb.BeaconState{
|
|
||||||
RandaoMixes: [][]byte{
|
|
||||||
val1,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
require.NoError(t, err)
|
|
||||||
s, ok := a.(*BeaconState)
|
|
||||||
require.Equal(t, true, ok)
|
|
||||||
assertRefCount(t, s, randaoMixes, 1)
|
|
||||||
|
|
||||||
// Copy, increases reference count.
|
|
||||||
copied := a.Copy()
|
|
||||||
b, ok := copied.(*BeaconState)
|
|
||||||
require.Equal(t, true, ok)
|
|
||||||
assertRefCount(t, s, randaoMixes, 2)
|
|
||||||
assertRefCount(t, b, randaoMixes, 2)
|
|
||||||
|
|
||||||
// Assert shared state.
|
|
||||||
mixesA := a.RandaoMixes()
|
|
||||||
mixesB := b.RandaoMixes()
|
|
||||||
if len(mixesA) != len(mixesB) || len(mixesA) < 1 {
|
|
||||||
t.Errorf("Unexpected number of mix values, want: %v", 1)
|
|
||||||
}
|
|
||||||
assertValFound(t, mixesA, val1)
|
|
||||||
assertValFound(t, mixesB, val1)
|
|
||||||
|
|
||||||
// Mutator should only affect calling state: a.
|
|
||||||
require.NoError(t, a.UpdateRandaoMixesAtIndex(0, val2))
|
|
||||||
|
|
||||||
// Assert no shared state mutation occurred only on state a (copy on write).
|
|
||||||
if len(mixesA) != len(mixesB) || len(mixesA) < 1 {
|
|
||||||
t.Errorf("Unexpected number of mix values, want: %v", 1)
|
|
||||||
}
|
|
||||||
assertValFound(t, a.RandaoMixes(), val2)
|
|
||||||
assertValNotFound(t, a.RandaoMixes(), val1)
|
|
||||||
assertValFound(t, b.RandaoMixes(), val1)
|
|
||||||
assertValNotFound(t, b.RandaoMixes(), val2)
|
|
||||||
assertValFound(t, mixesB, val1)
|
|
||||||
assertValNotFound(t, mixesB, val2)
|
|
||||||
assert.DeepEqual(t, val2, a.RandaoMixes()[0], "Expected mutation not found")
|
|
||||||
assert.DeepEqual(t, val1, mixesB[0], "Unexpected mutation found")
|
|
||||||
|
|
||||||
// Copy on write happened, reference counters are reset.
|
|
||||||
assertRefCount(t, s, randaoMixes, 1)
|
|
||||||
assertRefCount(t, b, randaoMixes, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStateReferenceCopy_NoUnexpectedAttestationsMutation(t *testing.T) {
|
|
||||||
assertAttFound := func(vals []*ethpb.PendingAttestation, val uint64) {
|
|
||||||
for i := range vals {
|
|
||||||
if reflect.DeepEqual(vals[i].AggregationBits, bitfield.NewBitlist(val)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t.Log(string(debug.Stack()))
|
|
||||||
t.Fatalf("Expected attestation not found (%v), want: %v", vals, val)
|
|
||||||
}
|
|
||||||
assertAttNotFound := func(vals []*ethpb.PendingAttestation, val uint64) {
|
|
||||||
for i := range vals {
|
|
||||||
if reflect.DeepEqual(vals[i].AggregationBits, bitfield.NewBitlist(val)) {
|
|
||||||
t.Log(string(debug.Stack()))
|
|
||||||
t.Fatalf("Unexpected attestation found (%v): %v", vals, val)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a, err := InitializeFromProtoUnsafe(ðpb.BeaconState{})
|
|
||||||
require.NoError(t, err)
|
|
||||||
s, ok := a.(*BeaconState)
|
|
||||||
require.Equal(t, true, ok)
|
|
||||||
assertRefCount(t, s, previousEpochAttestations, 1)
|
|
||||||
assertRefCount(t, s, currentEpochAttestations, 1)
|
|
||||||
|
|
||||||
// Update initial state.
|
|
||||||
atts := []*ethpb.PendingAttestation{
|
|
||||||
{AggregationBits: bitfield.NewBitlist(1)},
|
|
||||||
{AggregationBits: bitfield.NewBitlist(2)},
|
|
||||||
}
|
|
||||||
s.setPreviousEpochAttestations(atts[:1])
|
|
||||||
s.setCurrentEpochAttestations(atts[:1])
|
|
||||||
curAtt, err := a.CurrentEpochAttestations()
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 1, len(curAtt), "Unexpected number of attestations")
|
|
||||||
preAtt, err := a.PreviousEpochAttestations()
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 1, len(preAtt), "Unexpected number of attestations")
|
|
||||||
|
|
||||||
// Copy, increases reference count.
|
|
||||||
copied := a.Copy()
|
|
||||||
b, ok := copied.(*BeaconState)
|
|
||||||
require.Equal(t, true, ok)
|
|
||||||
assertRefCount(t, s, previousEpochAttestations, 2)
|
|
||||||
assertRefCount(t, s, currentEpochAttestations, 2)
|
|
||||||
assertRefCount(t, b, previousEpochAttestations, 2)
|
|
||||||
assertRefCount(t, b, currentEpochAttestations, 2)
|
|
||||||
bPrevEpochAtts, err := b.PreviousEpochAttestations()
|
|
||||||
require.NoError(t, err)
|
|
||||||
bCurrEpochAtts, err := b.CurrentEpochAttestations()
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 1, len(bPrevEpochAtts), "Unexpected number of attestations")
|
|
||||||
assert.Equal(t, 1, len(bCurrEpochAtts), "Unexpected number of attestations")
|
|
||||||
|
|
||||||
// Assert shared state.
|
|
||||||
aCurrEpochAtts, err := a.CurrentEpochAttestations()
|
|
||||||
require.NoError(t, err)
|
|
||||||
curAttsA := aCurrEpochAtts
|
|
||||||
aPrevEpochAtts, err := a.PreviousEpochAttestations()
|
|
||||||
require.NoError(t, err)
|
|
||||||
prevAttsA := aPrevEpochAtts
|
|
||||||
bCurrEpochAtts, err = b.CurrentEpochAttestations()
|
|
||||||
require.NoError(t, err)
|
|
||||||
curAttsB := bCurrEpochAtts
|
|
||||||
bPrevEpochAtts, err = b.PreviousEpochAttestations()
|
|
||||||
require.NoError(t, err)
|
|
||||||
prevAttsB := bPrevEpochAtts
|
|
||||||
if len(curAttsA) != len(curAttsB) || len(curAttsA) < 1 {
|
|
||||||
t.Errorf("Unexpected number of attestations, want: %v", 1)
|
|
||||||
}
|
|
||||||
if len(prevAttsA) != len(prevAttsB) || len(prevAttsA) < 1 {
|
|
||||||
t.Errorf("Unexpected number of attestations, want: %v", 1)
|
|
||||||
}
|
|
||||||
assertAttFound(curAttsA, 1)
|
|
||||||
assertAttFound(prevAttsA, 1)
|
|
||||||
assertAttFound(curAttsB, 1)
|
|
||||||
assertAttFound(prevAttsB, 1)
|
|
||||||
|
|
||||||
// Extends state a attestations.
|
|
||||||
require.NoError(t, a.AppendCurrentEpochAttestations(atts[1]))
|
|
||||||
require.NoError(t, a.AppendPreviousEpochAttestations(atts[1]))
|
|
||||||
curAtt, err = a.CurrentEpochAttestations()
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 2, len(curAtt), "Unexpected number of attestations")
|
|
||||||
preAtt, err = a.PreviousEpochAttestations()
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 2, len(preAtt), "Unexpected number of attestations")
|
|
||||||
aCurrEpochAtts, err = a.CurrentEpochAttestations()
|
|
||||||
require.NoError(t, err)
|
|
||||||
aPrevEpochAtts, err = a.PreviousEpochAttestations()
|
|
||||||
require.NoError(t, err)
|
|
||||||
bCurrEpochAtts, err = b.CurrentEpochAttestations()
|
|
||||||
require.NoError(t, err)
|
|
||||||
bPrevEpochAtts, err = b.PreviousEpochAttestations()
|
|
||||||
require.NoError(t, err)
|
|
||||||
assertAttFound(aCurrEpochAtts, 1)
|
|
||||||
assertAttFound(aPrevEpochAtts, 1)
|
|
||||||
assertAttFound(aCurrEpochAtts, 2)
|
|
||||||
assertAttFound(aPrevEpochAtts, 2)
|
|
||||||
assertAttFound(bCurrEpochAtts, 1)
|
|
||||||
assertAttFound(bPrevEpochAtts, 1)
|
|
||||||
assertAttNotFound(bCurrEpochAtts, 2)
|
|
||||||
assertAttNotFound(bPrevEpochAtts, 2)
|
|
||||||
|
|
||||||
// Mutator should only affect calling state: a.
|
|
||||||
applyToEveryAttestation := func(state *BeaconState) {
|
|
||||||
// One MUST copy on write.
|
|
||||||
atts = make([]*ethpb.PendingAttestation, len(state.currentEpochAttestations))
|
|
||||||
copy(atts, state.currentEpochAttestations)
|
|
||||||
state.currentEpochAttestations = atts
|
|
||||||
currEpochAtts, err := state.CurrentEpochAttestations()
|
|
||||||
require.NoError(t, err)
|
|
||||||
for i := range currEpochAtts {
|
|
||||||
att := ethpb.CopyPendingAttestation(state.currentEpochAttestations[i])
|
|
||||||
att.AggregationBits = bitfield.NewBitlist(3)
|
|
||||||
state.currentEpochAttestations[i] = att
|
|
||||||
}
|
|
||||||
|
|
||||||
atts = make([]*ethpb.PendingAttestation, len(state.previousEpochAttestations))
|
|
||||||
copy(atts, state.previousEpochAttestations)
|
|
||||||
state.previousEpochAttestations = atts
|
|
||||||
prevEpochAtts, err := state.PreviousEpochAttestations()
|
|
||||||
require.NoError(t, err)
|
|
||||||
for i := range prevEpochAtts {
|
|
||||||
att := ethpb.CopyPendingAttestation(state.previousEpochAttestations[i])
|
|
||||||
att.AggregationBits = bitfield.NewBitlist(3)
|
|
||||||
state.previousEpochAttestations[i] = att
|
|
||||||
}
|
|
||||||
}
|
|
||||||
applyToEveryAttestation(s)
|
|
||||||
|
|
||||||
aCurrEpochAtts, err = a.CurrentEpochAttestations()
|
|
||||||
require.NoError(t, err)
|
|
||||||
aPrevEpochAtts, err = a.PreviousEpochAttestations()
|
|
||||||
require.NoError(t, err)
|
|
||||||
bCurrEpochAtts, err = b.CurrentEpochAttestations()
|
|
||||||
require.NoError(t, err)
|
|
||||||
bPrevEpochAtts, err = b.PreviousEpochAttestations()
|
|
||||||
require.NoError(t, err)
|
|
||||||
// Assert no shared state mutation occurred only on state a (copy on write).
|
|
||||||
assertAttFound(aCurrEpochAtts, 3)
|
|
||||||
assertAttFound(aPrevEpochAtts, 3)
|
|
||||||
assertAttNotFound(aCurrEpochAtts, 1)
|
|
||||||
assertAttNotFound(aPrevEpochAtts, 1)
|
|
||||||
assertAttNotFound(aCurrEpochAtts, 2)
|
|
||||||
assertAttNotFound(aPrevEpochAtts, 2)
|
|
||||||
// State b must be unaffected.
|
|
||||||
assertAttNotFound(bCurrEpochAtts, 3)
|
|
||||||
assertAttNotFound(bPrevEpochAtts, 3)
|
|
||||||
assertAttFound(bCurrEpochAtts, 1)
|
|
||||||
assertAttFound(bPrevEpochAtts, 1)
|
|
||||||
assertAttNotFound(bCurrEpochAtts, 2)
|
|
||||||
assertAttNotFound(bPrevEpochAtts, 2)
|
|
||||||
|
|
||||||
// Copy on write happened, reference counters are reset.
|
|
||||||
assertRefCount(t, s, currentEpochAttestations, 1)
|
|
||||||
assertRefCount(t, b, currentEpochAttestations, 1)
|
|
||||||
assertRefCount(t, s, previousEpochAttestations, 1)
|
|
||||||
assertRefCount(t, b, previousEpochAttestations, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestValidatorReferences_RemainsConsistent(t *testing.T) {
|
|
||||||
a, err := InitializeFromProtoUnsafe(ðpb.BeaconState{
|
|
||||||
Validators: []*ethpb.Validator{
|
|
||||||
{PublicKey: []byte{'A'}},
|
|
||||||
{PublicKey: []byte{'B'}},
|
|
||||||
{PublicKey: []byte{'C'}},
|
|
||||||
{PublicKey: []byte{'D'}},
|
|
||||||
{PublicKey: []byte{'E'}},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// Create a second state.
|
|
||||||
copied := a.Copy()
|
|
||||||
b, ok := copied.(*BeaconState)
|
|
||||||
require.Equal(t, true, ok)
|
|
||||||
|
|
||||||
// Update First Validator.
|
|
||||||
assert.NoError(t, a.UpdateValidatorAtIndex(0, ðpb.Validator{PublicKey: []byte{'Z'}}))
|
|
||||||
|
|
||||||
assert.DeepNotEqual(t, a.Validators()[0], b.Validators()[0], "validators are equal when they are supposed to be different")
|
|
||||||
// Modify all validators from copied state.
|
|
||||||
assert.NoError(t, b.ApplyToEveryValidator(func(idx int, val *ethpb.Validator) (bool, *ethpb.Validator, error) {
|
|
||||||
return true, ðpb.Validator{PublicKey: []byte{'V'}}, nil
|
|
||||||
}))
|
|
||||||
|
|
||||||
// Ensure reference is properly accounted for.
|
|
||||||
assert.NoError(t, a.ReadFromEveryValidator(func(idx int, val state.ReadOnlyValidator) error {
|
|
||||||
assert.NotEqual(t, bytesutil.ToBytes48([]byte{'V'}), val.PublicKey())
|
|
||||||
return nil
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
// assertRefCount checks whether reference count for a given state
|
|
||||||
// at a given index is equal to expected amount.
|
|
||||||
func assertRefCount(t *testing.T, b *BeaconState, idx types.FieldIndex, want uint) {
|
|
||||||
if cnt := b.sharedFieldReferences[idx].Refs(); cnt != want {
|
|
||||||
t.Errorf("Unexpected count of references for index %d, want: %v, got: %v", idx, want, cnt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// assertValFound checks whether item with a given value exists in list.
|
|
||||||
func assertValFound(t *testing.T, vals [][]byte, val []byte) {
|
|
||||||
for i := range vals {
|
|
||||||
if reflect.DeepEqual(vals[i], val) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t.Log(string(debug.Stack()))
|
|
||||||
t.Fatalf("Expected value not found (%v), want: %v", vals, val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// assertValNotFound checks whether item with a given value doesn't exist in list.
|
|
||||||
func assertValNotFound(t *testing.T, vals [][]byte, val []byte) {
|
|
||||||
for i := range vals {
|
|
||||||
if reflect.DeepEqual(vals[i], val) {
|
|
||||||
t.Log(string(debug.Stack()))
|
|
||||||
t.Errorf("Unexpected value found (%v),: %v", vals, val)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/prysmaticlabs/go-bitfield"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SetJustificationBits for the beacon state.
|
|
||||||
func (b *BeaconState) SetJustificationBits(val bitfield.Bitvector4) error {
|
|
||||||
b.lock.Lock()
|
|
||||||
defer b.lock.Unlock()
|
|
||||||
|
|
||||||
b.justificationBits = val
|
|
||||||
b.markFieldAsDirty(justificationBits)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPreviousJustifiedCheckpoint for the beacon state.
|
|
||||||
func (b *BeaconState) SetPreviousJustifiedCheckpoint(val *ethpb.Checkpoint) error {
|
|
||||||
b.lock.Lock()
|
|
||||||
defer b.lock.Unlock()
|
|
||||||
|
|
||||||
b.previousJustifiedCheckpoint = val
|
|
||||||
b.markFieldAsDirty(previousJustifiedCheckpoint)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetCurrentJustifiedCheckpoint for the beacon state.
|
|
||||||
func (b *BeaconState) SetCurrentJustifiedCheckpoint(val *ethpb.Checkpoint) error {
|
|
||||||
b.lock.Lock()
|
|
||||||
defer b.lock.Unlock()
|
|
||||||
|
|
||||||
b.currentJustifiedCheckpoint = val
|
|
||||||
b.markFieldAsDirty(currentJustifiedCheckpoint)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetFinalizedCheckpoint for the beacon state.
|
|
||||||
func (b *BeaconState) SetFinalizedCheckpoint(val *ethpb.Checkpoint) error {
|
|
||||||
b.lock.Lock()
|
|
||||||
defer b.lock.Unlock()
|
|
||||||
|
|
||||||
b.finalizedCheckpoint = val
|
|
||||||
b.markFieldAsDirty(finalizedCheckpoint)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SetEth1Data for the beacon state.
|
|
||||||
func (b *BeaconState) SetEth1Data(val *ethpb.Eth1Data) error {
|
|
||||||
b.lock.Lock()
|
|
||||||
defer b.lock.Unlock()
|
|
||||||
|
|
||||||
b.eth1Data = val
|
|
||||||
b.markFieldAsDirty(eth1Data)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetEth1DataVotes for the beacon state. Updates the entire
|
|
||||||
// list to a new value by overwriting the previous one.
|
|
||||||
func (b *BeaconState) SetEth1DataVotes(val []*ethpb.Eth1Data) error {
|
|
||||||
b.lock.Lock()
|
|
||||||
defer b.lock.Unlock()
|
|
||||||
|
|
||||||
b.sharedFieldReferences[eth1DataVotes].MinusRef()
|
|
||||||
b.sharedFieldReferences[eth1DataVotes] = stateutil.NewRef(1)
|
|
||||||
|
|
||||||
b.eth1DataVotes = val
|
|
||||||
b.markFieldAsDirty(eth1DataVotes)
|
|
||||||
b.rebuildTrie[eth1DataVotes] = true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetEth1DepositIndex for the beacon state.
|
|
||||||
func (b *BeaconState) SetEth1DepositIndex(val uint64) error {
|
|
||||||
b.lock.Lock()
|
|
||||||
defer b.lock.Unlock()
|
|
||||||
|
|
||||||
b.eth1DepositIndex = val
|
|
||||||
b.markFieldAsDirty(eth1DepositIndex)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendEth1DataVotes for the beacon state. Appends the new value
|
|
||||||
// to the the end of list.
|
|
||||||
func (b *BeaconState) AppendEth1DataVotes(val *ethpb.Eth1Data) error {
|
|
||||||
b.lock.Lock()
|
|
||||||
defer b.lock.Unlock()
|
|
||||||
|
|
||||||
votes := b.eth1DataVotes
|
|
||||||
if b.sharedFieldReferences[eth1DataVotes].Refs() > 1 {
|
|
||||||
// Copy elements in underlying array by reference.
|
|
||||||
votes = make([]*ethpb.Eth1Data, len(b.eth1DataVotes))
|
|
||||||
copy(votes, b.eth1DataVotes)
|
|
||||||
b.sharedFieldReferences[eth1DataVotes].MinusRef()
|
|
||||||
b.sharedFieldReferences[eth1DataVotes] = stateutil.NewRef(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
b.eth1DataVotes = append(votes, val)
|
|
||||||
b.markFieldAsDirty(eth1DataVotes)
|
|
||||||
b.addDirtyIndices(eth1DataVotes, []uint64{uint64(len(b.eth1DataVotes) - 1)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,201 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
|
||||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SetValidators for the beacon state. Updates the entire
|
|
||||||
// to a new value by overwriting the previous one.
|
|
||||||
func (b *BeaconState) SetValidators(val []*ethpb.Validator) error {
|
|
||||||
b.lock.Lock()
|
|
||||||
defer b.lock.Unlock()
|
|
||||||
|
|
||||||
b.validators = val
|
|
||||||
b.sharedFieldReferences[validators].MinusRef()
|
|
||||||
b.sharedFieldReferences[validators] = stateutil.NewRef(1)
|
|
||||||
b.markFieldAsDirty(validators)
|
|
||||||
b.rebuildTrie[validators] = true
|
|
||||||
b.valMapHandler = stateutil.NewValMapHandler(b.validators)
|
|
||||||
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[validators]; ref.Refs() > 1 {
|
|
||||||
v = b.validatorsReferences()
|
|
||||||
ref.MinusRef()
|
|
||||||
b.sharedFieldReferences[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 changed {
|
|
||||||
changedVals = append(changedVals, uint64(i))
|
|
||||||
v[i] = newVal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.Lock()
|
|
||||||
defer b.lock.Unlock()
|
|
||||||
|
|
||||||
b.validators = v
|
|
||||||
b.markFieldAsDirty(validators)
|
|
||||||
b.addDirtyIndices(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 types.ValidatorIndex, val *ethpb.Validator) error {
|
|
||||||
if uint64(len(b.validators)) <= uint64(idx) {
|
|
||||||
return errors.Errorf("invalid index provided %d", idx)
|
|
||||||
}
|
|
||||||
b.lock.Lock()
|
|
||||||
defer b.lock.Unlock()
|
|
||||||
|
|
||||||
v := b.validators
|
|
||||||
if ref := b.sharedFieldReferences[validators]; ref.Refs() > 1 {
|
|
||||||
v = b.validatorsReferences()
|
|
||||||
ref.MinusRef()
|
|
||||||
b.sharedFieldReferences[validators] = stateutil.NewRef(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
v[idx] = val
|
|
||||||
b.validators = v
|
|
||||||
b.markFieldAsDirty(validators)
|
|
||||||
b.addDirtyIndices(validators, []uint64{uint64(idx)})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetBalances for the beacon state. Updates the entire
|
|
||||||
// list to a new value by overwriting the previous one.
|
|
||||||
func (b *BeaconState) SetBalances(val []uint64) error {
|
|
||||||
b.lock.Lock()
|
|
||||||
defer b.lock.Unlock()
|
|
||||||
|
|
||||||
b.sharedFieldReferences[balances].MinusRef()
|
|
||||||
b.sharedFieldReferences[balances] = stateutil.NewRef(1)
|
|
||||||
|
|
||||||
b.balances = val
|
|
||||||
b.markFieldAsDirty(balances)
|
|
||||||
b.rebuildTrie[balances] = true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateBalancesAtIndex for the beacon state. This method updates the balance
|
|
||||||
// at a specific index to a new value.
|
|
||||||
func (b *BeaconState) UpdateBalancesAtIndex(idx types.ValidatorIndex, val uint64) error {
|
|
||||||
if uint64(len(b.balances)) <= uint64(idx) {
|
|
||||||
return errors.Errorf("invalid index provided %d", idx)
|
|
||||||
}
|
|
||||||
b.lock.Lock()
|
|
||||||
defer b.lock.Unlock()
|
|
||||||
|
|
||||||
bals := b.balances
|
|
||||||
if b.sharedFieldReferences[balances].Refs() > 1 {
|
|
||||||
bals = b.balancesVal()
|
|
||||||
b.sharedFieldReferences[balances].MinusRef()
|
|
||||||
b.sharedFieldReferences[balances] = stateutil.NewRef(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
bals[idx] = val
|
|
||||||
b.balances = bals
|
|
||||||
b.markFieldAsDirty(balances)
|
|
||||||
b.addDirtyIndices(balances, []uint64{uint64(idx)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetSlashings for the beacon state. Updates the entire
|
|
||||||
// list to a new value by overwriting the previous one.
|
|
||||||
func (b *BeaconState) SetSlashings(val []uint64) error {
|
|
||||||
b.lock.Lock()
|
|
||||||
defer b.lock.Unlock()
|
|
||||||
|
|
||||||
b.sharedFieldReferences[slashings].MinusRef()
|
|
||||||
b.sharedFieldReferences[slashings] = stateutil.NewRef(1)
|
|
||||||
|
|
||||||
b.slashings = val
|
|
||||||
b.markFieldAsDirty(slashings)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateSlashingsAtIndex for the beacon state. Updates the slashings
|
|
||||||
// at a specific index to a new value.
|
|
||||||
func (b *BeaconState) UpdateSlashingsAtIndex(idx, val uint64) error {
|
|
||||||
if uint64(len(b.slashings)) <= idx {
|
|
||||||
return errors.Errorf("invalid index provided %d", idx)
|
|
||||||
}
|
|
||||||
b.lock.Lock()
|
|
||||||
defer b.lock.Unlock()
|
|
||||||
|
|
||||||
s := b.slashings
|
|
||||||
if b.sharedFieldReferences[slashings].Refs() > 1 {
|
|
||||||
s = b.slashingsVal()
|
|
||||||
b.sharedFieldReferences[slashings].MinusRef()
|
|
||||||
b.sharedFieldReferences[slashings] = stateutil.NewRef(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
s[idx] = val
|
|
||||||
|
|
||||||
b.slashings = s
|
|
||||||
|
|
||||||
b.markFieldAsDirty(slashings)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendValidator for the beacon state. Appends the new value
|
|
||||||
// to the the end of list.
|
|
||||||
func (b *BeaconState) AppendValidator(val *ethpb.Validator) error {
|
|
||||||
b.lock.Lock()
|
|
||||||
defer b.lock.Unlock()
|
|
||||||
|
|
||||||
vals := b.validators
|
|
||||||
if b.sharedFieldReferences[validators].Refs() > 1 {
|
|
||||||
vals = b.validatorsReferences()
|
|
||||||
b.sharedFieldReferences[validators].MinusRef()
|
|
||||||
b.sharedFieldReferences[validators] = stateutil.NewRef(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// append validator to slice
|
|
||||||
b.validators = append(vals, val)
|
|
||||||
valIdx := types.ValidatorIndex(len(b.validators) - 1)
|
|
||||||
|
|
||||||
b.valMapHandler.Set(bytesutil.ToBytes48(val.PublicKey), valIdx)
|
|
||||||
|
|
||||||
b.markFieldAsDirty(validators)
|
|
||||||
b.addDirtyIndices(validators, []uint64{uint64(valIdx)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendBalance for the beacon state. Appends the new value
|
|
||||||
// to the the end of list.
|
|
||||||
func (b *BeaconState) AppendBalance(bal uint64) error {
|
|
||||||
b.lock.Lock()
|
|
||||||
defer b.lock.Unlock()
|
|
||||||
|
|
||||||
bals := b.balances
|
|
||||||
if b.sharedFieldReferences[balances].Refs() > 1 {
|
|
||||||
bals = b.balancesVal()
|
|
||||||
b.sharedFieldReferences[balances].MinusRef()
|
|
||||||
b.sharedFieldReferences[balances] = stateutil.NewRef(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
b.balances = append(bals, bal)
|
|
||||||
balIdx := len(b.balances) - 1
|
|
||||||
b.markFieldAsDirty(balances)
|
|
||||||
b.addDirtyIndices(balances, []uint64{uint64(balIdx)})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,475 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"runtime"
|
|
||||||
"sort"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/fieldtrie"
|
|
||||||
customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/types"
|
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
|
||||||
"github.com/prysmaticlabs/prysm/container/slice"
|
|
||||||
"github.com/prysmaticlabs/prysm/crypto/hash"
|
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
|
||||||
"github.com/prysmaticlabs/prysm/encoding/ssz"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
"go.opencensus.io/trace"
|
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
)
|
|
||||||
|
|
||||||
// InitializeFromProto the beacon state from a protobuf representation.
|
|
||||||
func InitializeFromProto(st *ethpb.BeaconState) (state.BeaconState, error) {
|
|
||||||
return InitializeFromProtoUnsafe(proto.Clone(st).(*ethpb.BeaconState))
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitializeFromProtoUnsafe directly uses the beacon state protobuf fields
|
|
||||||
// and sets them as fields of the BeaconState type.
|
|
||||||
func InitializeFromProtoUnsafe(st *ethpb.BeaconState) (state.BeaconState, error) {
|
|
||||||
if st == nil {
|
|
||||||
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{
|
|
||||||
genesisTime: st.GenesisTime,
|
|
||||||
genesisValidatorsRoot: bytesutil.ToBytes32(st.GenesisValidatorsRoot),
|
|
||||||
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,
|
|
||||||
justificationBits: st.JustificationBits,
|
|
||||||
previousJustifiedCheckpoint: st.PreviousJustifiedCheckpoint,
|
|
||||||
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, 10),
|
|
||||||
rebuildTrie: make(map[types.FieldIndex]bool, fieldCount),
|
|
||||||
valMapHandler: stateutil.NewValMapHandler(st.Validators),
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
for i := 0; i < fieldCount; i++ {
|
|
||||||
b.dirtyFields[types.FieldIndex(i)] = true
|
|
||||||
b.rebuildTrie[types.FieldIndex(i)] = true
|
|
||||||
b.dirtyIndices[types.FieldIndex(i)] = []uint64{}
|
|
||||||
b.stateFieldLeaves[types.FieldIndex(i)], err = fieldtrie.NewFieldTrie(types.FieldIndex(i), types.BasicArray, nil, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize field reference tracking for shared data.
|
|
||||||
b.sharedFieldReferences[randaoMixes] = stateutil.NewRef(1)
|
|
||||||
b.sharedFieldReferences[stateRoots] = stateutil.NewRef(1)
|
|
||||||
b.sharedFieldReferences[blockRoots] = stateutil.NewRef(1)
|
|
||||||
b.sharedFieldReferences[previousEpochAttestations] = stateutil.NewRef(1)
|
|
||||||
b.sharedFieldReferences[currentEpochAttestations] = stateutil.NewRef(1)
|
|
||||||
b.sharedFieldReferences[slashings] = stateutil.NewRef(1)
|
|
||||||
b.sharedFieldReferences[eth1DataVotes] = stateutil.NewRef(1)
|
|
||||||
b.sharedFieldReferences[validators] = stateutil.NewRef(1)
|
|
||||||
b.sharedFieldReferences[balances] = stateutil.NewRef(1)
|
|
||||||
b.sharedFieldReferences[historicalRoots] = stateutil.NewRef(1)
|
|
||||||
|
|
||||||
state.StateCount.Inc()
|
|
||||||
return b, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy returns a deep copy of the beacon state.
|
|
||||||
func (b *BeaconState) Copy() state.BeaconState {
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
fieldCount := params.BeaconConfig().BeaconStateFieldCount
|
|
||||||
dst := &BeaconState{
|
|
||||||
// Primitive types, safe to copy.
|
|
||||||
genesisTime: b.genesisTime,
|
|
||||||
slot: b.slot,
|
|
||||||
eth1DepositIndex: b.eth1DepositIndex,
|
|
||||||
|
|
||||||
// Large arrays, infrequently changed, constant size.
|
|
||||||
slashings: b.slashings,
|
|
||||||
|
|
||||||
// Large arrays, infrequently changed, constant size.
|
|
||||||
blockRoots: b.blockRoots,
|
|
||||||
stateRoots: b.stateRoots,
|
|
||||||
randaoMixes: b.randaoMixes,
|
|
||||||
previousEpochAttestations: b.previousEpochAttestations,
|
|
||||||
currentEpochAttestations: b.currentEpochAttestations,
|
|
||||||
eth1DataVotes: b.eth1DataVotes,
|
|
||||||
|
|
||||||
// Large arrays, increases over time.
|
|
||||||
balances: b.balances,
|
|
||||||
historicalRoots: b.historicalRoots,
|
|
||||||
validators: b.validators,
|
|
||||||
|
|
||||||
// Everything else, too small to be concerned about, constant size.
|
|
||||||
genesisValidatorsRoot: b.genesisValidatorsRoot,
|
|
||||||
justificationBits: b.justificationBitsVal(),
|
|
||||||
fork: b.forkVal(),
|
|
||||||
latestBlockHeader: b.latestBlockHeaderVal(),
|
|
||||||
eth1Data: b.eth1DataVal(),
|
|
||||||
previousJustifiedCheckpoint: b.previousJustifiedCheckpointVal(),
|
|
||||||
currentJustifiedCheckpoint: b.currentJustifiedCheckpointVal(),
|
|
||||||
finalizedCheckpoint: b.finalizedCheckpointVal(),
|
|
||||||
|
|
||||||
dirtyFields: make(map[types.FieldIndex]bool, fieldCount),
|
|
||||||
dirtyIndices: make(map[types.FieldIndex][]uint64, fieldCount),
|
|
||||||
rebuildTrie: make(map[types.FieldIndex]bool, fieldCount),
|
|
||||||
sharedFieldReferences: make(map[types.FieldIndex]*stateutil.Reference, 10),
|
|
||||||
stateFieldLeaves: make(map[types.FieldIndex]*fieldtrie.FieldTrie, fieldCount),
|
|
||||||
|
|
||||||
// Share the reference to validator index map.
|
|
||||||
valMapHandler: b.valMapHandler,
|
|
||||||
}
|
|
||||||
|
|
||||||
for field, ref := range b.sharedFieldReferences {
|
|
||||||
ref.AddRef()
|
|
||||||
dst.sharedFieldReferences[field] = ref
|
|
||||||
}
|
|
||||||
|
|
||||||
// Increment ref for validator map
|
|
||||||
b.valMapHandler.AddRef()
|
|
||||||
|
|
||||||
for i := range b.dirtyFields {
|
|
||||||
dst.dirtyFields[i] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := range b.dirtyIndices {
|
|
||||||
indices := make([]uint64, len(b.dirtyIndices[i]))
|
|
||||||
copy(indices, b.dirtyIndices[i])
|
|
||||||
dst.dirtyIndices[i] = indices
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := range b.rebuildTrie {
|
|
||||||
dst.rebuildTrie[i] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
for fldIdx, fieldTrie := range b.stateFieldLeaves {
|
|
||||||
dst.stateFieldLeaves[fldIdx] = fieldTrie
|
|
||||||
if fieldTrie.FieldReference() != nil {
|
|
||||||
fieldTrie.Lock()
|
|
||||||
fieldTrie.FieldReference().AddRef()
|
|
||||||
fieldTrie.Unlock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if b.merkleLayers != nil {
|
|
||||||
dst.merkleLayers = make([][][]byte, len(b.merkleLayers))
|
|
||||||
for i, layer := range b.merkleLayers {
|
|
||||||
dst.merkleLayers[i] = make([][]byte, len(layer))
|
|
||||||
for j, content := range layer {
|
|
||||||
dst.merkleLayers[i][j] = make([]byte, len(content))
|
|
||||||
copy(dst.merkleLayers[i][j], content)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
state.StateCount.Inc()
|
|
||||||
// Finalizer runs when dst is being destroyed in garbage collection.
|
|
||||||
runtime.SetFinalizer(dst, func(b *BeaconState) {
|
|
||||||
for field, v := range b.sharedFieldReferences {
|
|
||||||
v.MinusRef()
|
|
||||||
if b.stateFieldLeaves[field].FieldReference() != nil {
|
|
||||||
b.stateFieldLeaves[field].FieldReference().MinusRef()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
for i := 0; i < fieldCount; i++ {
|
|
||||||
field := types.FieldIndex(i)
|
|
||||||
delete(b.stateFieldLeaves, field)
|
|
||||||
delete(b.dirtyIndices, field)
|
|
||||||
delete(b.dirtyFields, field)
|
|
||||||
delete(b.sharedFieldReferences, field)
|
|
||||||
delete(b.stateFieldLeaves, field)
|
|
||||||
}
|
|
||||||
state.StateCount.Sub(1)
|
|
||||||
})
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// HashTreeRoot of the beacon state retrieves the Merkle root of the trie
|
|
||||||
// representation of the beacon state based on the Ethereum Simple Serialize specification.
|
|
||||||
func (b *BeaconState) HashTreeRoot(ctx context.Context) ([32]byte, error) {
|
|
||||||
ctx, span := trace.StartSpan(ctx, "beaconState.HashTreeRoot")
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
b.lock.Lock()
|
|
||||||
defer b.lock.Unlock()
|
|
||||||
if err := b.initializeMerkleLayers(ctx); err != nil {
|
|
||||||
return [32]byte{}, err
|
|
||||||
}
|
|
||||||
if err := b.recomputeDirtyFields(ctx); err != nil {
|
|
||||||
return [32]byte{}, err
|
|
||||||
}
|
|
||||||
return bytesutil.ToBytes32(b.merkleLayers[len(b.merkleLayers)-1][0]), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initializes the Merkle layers for the beacon state if they are empty.
|
|
||||||
// WARNING: Caller must acquire the mutex before using.
|
|
||||||
func (b *BeaconState) initializeMerkleLayers(ctx context.Context) error {
|
|
||||||
if len(b.merkleLayers) > 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
protoState, ok := b.ToProtoUnsafe().(*ethpb.BeaconState)
|
|
||||||
if !ok {
|
|
||||||
return errors.New("state is of the wrong type")
|
|
||||||
}
|
|
||||||
fieldRoots, err := computeFieldRoots(ctx, protoState)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
layers := stateutil.Merkleize(fieldRoots)
|
|
||||||
b.merkleLayers = layers
|
|
||||||
b.dirtyFields = make(map[types.FieldIndex]bool, params.BeaconConfig().BeaconStateFieldCount)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recomputes the Merkle layers for the dirty fields in the state.
|
|
||||||
// WARNING: Caller must acquire the mutex before using.
|
|
||||||
func (b *BeaconState) recomputeDirtyFields(ctx context.Context) error {
|
|
||||||
for field := range b.dirtyFields {
|
|
||||||
root, err := b.rootSelector(ctx, field)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
b.merkleLayers[0][field] = root[:]
|
|
||||||
b.recomputeRoot(int(field))
|
|
||||||
delete(b.dirtyFields, field)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FieldReferencesCount returns the reference count held by each field. This
|
|
||||||
// also includes the field trie held by each field.
|
|
||||||
func (b *BeaconState) FieldReferencesCount() map[string]uint64 {
|
|
||||||
refMap := make(map[string]uint64)
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
for i, f := range b.sharedFieldReferences {
|
|
||||||
refMap[i.String(b.Version())] = uint64(f.Refs())
|
|
||||||
}
|
|
||||||
for i, f := range b.stateFieldLeaves {
|
|
||||||
numOfRefs := uint64(f.FieldReference().Refs())
|
|
||||||
f.RLock()
|
|
||||||
if !f.Empty() {
|
|
||||||
refMap[i.String(b.Version())+"_trie"] = numOfRefs
|
|
||||||
}
|
|
||||||
f.RUnlock()
|
|
||||||
}
|
|
||||||
return refMap
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsNil checks if the state and the underlying proto
|
|
||||||
// object are nil.
|
|
||||||
func (b *BeaconState) IsNil() bool {
|
|
||||||
return b == nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BeaconState) rootSelector(ctx context.Context, field types.FieldIndex) ([32]byte, error) {
|
|
||||||
_, span := trace.StartSpan(ctx, "beaconState.rootSelector")
|
|
||||||
defer span.End()
|
|
||||||
span.AddAttributes(trace.StringAttribute("field", field.String(b.Version())))
|
|
||||||
|
|
||||||
hasher := hash.CustomSHA256Hasher()
|
|
||||||
switch field {
|
|
||||||
case genesisTime:
|
|
||||||
return ssz.Uint64Root(b.genesisTime), nil
|
|
||||||
case genesisValidatorsRoot:
|
|
||||||
return b.genesisValidatorsRoot, nil
|
|
||||||
case slot:
|
|
||||||
return ssz.Uint64Root(uint64(b.slot)), nil
|
|
||||||
case eth1DepositIndex:
|
|
||||||
return ssz.Uint64Root(b.eth1DepositIndex), nil
|
|
||||||
case fork:
|
|
||||||
return ssz.ForkRoot(b.fork)
|
|
||||||
case latestBlockHeader:
|
|
||||||
return stateutil.BlockHeaderRoot(b.latestBlockHeader)
|
|
||||||
case 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(blockRoots, b.blockRoots)
|
|
||||||
case 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(stateRoots, b.stateRoots)
|
|
||||||
case historicalRoots:
|
|
||||||
hRoots := make([][]byte, len(b.historicalRoots))
|
|
||||||
for i := range hRoots {
|
|
||||||
hRoots[i] = b.historicalRoots[i][:]
|
|
||||||
}
|
|
||||||
return ssz.ByteArrayRootWithLimit(hRoots, fieldparams.HistoricalRootsLength)
|
|
||||||
case eth1Data:
|
|
||||||
return stateutil.Eth1Root(hasher, b.eth1Data)
|
|
||||||
case eth1DataVotes:
|
|
||||||
if b.rebuildTrie[field] {
|
|
||||||
err := b.resetFieldTrie(
|
|
||||||
field,
|
|
||||||
b.eth1DataVotes,
|
|
||||||
fieldparams.Eth1DataVotesLength,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return [32]byte{}, err
|
|
||||||
}
|
|
||||||
delete(b.rebuildTrie, field)
|
|
||||||
return b.stateFieldLeaves[field].TrieRoot()
|
|
||||||
}
|
|
||||||
return b.recomputeFieldTrie(field, b.eth1DataVotes)
|
|
||||||
case validators:
|
|
||||||
if b.rebuildTrie[field] {
|
|
||||||
err := b.resetFieldTrie(field, b.validators, fieldparams.ValidatorRegistryLimit)
|
|
||||||
if err != nil {
|
|
||||||
return [32]byte{}, err
|
|
||||||
}
|
|
||||||
delete(b.rebuildTrie, validators)
|
|
||||||
return b.stateFieldLeaves[field].TrieRoot()
|
|
||||||
}
|
|
||||||
return b.recomputeFieldTrie(validators, b.validators)
|
|
||||||
case balances:
|
|
||||||
if b.rebuildTrie[field] {
|
|
||||||
maxBalCap := uint64(fieldparams.ValidatorRegistryLimit)
|
|
||||||
elemSize := uint64(8)
|
|
||||||
balLimit := (maxBalCap*elemSize + 31) / 32
|
|
||||||
err := b.resetFieldTrie(field, b.balances, balLimit)
|
|
||||||
if err != nil {
|
|
||||||
return [32]byte{}, err
|
|
||||||
}
|
|
||||||
delete(b.rebuildTrie, field)
|
|
||||||
return b.stateFieldLeaves[field].TrieRoot()
|
|
||||||
}
|
|
||||||
return b.recomputeFieldTrie(balances, b.balances)
|
|
||||||
case 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(randaoMixes, b.randaoMixes)
|
|
||||||
case slashings:
|
|
||||||
return ssz.SlashingsRoot(b.slashings)
|
|
||||||
case previousEpochAttestations:
|
|
||||||
if b.rebuildTrie[field] {
|
|
||||||
err := b.resetFieldTrie(
|
|
||||||
field,
|
|
||||||
b.previousEpochAttestations,
|
|
||||||
fieldparams.PreviousEpochAttestationsLength,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return [32]byte{}, err
|
|
||||||
}
|
|
||||||
delete(b.rebuildTrie, field)
|
|
||||||
return b.stateFieldLeaves[field].TrieRoot()
|
|
||||||
}
|
|
||||||
return b.recomputeFieldTrie(field, b.previousEpochAttestations)
|
|
||||||
case currentEpochAttestations:
|
|
||||||
if b.rebuildTrie[field] {
|
|
||||||
err := b.resetFieldTrie(
|
|
||||||
field,
|
|
||||||
b.currentEpochAttestations,
|
|
||||||
fieldparams.CurrentEpochAttestationsLength,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return [32]byte{}, err
|
|
||||||
}
|
|
||||||
delete(b.rebuildTrie, field)
|
|
||||||
return b.stateFieldLeaves[field].TrieRoot()
|
|
||||||
}
|
|
||||||
return b.recomputeFieldTrie(field, b.currentEpochAttestations)
|
|
||||||
case justificationBits:
|
|
||||||
return bytesutil.ToBytes32(b.justificationBits), nil
|
|
||||||
case previousJustifiedCheckpoint:
|
|
||||||
return ssz.CheckpointRoot(hasher, b.previousJustifiedCheckpoint)
|
|
||||||
case currentJustifiedCheckpoint:
|
|
||||||
return ssz.CheckpointRoot(hasher, b.currentJustifiedCheckpoint)
|
|
||||||
case finalizedCheckpoint:
|
|
||||||
return ssz.CheckpointRoot(hasher, b.finalizedCheckpoint)
|
|
||||||
}
|
|
||||||
return [32]byte{}, errors.New("invalid field index provided")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BeaconState) recomputeFieldTrie(index types.FieldIndex, elements interface{}) ([32]byte, error) {
|
|
||||||
fTrie := b.stateFieldLeaves[index]
|
|
||||||
// We can't lock the trie directly because the trie's variable gets reassigned,
|
|
||||||
// and therefore we would call Unlock() on a different object.
|
|
||||||
fTrieMutex := fTrie.RWMutex
|
|
||||||
if fTrie.FieldReference().Refs() > 1 {
|
|
||||||
fTrieMutex.Lock()
|
|
||||||
fTrie.FieldReference().MinusRef()
|
|
||||||
newTrie := fTrie.CopyTrie()
|
|
||||||
b.stateFieldLeaves[index] = newTrie
|
|
||||||
fTrie = newTrie
|
|
||||||
fTrieMutex.Unlock()
|
|
||||||
}
|
|
||||||
// remove duplicate indexes
|
|
||||||
b.dirtyIndices[index] = slice.SetUint64(b.dirtyIndices[index])
|
|
||||||
// sort indexes again
|
|
||||||
sort.Slice(b.dirtyIndices[index], func(i int, j int) bool {
|
|
||||||
return b.dirtyIndices[index][i] < b.dirtyIndices[index][j]
|
|
||||||
})
|
|
||||||
root, err := fTrie.RecomputeTrie(b.dirtyIndices[index], elements)
|
|
||||||
if err != nil {
|
|
||||||
return [32]byte{}, err
|
|
||||||
}
|
|
||||||
b.dirtyIndices[index] = []uint64{}
|
|
||||||
return root, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BeaconState) resetFieldTrie(index types.FieldIndex, elements interface{}, length uint64) error {
|
|
||||||
fTrie, err := fieldtrie.NewFieldTrie(index, fieldMap[index], elements, length)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
b.stateFieldLeaves[index] = fTrie
|
|
||||||
b.dirtyIndices[index] = []uint64{}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/types"
|
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Ensure type BeaconState below implements BeaconState interface.
|
|
||||||
var _ state.BeaconState = (*BeaconState)(nil)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
fieldMap = make(map[types.FieldIndex]types.DataType, params.BeaconConfig().BeaconStateFieldCount)
|
|
||||||
// Initialize the fixed sized arrays.
|
|
||||||
fieldMap[types.BlockRoots] = types.BasicArray
|
|
||||||
fieldMap[types.StateRoots] = types.BasicArray
|
|
||||||
fieldMap[types.RandaoMixes] = types.BasicArray
|
|
||||||
|
|
||||||
// Initialize the composite arrays.
|
|
||||||
fieldMap[types.Eth1DataVotes] = types.CompositeArray
|
|
||||||
fieldMap[types.Validators] = types.CompositeArray
|
|
||||||
fieldMap[types.PreviousEpochAttestations] = types.CompositeArray
|
|
||||||
fieldMap[types.CurrentEpochAttestations] = types.CompositeArray
|
|
||||||
fieldMap[types.Balances] = types.CompressedArray
|
|
||||||
}
|
|
||||||
|
|
||||||
// fieldMap keeps track of each field
|
|
||||||
// to its corresponding data type.
|
|
||||||
var fieldMap map[types.FieldIndex]types.DataType
|
|
||||||
|
|
||||||
// Field Aliases for values from the types package.
|
|
||||||
const (
|
|
||||||
genesisTime = types.GenesisTime
|
|
||||||
genesisValidatorsRoot = types.GenesisValidatorsRoot
|
|
||||||
slot = types.Slot
|
|
||||||
fork = types.Fork
|
|
||||||
latestBlockHeader = types.LatestBlockHeader
|
|
||||||
blockRoots = types.BlockRoots
|
|
||||||
stateRoots = types.StateRoots
|
|
||||||
historicalRoots = types.HistoricalRoots
|
|
||||||
eth1Data = types.Eth1Data
|
|
||||||
eth1DataVotes = types.Eth1DataVotes
|
|
||||||
eth1DepositIndex = types.Eth1DepositIndex
|
|
||||||
validators = types.Validators
|
|
||||||
balances = types.Balances
|
|
||||||
randaoMixes = types.RandaoMixes
|
|
||||||
slashings = types.Slashings
|
|
||||||
previousEpochAttestations = types.PreviousEpochAttestations
|
|
||||||
currentEpochAttestations = types.CurrentEpochAttestations
|
|
||||||
justificationBits = types.JustificationBits
|
|
||||||
previousJustifiedCheckpoint = types.PreviousJustifiedCheckpoint
|
|
||||||
currentJustifiedCheckpoint = types.CurrentJustifiedCheckpoint
|
|
||||||
finalizedCheckpoint = types.FinalizedCheckpoint
|
|
||||||
)
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CurrentEpochParticipation is not supported for phase 0 beacon state.
|
|
||||||
func (*BeaconState) CurrentEpochParticipation() ([]byte, error) {
|
|
||||||
return nil, errors.New("CurrentEpochParticipation is not supported for phase 0 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// PreviousEpochParticipation is not supported for phase 0 beacon state.
|
|
||||||
func (*BeaconState) PreviousEpochParticipation() ([]byte, error) {
|
|
||||||
return nil, errors.New("PreviousEpochParticipation is not supported for phase 0 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// InactivityScores is not supported for phase 0 beacon state.
|
|
||||||
func (*BeaconState) InactivityScores() ([]uint64, error) {
|
|
||||||
return nil, errors.New("InactivityScores is not supported for phase 0 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// CurrentSyncCommittee is not supported for phase 0 beacon state.
|
|
||||||
func (*BeaconState) CurrentSyncCommittee() (*ethpb.SyncCommittee, error) {
|
|
||||||
return nil, errors.New("CurrentSyncCommittee is not supported for phase 0 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// NextSyncCommittee is not supported for phase 0 beacon state.
|
|
||||||
func (*BeaconState) NextSyncCommittee() (*ethpb.SyncCommittee, error) {
|
|
||||||
return nil, errors.New("NextSyncCommittee is not supported for phase 0 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// LatestExecutionPayloadHeader is not supported for phase 0 beacon state.
|
|
||||||
func (*BeaconState) LatestExecutionPayloadHeader() (*ethpb.ExecutionPayloadHeader, error) {
|
|
||||||
return nil, errors.New("LatestExecutionPayloadHeader is not supported for phase 0 beacon state")
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AppendCurrentParticipationBits is not supported for phase 0 beacon state.
|
|
||||||
func (*BeaconState) AppendCurrentParticipationBits(_ byte) error {
|
|
||||||
return errors.New("AppendCurrentParticipationBits is not supported for phase 0 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendPreviousParticipationBits is not supported for phase 0 beacon state.
|
|
||||||
func (*BeaconState) AppendPreviousParticipationBits(_ byte) error {
|
|
||||||
return errors.New("AppendPreviousParticipationBits is not supported for phase 0 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendInactivityScore is not supported for phase 0 beacon state.
|
|
||||||
func (*BeaconState) AppendInactivityScore(_ uint64) error {
|
|
||||||
return errors.New("AppendInactivityScore is not supported for phase 0 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetCurrentSyncCommittee is not supported for phase 0 beacon state.
|
|
||||||
func (*BeaconState) SetCurrentSyncCommittee(_ *ethpb.SyncCommittee) error {
|
|
||||||
return errors.New("SetCurrentSyncCommittee is not supported for phase 0 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetNextSyncCommittee is not supported for phase 0 beacon state.
|
|
||||||
func (*BeaconState) SetNextSyncCommittee(_ *ethpb.SyncCommittee) error {
|
|
||||||
return errors.New("SetNextSyncCommittee is not supported for phase 0 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPreviousParticipationBits is not supported for phase 0 beacon state.
|
|
||||||
func (*BeaconState) SetPreviousParticipationBits(_ []byte) error {
|
|
||||||
return errors.New("SetPreviousParticipationBits is not supported for phase 0 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetCurrentParticipationBits is not supported for phase 0 beacon state.
|
|
||||||
func (*BeaconState) SetCurrentParticipationBits(_ []byte) error {
|
|
||||||
return errors.New("SetCurrentParticipationBits is not supported for phase 0 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// ModifyPreviousParticipationBits is not supported for phase 0 beacon state.
|
|
||||||
func (b *BeaconState) ModifyPreviousParticipationBits(mutator func(val []byte) ([]byte, error)) error {
|
|
||||||
return errors.New("ModifyPreviousParticipationBits is not supported for phase 0 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// ModifyCurrentParticipationBits is not supported for phase 0 beacon state.
|
|
||||||
func (b *BeaconState) ModifyCurrentParticipationBits(mutator func(val []byte) ([]byte, error)) error {
|
|
||||||
return errors.New("ModifyCurrentParticipationBits is not supported for phase 0 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetInactivityScores is not supported for phase 0 beacon state.
|
|
||||||
func (*BeaconState) SetInactivityScores(_ []uint64) error {
|
|
||||||
return errors.New("SetInactivityScores is not supported for phase 0 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetLatestExecutionPayloadHeader is not supported for phase 0 beacon state.
|
|
||||||
func (*BeaconState) SetLatestExecutionPayloadHeader(val *ethpb.ExecutionPayloadHeader) error {
|
|
||||||
return errors.New("SetLatestExecutionPayloadHeader is not supported for phase 0 beacon state")
|
|
||||||
}
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
|
||||||
load("//proto:ssz_proto_library.bzl", "ssz_proto_files")
|
|
||||||
load("//tools:ssz.bzl", "SSZ_DEPS", "ssz_gen_marshal")
|
|
||||||
|
|
||||||
go_library(
|
|
||||||
name = "go_default_library",
|
|
||||||
srcs = [
|
|
||||||
"deprecated_getters.go",
|
|
||||||
"deprecated_setters.go",
|
|
||||||
"field_roots.go",
|
|
||||||
"getters_block.go",
|
|
||||||
"getters_checkpoint.go",
|
|
||||||
"getters_eth1.go",
|
|
||||||
"getters_misc.go",
|
|
||||||
"getters_participation.go",
|
|
||||||
"getters_randao.go",
|
|
||||||
"getters_state.go",
|
|
||||||
"getters_sync_committee.go",
|
|
||||||
"getters_validator.go",
|
|
||||||
"proofs.go",
|
|
||||||
"setters_block.go",
|
|
||||||
"setters_checkpoint.go",
|
|
||||||
"setters_eth1.go",
|
|
||||||
"setters_misc.go",
|
|
||||||
"setters_participation.go",
|
|
||||||
"setters_randao.go",
|
|
||||||
"setters_state.go",
|
|
||||||
"setters_sync_committee.go",
|
|
||||||
"setters_validator.go",
|
|
||||||
"state_trie.go",
|
|
||||||
"types.go",
|
|
||||||
":ssz_generated_files", # keep
|
|
||||||
] + select({
|
|
||||||
"//config:mainnet": ["beacon_state_mainnet.go"],
|
|
||||||
"//config:minimal": ["beacon_state_minimal.go"],
|
|
||||||
}),
|
|
||||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/v2",
|
|
||||||
visibility = [
|
|
||||||
"//beacon-chain:__subpackages__",
|
|
||||||
"//proto/migration:__subpackages__",
|
|
||||||
"//testing/spectest:__subpackages__",
|
|
||||||
"//testing/util:__pkg__",
|
|
||||||
],
|
|
||||||
deps = [
|
|
||||||
"//beacon-chain/state:go_default_library",
|
|
||||||
"//beacon-chain/state/fieldtrie:go_default_library",
|
|
||||||
"//beacon-chain/state/state-native/custom-types:go_default_library",
|
|
||||||
"//beacon-chain/state/state-native/v1:go_default_library",
|
|
||||||
"//beacon-chain/state/stateutil:go_default_library",
|
|
||||||
"//beacon-chain/state/types:go_default_library",
|
|
||||||
"//config/fieldparams:go_default_library",
|
|
||||||
"//config/params:go_default_library",
|
|
||||||
"//consensus-types/primitives:go_default_library",
|
|
||||||
"//container/slice:go_default_library",
|
|
||||||
"//crypto/hash:go_default_library",
|
|
||||||
"//encoding/bytesutil:go_default_library",
|
|
||||||
"//encoding/ssz:go_default_library",
|
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
|
||||||
"//runtime/version:go_default_library",
|
|
||||||
"@com_github_ferranbt_fastssz//:go_default_library",
|
|
||||||
"@com_github_pkg_errors//:go_default_library",
|
|
||||||
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
|
||||||
"@io_opencensus_go//trace:go_default_library",
|
|
||||||
"@org_golang_google_protobuf//proto:go_default_library",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
go_test(
|
|
||||||
name = "go_default_test",
|
|
||||||
srcs = [
|
|
||||||
"deprecated_getters_test.go",
|
|
||||||
"deprecated_setters_test.go",
|
|
||||||
"getters_block_test.go",
|
|
||||||
"getters_test.go",
|
|
||||||
"getters_validator_test.go",
|
|
||||||
"proofs_test.go",
|
|
||||||
"setters_test.go",
|
|
||||||
"state_trie_test.go",
|
|
||||||
] + select({
|
|
||||||
"//config:mainnet": ["beacon_state_mainnet_test.go"],
|
|
||||||
"//config:minimal": ["beacon_state_minimal_test.go"],
|
|
||||||
}),
|
|
||||||
embed = [":go_default_library"],
|
|
||||||
deps = [
|
|
||||||
"//beacon-chain/state:go_default_library",
|
|
||||||
"//beacon-chain/state/stateutil:go_default_library",
|
|
||||||
"//beacon-chain/state/testing:go_default_library",
|
|
||||||
"//beacon-chain/state/types:go_default_library",
|
|
||||||
"//beacon-chain/state/v2:go_default_library",
|
|
||||||
"//config/fieldparams:go_default_library",
|
|
||||||
"//config/params:go_default_library",
|
|
||||||
"//consensus-types/primitives:go_default_library",
|
|
||||||
"//container/trie:go_default_library",
|
|
||||||
"//crypto/bls:go_default_library",
|
|
||||||
"//encoding/bytesutil:go_default_library",
|
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
|
||||||
"//testing/assert:go_default_library",
|
|
||||||
"//testing/require:go_default_library",
|
|
||||||
"//testing/util:go_default_library",
|
|
||||||
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
ssz_gen_marshal(
|
|
||||||
name = "ssz_generated_files",
|
|
||||||
srcs = select({
|
|
||||||
"//config:mainnet": ["beacon_state_mainnet.go"],
|
|
||||||
"//config:minimal": ["beacon_state_minimal.go"],
|
|
||||||
}),
|
|
||||||
includes = [
|
|
||||||
"//beacon-chain/state/state-native/custom-types:go_default_library",
|
|
||||||
"//config/fieldparams:go_default_library",
|
|
||||||
"//consensus-types/primitives:go_default_library",
|
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
|
||||||
],
|
|
||||||
objs = [
|
|
||||||
"BeaconState[no-htr]",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
//go:build !minimal
|
|
||||||
// +build !minimal
|
|
||||||
|
|
||||||
package v2
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/prysmaticlabs/go-bitfield"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/fieldtrie"
|
|
||||||
customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/types"
|
|
||||||
eth2types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// BeaconState defines a struct containing utilities for the eth2 chain state, defining
|
|
||||||
// getters and setters for its respective values and helpful functions such as HashTreeRoot().
|
|
||||||
type BeaconState struct {
|
|
||||||
genesisTime uint64 `ssz-gen:"true"`
|
|
||||||
genesisValidatorsRoot customtypes.Byte32 `ssz-gen:"true" ssz-size:"32"`
|
|
||||||
slot eth2types.Slot `ssz-gen:"true"`
|
|
||||||
fork *ethpb.Fork `ssz-gen:"true"`
|
|
||||||
latestBlockHeader *ethpb.BeaconBlockHeader `ssz-gen:"true"`
|
|
||||||
blockRoots *customtypes.BlockRoots `ssz-gen:"true" ssz-size:"8192,32"`
|
|
||||||
stateRoots *customtypes.StateRoots `ssz-gen:"true" ssz-size:"8192,32"`
|
|
||||||
historicalRoots customtypes.HistoricalRoots `ssz-gen:"true" ssz-size:"?,32" ssz-max:"16777216"`
|
|
||||||
eth1Data *ethpb.Eth1Data `ssz-gen:"true"`
|
|
||||||
eth1DataVotes []*ethpb.Eth1Data `ssz-gen:"true" ssz-max:"2048"`
|
|
||||||
eth1DepositIndex uint64 `ssz-gen:"true"`
|
|
||||||
validators []*ethpb.Validator `ssz-gen:"true" ssz-max:"1099511627776"`
|
|
||||||
balances []uint64 `ssz-gen:"true" ssz-max:"1099511627776"`
|
|
||||||
randaoMixes *customtypes.RandaoMixes `ssz-gen:"true" ssz-size:"65536,32"`
|
|
||||||
slashings []uint64 `ssz-gen:"true" ssz-size:"8192"`
|
|
||||||
previousEpochParticipation []byte `ssz-gen:"true" ssz-max:"1099511627776"`
|
|
||||||
currentEpochParticipation []byte `ssz-gen:"true" ssz-max:"1099511627776"`
|
|
||||||
justificationBits bitfield.Bitvector4 `ssz-gen:"true" ssz-size:"1"`
|
|
||||||
previousJustifiedCheckpoint *ethpb.Checkpoint `ssz-gen:"true"`
|
|
||||||
currentJustifiedCheckpoint *ethpb.Checkpoint `ssz-gen:"true"`
|
|
||||||
finalizedCheckpoint *ethpb.Checkpoint `ssz-gen:"true"`
|
|
||||||
inactivityScores []uint64 `ssz-gen:"true" ssz-max:"1099511627776"`
|
|
||||||
currentSyncCommittee *ethpb.SyncCommittee `ssz-gen:"true"`
|
|
||||||
nextSyncCommittee *ethpb.SyncCommittee `ssz-gen:"true"`
|
|
||||||
|
|
||||||
lock sync.RWMutex
|
|
||||||
dirtyFields map[types.FieldIndex]bool
|
|
||||||
dirtyIndices map[types.FieldIndex][]uint64
|
|
||||||
stateFieldLeaves map[types.FieldIndex]*fieldtrie.FieldTrie
|
|
||||||
rebuildTrie map[types.FieldIndex]bool
|
|
||||||
valMapHandler *stateutil.ValidatorMapHandler
|
|
||||||
merkleLayers [][][]byte
|
|
||||||
sharedFieldReferences map[types.FieldIndex]*stateutil.Reference
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
//go:build !minimal
|
|
||||||
// +build !minimal
|
|
||||||
|
|
||||||
package v2
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestMainnetSszValuesAgainstFieldParams(t *testing.T) {
|
|
||||||
// Casting needed to avoid lock copy analyzer issue.
|
|
||||||
bs := (interface{})(BeaconState{})
|
|
||||||
bsType := reflect.TypeOf(bs)
|
|
||||||
|
|
||||||
f, ok := bsType.FieldByName("genesisValidatorsRoot")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v := f.Tag.Get("ssz-size")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.RootLength), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("blockRoots")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-size")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.BlockRootsLength)+","+strconv.Itoa(fieldparams.RootLength), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("stateRoots")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-size")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.StateRootsLength)+","+strconv.Itoa(fieldparams.RootLength), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("historicalRoots")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-size")
|
|
||||||
assert.Equal(t, "?,"+strconv.Itoa(fieldparams.RootLength), v)
|
|
||||||
v = f.Tag.Get("ssz-max")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.HistoricalRootsLength), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("eth1DataVotes")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-max")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.Eth1DataVotesLength), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("validators")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-max")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.ValidatorRegistryLimit), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("balances")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-max")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.ValidatorRegistryLimit), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("randaoMixes")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-size")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.RandaoMixesLength)+","+strconv.Itoa(fieldparams.RootLength), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("slashings")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-size")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.SlashingsLength), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("previousEpochParticipation")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-max")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.ValidatorRegistryLimit), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("currentEpochParticipation")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-max")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.ValidatorRegistryLimit), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("justificationBits")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-size")
|
|
||||||
assert.Equal(t, "1", v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("inactivityScores")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-max")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.ValidatorRegistryLimit), v)
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
//go:build minimal
|
|
||||||
// +build minimal
|
|
||||||
|
|
||||||
package v2
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/prysmaticlabs/go-bitfield"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/fieldtrie"
|
|
||||||
customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/types"
|
|
||||||
eth2types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// BeaconState defines a struct containing utilities for the eth2 chain state, defining
|
|
||||||
// getters and setters for its respective values and helpful functions such as HashTreeRoot().
|
|
||||||
type BeaconState struct {
|
|
||||||
genesisTime uint64 `ssz-gen:"true"`
|
|
||||||
genesisValidatorsRoot customtypes.Byte32 `ssz-gen:"true" ssz-size:"32"`
|
|
||||||
slot eth2types.Slot `ssz-gen:"true"`
|
|
||||||
fork *ethpb.Fork `ssz-gen:"true"`
|
|
||||||
latestBlockHeader *ethpb.BeaconBlockHeader `ssz-gen:"true"`
|
|
||||||
blockRoots *customtypes.BlockRoots `ssz-gen:"true" ssz-size:"64,32"`
|
|
||||||
stateRoots *customtypes.StateRoots `ssz-gen:"true" ssz-size:"64,32"`
|
|
||||||
historicalRoots customtypes.HistoricalRoots `ssz-gen:"true" ssz-size:"?,32" ssz-max:"16777216"`
|
|
||||||
eth1Data *ethpb.Eth1Data `ssz-gen:"true"`
|
|
||||||
eth1DataVotes []*ethpb.Eth1Data `ssz-gen:"true" ssz-max:"32"`
|
|
||||||
eth1DepositIndex uint64 `ssz-gen:"true"`
|
|
||||||
validators []*ethpb.Validator `ssz-gen:"true" ssz-max:"1099511627776"`
|
|
||||||
balances []uint64 `ssz-gen:"true" ssz-max:"1099511627776"`
|
|
||||||
randaoMixes *customtypes.RandaoMixes `ssz-gen:"true" ssz-size:"64,32"`
|
|
||||||
slashings []uint64 `ssz-gen:"true" ssz-size:"64"`
|
|
||||||
previousEpochParticipation []byte `ssz-gen:"true" ssz-max:"1099511627776"`
|
|
||||||
currentEpochParticipation []byte `ssz-gen:"true" ssz-max:"1099511627776"`
|
|
||||||
justificationBits bitfield.Bitvector4 `ssz-gen:"true" ssz-size:"1"`
|
|
||||||
previousJustifiedCheckpoint *ethpb.Checkpoint `ssz-gen:"true"`
|
|
||||||
currentJustifiedCheckpoint *ethpb.Checkpoint `ssz-gen:"true"`
|
|
||||||
finalizedCheckpoint *ethpb.Checkpoint `ssz-gen:"true"`
|
|
||||||
inactivityScores []uint64 `ssz-gen:"true" ssz-max:"1099511627776"`
|
|
||||||
currentSyncCommittee *ethpb.SyncCommittee `ssz-gen:"true"`
|
|
||||||
nextSyncCommittee *ethpb.SyncCommittee `ssz-gen:"true"`
|
|
||||||
|
|
||||||
lock sync.RWMutex
|
|
||||||
dirtyFields map[types.FieldIndex]bool
|
|
||||||
dirtyIndices map[types.FieldIndex][]uint64
|
|
||||||
stateFieldLeaves map[types.FieldIndex]*fieldtrie.FieldTrie
|
|
||||||
rebuildTrie map[types.FieldIndex]bool
|
|
||||||
valMapHandler *stateutil.ValidatorMapHandler
|
|
||||||
merkleLayers [][][]byte
|
|
||||||
sharedFieldReferences map[types.FieldIndex]*stateutil.Reference
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
//go:build minimal
|
|
||||||
// +build minimal
|
|
||||||
|
|
||||||
package v2
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestMinimalSszValuesAgainstFieldParams(t *testing.T) {
|
|
||||||
// Casting needed to avoid lock copy analyzer issue.
|
|
||||||
bs := (interface{})(BeaconState{})
|
|
||||||
bsType := reflect.TypeOf(bs)
|
|
||||||
|
|
||||||
f, ok := bsType.FieldByName("genesisValidatorsRoot")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v := f.Tag.Get("ssz-size")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.RootLength), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("blockRoots")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-size")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.BlockRootsLength)+","+strconv.Itoa(fieldparams.RootLength), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("stateRoots")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-size")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.StateRootsLength)+","+strconv.Itoa(fieldparams.RootLength), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("historicalRoots")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-size")
|
|
||||||
assert.Equal(t, "?,"+strconv.Itoa(fieldparams.RootLength), v)
|
|
||||||
v = f.Tag.Get("ssz-max")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.HistoricalRootsLength), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("eth1DataVotes")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-max")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.Eth1DataVotesLength), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("validators")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-max")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.ValidatorRegistryLimit), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("balances")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-max")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.ValidatorRegistryLimit), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("randaoMixes")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-size")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.RandaoMixesLength)+","+strconv.Itoa(fieldparams.RootLength), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("slashings")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-size")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.SlashingsLength), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("previousEpochParticipation")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-max")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.ValidatorRegistryLimit), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("currentEpochParticipation")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-max")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.ValidatorRegistryLimit), v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("justificationBits")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-size")
|
|
||||||
assert.Equal(t, "1", v)
|
|
||||||
|
|
||||||
f, ok = bsType.FieldByName("inactivityScores")
|
|
||||||
require.Equal(t, true, ok, "Required field not found")
|
|
||||||
v = f.Tag.Get("ssz-max")
|
|
||||||
assert.Equal(t, strconv.Itoa(fieldparams.ValidatorRegistryLimit), v)
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package v2
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PreviousEpochAttestations is not supported for HF1 beacon state.
|
|
||||||
func (*BeaconState) PreviousEpochAttestations() ([]*ethpb.PendingAttestation, error) {
|
|
||||||
return nil, errors.New("PreviousEpochAttestations is not supported for hard fork 1 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// CurrentEpochAttestations is not supported for HF1 beacon state.
|
|
||||||
func (*BeaconState) CurrentEpochAttestations() ([]*ethpb.PendingAttestation, error) {
|
|
||||||
return nil, errors.New("CurrentEpochAttestations is not supported for hard fork 1 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// LatestExecutionPayloadHeader is not supported for hard fork 1 beacon state.
|
|
||||||
func (*BeaconState) LatestExecutionPayloadHeader() (*ethpb.ExecutionPayloadHeader, error) {
|
|
||||||
return nil, errors.New("LatestExecutionPayloadHeader is not supported for hard fork 1 beacon state")
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
package v2
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestBeaconState_CurrentEpochAttestations(t *testing.T) {
|
|
||||||
s := &BeaconState{}
|
|
||||||
_, err := s.CurrentEpochAttestations()
|
|
||||||
require.ErrorContains(t, "CurrentEpochAttestations is not supported for hard fork 1 beacon state", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_PreviousEpochAttestations(t *testing.T) {
|
|
||||||
s := &BeaconState{}
|
|
||||||
_, err := s.PreviousEpochAttestations()
|
|
||||||
require.ErrorContains(t, "PreviousEpochAttestations is not supported for hard fork 1 beacon state", err)
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
package v2
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SetPreviousEpochAttestations is not supported for HF1 beacon state.
|
|
||||||
func (*BeaconState) SetPreviousEpochAttestations(_ []*ethpb.PendingAttestation) error {
|
|
||||||
return errors.New("SetPreviousEpochAttestations is not supported for hard fork 1 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetCurrentEpochAttestations is not supported for HF1 beacon state.
|
|
||||||
func (*BeaconState) SetCurrentEpochAttestations(_ []*ethpb.PendingAttestation) error {
|
|
||||||
return errors.New("SetCurrentEpochAttestations is not supported for hard fork 1 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendCurrentEpochAttestations is not supported for HF1 beacon state.
|
|
||||||
func (*BeaconState) AppendCurrentEpochAttestations(_ *ethpb.PendingAttestation) error {
|
|
||||||
return errors.New("AppendCurrentEpochAttestations is not supported for hard fork 1 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendPreviousEpochAttestations is not supported for HF1 beacon state.
|
|
||||||
func (*BeaconState) AppendPreviousEpochAttestations(_ *ethpb.PendingAttestation) error {
|
|
||||||
return errors.New("AppendPreviousEpochAttestations is not supported for hard fork 1 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// RotateAttestations is not supported for HF1 beacon state.
|
|
||||||
func (*BeaconState) RotateAttestations() error {
|
|
||||||
return errors.New("RotateAttestations is not supported for hard fork 1 beacon state")
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetLatestExecutionPayloadHeader is not supported for hard fork 1 beacon state.
|
|
||||||
func (*BeaconState) SetLatestExecutionPayloadHeader(_ *ethpb.ExecutionPayloadHeader) error {
|
|
||||||
return errors.New("SetLatestExecutionPayloadHeader is not supported for hard fork 1 beacon state")
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package v2
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestBeaconState_AppendCurrentEpochAttestations(t *testing.T) {
|
|
||||||
s := &BeaconState{}
|
|
||||||
require.ErrorContains(t, "AppendCurrentEpochAttestations is not supported for hard fork 1 beacon state", s.AppendCurrentEpochAttestations(nil))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_AppendPreviousEpochAttestations(t *testing.T) {
|
|
||||||
s := &BeaconState{}
|
|
||||||
require.ErrorContains(t, "AppendPreviousEpochAttestations is not supported for hard fork 1 beacon state", s.AppendPreviousEpochAttestations(nil))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_SetCurrentEpochAttestations(t *testing.T) {
|
|
||||||
s := &BeaconState{}
|
|
||||||
require.ErrorContains(t, "SetCurrentEpochAttestations is not supported for hard fork 1 beacon state", s.SetCurrentEpochAttestations(nil))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_SetPreviousEpochAttestations(t *testing.T) {
|
|
||||||
s := &BeaconState{}
|
|
||||||
require.ErrorContains(t, "SetPreviousEpochAttestations is not supported for hard fork 1 beacon state", s.SetPreviousEpochAttestations(nil))
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
package v2
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// computeFieldRoots returns the hash tree root computations of every field in
|
|
||||||
// the beacon state as a list of 32 byte roots.
|
|
||||||
func computeFieldRoots(ctx context.Context, state *ethpb.BeaconStateAltair) ([][]byte, error) {
|
|
||||||
return stateutil.ComputeFieldRootsWithHasherAltair(ctx, state)
|
|
||||||
}
|
|
||||||
@@ -1,505 +0,0 @@
|
|||||||
// Code generated by fastssz. DO NOT EDIT.
|
|
||||||
// Hash: 62b465df1ba19e36b9e8f7b16a383284350eb588bc459b4dd80f1b48ce9d7d64
|
|
||||||
package v2
|
|
||||||
|
|
||||||
import (
|
|
||||||
ssz "github.com/ferranbt/fastssz"
|
|
||||||
eth2types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MarshalSSZ ssz marshals the BeaconState object
|
|
||||||
func (b *BeaconState) MarshalSSZ() ([]byte, error) {
|
|
||||||
return ssz.MarshalSSZ(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalSSZTo ssz marshals the BeaconState object to a target array
|
|
||||||
func (b *BeaconState) MarshalSSZTo(buf []byte) (dst []byte, err error) {
|
|
||||||
dst = buf
|
|
||||||
offset := int(2736629)
|
|
||||||
|
|
||||||
// Field (0) 'genesisTime'
|
|
||||||
dst = ssz.MarshalUint64(dst, b.genesisTime)
|
|
||||||
|
|
||||||
// Field (1) 'genesisValidatorsRoot'
|
|
||||||
dst = append(dst, b.genesisValidatorsRoot[:]...)
|
|
||||||
|
|
||||||
// Field (2) 'slot'
|
|
||||||
dst = ssz.MarshalUint64(dst, uint64(b.slot))
|
|
||||||
|
|
||||||
// Field (3) 'fork'
|
|
||||||
if b.fork == nil {
|
|
||||||
b.fork = new(ethpb.Fork)
|
|
||||||
}
|
|
||||||
if dst, err = b.fork.MarshalSSZTo(dst); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (4) 'latestBlockHeader'
|
|
||||||
if b.latestBlockHeader == nil {
|
|
||||||
b.latestBlockHeader = new(ethpb.BeaconBlockHeader)
|
|
||||||
}
|
|
||||||
if dst, err = b.latestBlockHeader.MarshalSSZTo(dst); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (5) 'blockRoots'
|
|
||||||
for ii := 0; ii < 8192; ii++ {
|
|
||||||
dst = append(dst, b.blockRoots[ii][:]...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (6) 'stateRoots'
|
|
||||||
for ii := 0; ii < 8192; ii++ {
|
|
||||||
dst = append(dst, b.stateRoots[ii][:]...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset (7) 'historicalRoots'
|
|
||||||
dst = ssz.WriteOffset(dst, offset)
|
|
||||||
offset += len(b.historicalRoots) * 32
|
|
||||||
|
|
||||||
// Field (8) 'eth1Data'
|
|
||||||
if b.eth1Data == nil {
|
|
||||||
b.eth1Data = new(ethpb.Eth1Data)
|
|
||||||
}
|
|
||||||
if dst, err = b.eth1Data.MarshalSSZTo(dst); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset (9) 'eth1DataVotes'
|
|
||||||
dst = ssz.WriteOffset(dst, offset)
|
|
||||||
offset += len(b.eth1DataVotes) * 72
|
|
||||||
|
|
||||||
// Field (10) 'eth1DepositIndex'
|
|
||||||
dst = ssz.MarshalUint64(dst, b.eth1DepositIndex)
|
|
||||||
|
|
||||||
// Offset (11) 'validators'
|
|
||||||
dst = ssz.WriteOffset(dst, offset)
|
|
||||||
offset += len(b.validators) * 121
|
|
||||||
|
|
||||||
// Offset (12) 'balances'
|
|
||||||
dst = ssz.WriteOffset(dst, offset)
|
|
||||||
offset += len(b.balances) * 8
|
|
||||||
|
|
||||||
// Field (13) 'randaoMixes'
|
|
||||||
for ii := 0; ii < 65536; ii++ {
|
|
||||||
dst = append(dst, b.randaoMixes[ii][:]...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (14) 'slashings'
|
|
||||||
if len(b.slashings) != 8192 {
|
|
||||||
err = ssz.ErrVectorLength
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for ii := 0; ii < 8192; ii++ {
|
|
||||||
dst = ssz.MarshalUint64(dst, b.slashings[ii])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset (15) 'previousEpochParticipation'
|
|
||||||
dst = ssz.WriteOffset(dst, offset)
|
|
||||||
offset += len(b.previousEpochParticipation)
|
|
||||||
|
|
||||||
// Offset (16) 'currentEpochParticipation'
|
|
||||||
dst = ssz.WriteOffset(dst, offset)
|
|
||||||
offset += len(b.currentEpochParticipation)
|
|
||||||
|
|
||||||
// Field (17) 'justificationBits'
|
|
||||||
if len(b.justificationBits) != 1 {
|
|
||||||
err = ssz.ErrBytesLength
|
|
||||||
return
|
|
||||||
}
|
|
||||||
dst = append(dst, b.justificationBits...)
|
|
||||||
|
|
||||||
// Field (18) 'previousJustifiedCheckpoint'
|
|
||||||
if b.previousJustifiedCheckpoint == nil {
|
|
||||||
b.previousJustifiedCheckpoint = new(ethpb.Checkpoint)
|
|
||||||
}
|
|
||||||
if dst, err = b.previousJustifiedCheckpoint.MarshalSSZTo(dst); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (19) 'currentJustifiedCheckpoint'
|
|
||||||
if b.currentJustifiedCheckpoint == nil {
|
|
||||||
b.currentJustifiedCheckpoint = new(ethpb.Checkpoint)
|
|
||||||
}
|
|
||||||
if dst, err = b.currentJustifiedCheckpoint.MarshalSSZTo(dst); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (20) 'finalizedCheckpoint'
|
|
||||||
if b.finalizedCheckpoint == nil {
|
|
||||||
b.finalizedCheckpoint = new(ethpb.Checkpoint)
|
|
||||||
}
|
|
||||||
if dst, err = b.finalizedCheckpoint.MarshalSSZTo(dst); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset (21) 'inactivityScores'
|
|
||||||
dst = ssz.WriteOffset(dst, offset)
|
|
||||||
offset += len(b.inactivityScores) * 8
|
|
||||||
|
|
||||||
// Field (22) 'currentSyncCommittee'
|
|
||||||
if b.currentSyncCommittee == nil {
|
|
||||||
b.currentSyncCommittee = new(ethpb.SyncCommittee)
|
|
||||||
}
|
|
||||||
if dst, err = b.currentSyncCommittee.MarshalSSZTo(dst); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (23) 'nextSyncCommittee'
|
|
||||||
if b.nextSyncCommittee == nil {
|
|
||||||
b.nextSyncCommittee = new(ethpb.SyncCommittee)
|
|
||||||
}
|
|
||||||
if dst, err = b.nextSyncCommittee.MarshalSSZTo(dst); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (7) 'historicalRoots'
|
|
||||||
if len(b.historicalRoots) > 16777216 {
|
|
||||||
err = ssz.ErrListTooBig
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for ii := 0; ii < len(b.historicalRoots); ii++ {
|
|
||||||
dst = append(dst, b.historicalRoots[ii][:]...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (9) 'eth1DataVotes'
|
|
||||||
if len(b.eth1DataVotes) > 2048 {
|
|
||||||
err = ssz.ErrListTooBig
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for ii := 0; ii < len(b.eth1DataVotes); ii++ {
|
|
||||||
if dst, err = b.eth1DataVotes[ii].MarshalSSZTo(dst); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (11) 'validators'
|
|
||||||
if len(b.validators) > 1099511627776 {
|
|
||||||
err = ssz.ErrListTooBig
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for ii := 0; ii < len(b.validators); ii++ {
|
|
||||||
if dst, err = b.validators[ii].MarshalSSZTo(dst); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (12) 'balances'
|
|
||||||
if len(b.balances) > 1099511627776 {
|
|
||||||
err = ssz.ErrListTooBig
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for ii := 0; ii < len(b.balances); ii++ {
|
|
||||||
dst = ssz.MarshalUint64(dst, b.balances[ii])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (15) 'previousEpochParticipation'
|
|
||||||
if len(b.previousEpochParticipation) > 1099511627776 {
|
|
||||||
err = ssz.ErrBytesLength
|
|
||||||
return
|
|
||||||
}
|
|
||||||
dst = append(dst, b.previousEpochParticipation...)
|
|
||||||
|
|
||||||
// Field (16) 'currentEpochParticipation'
|
|
||||||
if len(b.currentEpochParticipation) > 1099511627776 {
|
|
||||||
err = ssz.ErrBytesLength
|
|
||||||
return
|
|
||||||
}
|
|
||||||
dst = append(dst, b.currentEpochParticipation...)
|
|
||||||
|
|
||||||
// Field (21) 'inactivityScores'
|
|
||||||
if len(b.inactivityScores) > 1099511627776 {
|
|
||||||
err = ssz.ErrListTooBig
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for ii := 0; ii < len(b.inactivityScores); ii++ {
|
|
||||||
dst = ssz.MarshalUint64(dst, b.inactivityScores[ii])
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalSSZ ssz unmarshals the BeaconState object
|
|
||||||
func (b *BeaconState) UnmarshalSSZ(buf []byte) error {
|
|
||||||
var err error
|
|
||||||
size := uint64(len(buf))
|
|
||||||
if size < 2736629 {
|
|
||||||
return ssz.ErrSize
|
|
||||||
}
|
|
||||||
|
|
||||||
tail := buf
|
|
||||||
var o7, o9, o11, o12, o15, o16, o21 uint64
|
|
||||||
|
|
||||||
// Field (0) 'genesisTime'
|
|
||||||
b.genesisTime = ssz.UnmarshallUint64(buf[0:8])
|
|
||||||
|
|
||||||
// Field (1) 'genesisValidatorsRoot'
|
|
||||||
copy(b.genesisValidatorsRoot[:], buf[8:40])
|
|
||||||
|
|
||||||
// Field (2) 'slot'
|
|
||||||
b.slot = eth2types.Slot(ssz.UnmarshallUint64(buf[40:48]))
|
|
||||||
|
|
||||||
// Field (3) 'fork'
|
|
||||||
if b.fork == nil {
|
|
||||||
b.fork = new(ethpb.Fork)
|
|
||||||
}
|
|
||||||
if err = b.fork.UnmarshalSSZ(buf[48:64]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (4) 'latestBlockHeader'
|
|
||||||
if b.latestBlockHeader == nil {
|
|
||||||
b.latestBlockHeader = new(ethpb.BeaconBlockHeader)
|
|
||||||
}
|
|
||||||
if err = b.latestBlockHeader.UnmarshalSSZ(buf[64:176]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (5) 'blockRoots'
|
|
||||||
|
|
||||||
for ii := 0; ii < 8192; ii++ {
|
|
||||||
copy(b.blockRoots[ii][:], buf[176:262320][ii*32:(ii+1)*32])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (6) 'stateRoots'
|
|
||||||
|
|
||||||
for ii := 0; ii < 8192; ii++ {
|
|
||||||
copy(b.stateRoots[ii][:], buf[262320:524464][ii*32:(ii+1)*32])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset (7) 'historicalRoots'
|
|
||||||
if o7 = ssz.ReadOffset(buf[524464:524468]); o7 > size {
|
|
||||||
return ssz.ErrOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
if o7 < 2736629 {
|
|
||||||
return ssz.ErrInvalidVariableOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (8) 'eth1Data'
|
|
||||||
if b.eth1Data == nil {
|
|
||||||
b.eth1Data = new(ethpb.Eth1Data)
|
|
||||||
}
|
|
||||||
if err = b.eth1Data.UnmarshalSSZ(buf[524468:524540]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset (9) 'eth1DataVotes'
|
|
||||||
if o9 = ssz.ReadOffset(buf[524540:524544]); o9 > size || o7 > o9 {
|
|
||||||
return ssz.ErrOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (10) 'eth1DepositIndex'
|
|
||||||
b.eth1DepositIndex = ssz.UnmarshallUint64(buf[524544:524552])
|
|
||||||
|
|
||||||
// Offset (11) 'validators'
|
|
||||||
if o11 = ssz.ReadOffset(buf[524552:524556]); o11 > size || o9 > o11 {
|
|
||||||
return ssz.ErrOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset (12) 'balances'
|
|
||||||
if o12 = ssz.ReadOffset(buf[524556:524560]); o12 > size || o11 > o12 {
|
|
||||||
return ssz.ErrOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (13) 'randaoMixes'
|
|
||||||
|
|
||||||
for ii := 0; ii < 65536; ii++ {
|
|
||||||
copy(b.randaoMixes[ii][:], buf[524560:2621712][ii*32:(ii+1)*32])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (14) 'slashings'
|
|
||||||
b.slashings = ssz.ExtendUint64(b.slashings, 8192)
|
|
||||||
for ii := 0; ii < 8192; ii++ {
|
|
||||||
b.slashings[ii] = ssz.UnmarshallUint64(buf[2621712:2687248][ii*8 : (ii+1)*8])
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset (15) 'previousEpochParticipation'
|
|
||||||
if o15 = ssz.ReadOffset(buf[2687248:2687252]); o15 > size || o12 > o15 {
|
|
||||||
return ssz.ErrOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset (16) 'currentEpochParticipation'
|
|
||||||
if o16 = ssz.ReadOffset(buf[2687252:2687256]); o16 > size || o15 > o16 {
|
|
||||||
return ssz.ErrOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (17) 'justificationBits'
|
|
||||||
if cap(b.justificationBits) == 0 {
|
|
||||||
b.justificationBits = make([]byte, 0, len(buf[2687256:2687257]))
|
|
||||||
}
|
|
||||||
b.justificationBits = append(b.justificationBits, buf[2687256:2687257]...)
|
|
||||||
|
|
||||||
// Field (18) 'previousJustifiedCheckpoint'
|
|
||||||
if b.previousJustifiedCheckpoint == nil {
|
|
||||||
b.previousJustifiedCheckpoint = new(ethpb.Checkpoint)
|
|
||||||
}
|
|
||||||
if err = b.previousJustifiedCheckpoint.UnmarshalSSZ(buf[2687257:2687297]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (19) 'currentJustifiedCheckpoint'
|
|
||||||
if b.currentJustifiedCheckpoint == nil {
|
|
||||||
b.currentJustifiedCheckpoint = new(ethpb.Checkpoint)
|
|
||||||
}
|
|
||||||
if err = b.currentJustifiedCheckpoint.UnmarshalSSZ(buf[2687297:2687337]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (20) 'finalizedCheckpoint'
|
|
||||||
if b.finalizedCheckpoint == nil {
|
|
||||||
b.finalizedCheckpoint = new(ethpb.Checkpoint)
|
|
||||||
}
|
|
||||||
if err = b.finalizedCheckpoint.UnmarshalSSZ(buf[2687337:2687377]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset (21) 'inactivityScores'
|
|
||||||
if o21 = ssz.ReadOffset(buf[2687377:2687381]); o21 > size || o16 > o21 {
|
|
||||||
return ssz.ErrOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (22) 'currentSyncCommittee'
|
|
||||||
if b.currentSyncCommittee == nil {
|
|
||||||
b.currentSyncCommittee = new(ethpb.SyncCommittee)
|
|
||||||
}
|
|
||||||
if err = b.currentSyncCommittee.UnmarshalSSZ(buf[2687381:2712005]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (23) 'nextSyncCommittee'
|
|
||||||
if b.nextSyncCommittee == nil {
|
|
||||||
b.nextSyncCommittee = new(ethpb.SyncCommittee)
|
|
||||||
}
|
|
||||||
if err = b.nextSyncCommittee.UnmarshalSSZ(buf[2712005:2736629]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (7) 'historicalRoots'
|
|
||||||
{
|
|
||||||
buf = tail[o7:o9]
|
|
||||||
num, err := ssz.DivideInt2(len(buf), 32, 16777216)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
b.historicalRoots = make([][32]byte, num)
|
|
||||||
for ii := 0; ii < num; ii++ {
|
|
||||||
copy(b.historicalRoots[ii][:], buf[ii*32:(ii+1)*32])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (9) 'eth1DataVotes'
|
|
||||||
{
|
|
||||||
buf = tail[o9:o11]
|
|
||||||
num, err := ssz.DivideInt2(len(buf), 72, 2048)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
b.eth1DataVotes = make([]*ethpb.Eth1Data, num)
|
|
||||||
for ii := 0; ii < num; ii++ {
|
|
||||||
if b.eth1DataVotes[ii] == nil {
|
|
||||||
b.eth1DataVotes[ii] = new(ethpb.Eth1Data)
|
|
||||||
}
|
|
||||||
if err = b.eth1DataVotes[ii].UnmarshalSSZ(buf[ii*72 : (ii+1)*72]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (11) 'validators'
|
|
||||||
{
|
|
||||||
buf = tail[o11:o12]
|
|
||||||
num, err := ssz.DivideInt2(len(buf), 121, 1099511627776)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
b.validators = make([]*ethpb.Validator, num)
|
|
||||||
for ii := 0; ii < num; ii++ {
|
|
||||||
if b.validators[ii] == nil {
|
|
||||||
b.validators[ii] = new(ethpb.Validator)
|
|
||||||
}
|
|
||||||
if err = b.validators[ii].UnmarshalSSZ(buf[ii*121 : (ii+1)*121]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (12) 'balances'
|
|
||||||
{
|
|
||||||
buf = tail[o12:o15]
|
|
||||||
num, err := ssz.DivideInt2(len(buf), 8, 1099511627776)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
b.balances = ssz.ExtendUint64(b.balances, num)
|
|
||||||
for ii := 0; ii < num; ii++ {
|
|
||||||
b.balances[ii] = ssz.UnmarshallUint64(buf[ii*8 : (ii+1)*8])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (15) 'previousEpochParticipation'
|
|
||||||
{
|
|
||||||
buf = tail[o15:o16]
|
|
||||||
if len(buf) > 1099511627776 {
|
|
||||||
return ssz.ErrBytesLength
|
|
||||||
}
|
|
||||||
if cap(b.previousEpochParticipation) == 0 {
|
|
||||||
b.previousEpochParticipation = make([]byte, 0, len(buf))
|
|
||||||
}
|
|
||||||
b.previousEpochParticipation = append(b.previousEpochParticipation, buf...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (16) 'currentEpochParticipation'
|
|
||||||
{
|
|
||||||
buf = tail[o16:o21]
|
|
||||||
if len(buf) > 1099511627776 {
|
|
||||||
return ssz.ErrBytesLength
|
|
||||||
}
|
|
||||||
if cap(b.currentEpochParticipation) == 0 {
|
|
||||||
b.currentEpochParticipation = make([]byte, 0, len(buf))
|
|
||||||
}
|
|
||||||
b.currentEpochParticipation = append(b.currentEpochParticipation, buf...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field (21) 'inactivityScores'
|
|
||||||
{
|
|
||||||
buf = tail[o21:]
|
|
||||||
num, err := ssz.DivideInt2(len(buf), 8, 1099511627776)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
b.inactivityScores = ssz.ExtendUint64(b.inactivityScores, num)
|
|
||||||
for ii := 0; ii < num; ii++ {
|
|
||||||
b.inactivityScores[ii] = ssz.UnmarshallUint64(buf[ii*8 : (ii+1)*8])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// SizeSSZ returns the ssz encoded size in bytes for the BeaconState object
|
|
||||||
func (b *BeaconState) SizeSSZ() (size int) {
|
|
||||||
size = 2736629
|
|
||||||
|
|
||||||
// Field (7) 'historicalRoots'
|
|
||||||
size += len(b.historicalRoots) * 32
|
|
||||||
|
|
||||||
// Field (9) 'eth1DataVotes'
|
|
||||||
size += len(b.eth1DataVotes) * 72
|
|
||||||
|
|
||||||
// Field (11) 'validators'
|
|
||||||
size += len(b.validators) * 121
|
|
||||||
|
|
||||||
// Field (12) 'balances'
|
|
||||||
size += len(b.balances) * 8
|
|
||||||
|
|
||||||
// Field (15) 'previousEpochParticipation'
|
|
||||||
size += len(b.previousEpochParticipation)
|
|
||||||
|
|
||||||
// Field (16) 'currentEpochParticipation'
|
|
||||||
size += len(b.currentEpochParticipation)
|
|
||||||
|
|
||||||
// Field (21) 'inactivityScores'
|
|
||||||
size += len(b.inactivityScores) * 8
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
package v2
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// LatestBlockHeader stored within the beacon state.
|
|
||||||
func (b *BeaconState) LatestBlockHeader() *ethpb.BeaconBlockHeader {
|
|
||||||
if b.latestBlockHeader == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.latestBlockHeaderVal()
|
|
||||||
}
|
|
||||||
|
|
||||||
// latestBlockHeaderVal stored within the beacon state.
|
|
||||||
// This assumes that a lock is already held on BeaconState.
|
|
||||||
func (b *BeaconState) latestBlockHeaderVal() *ethpb.BeaconBlockHeader {
|
|
||||||
if b.latestBlockHeader == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
hdr := ðpb.BeaconBlockHeader{
|
|
||||||
Slot: b.latestBlockHeader.Slot,
|
|
||||||
ProposerIndex: b.latestBlockHeader.ProposerIndex,
|
|
||||||
}
|
|
||||||
|
|
||||||
parentRoot := make([]byte, len(b.latestBlockHeader.ParentRoot))
|
|
||||||
bodyRoot := make([]byte, len(b.latestBlockHeader.BodyRoot))
|
|
||||||
stateRoot := make([]byte, len(b.latestBlockHeader.StateRoot))
|
|
||||||
|
|
||||||
copy(parentRoot, b.latestBlockHeader.ParentRoot)
|
|
||||||
copy(bodyRoot, b.latestBlockHeader.BodyRoot)
|
|
||||||
copy(stateRoot, b.latestBlockHeader.StateRoot)
|
|
||||||
hdr.ParentRoot = parentRoot
|
|
||||||
hdr.BodyRoot = bodyRoot
|
|
||||||
hdr.StateRoot = stateRoot
|
|
||||||
return hdr
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
r, err := b.blockRootAtIndex(idx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return r[:], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// blockRootAtIndex retrieves a specific block root based on an
|
|
||||||
// input index value.
|
|
||||||
// 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 b.blockRoots[idx], nil
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
package v2
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
|
||||||
testtmpl "github.com/prysmaticlabs/prysm/beacon-chain/state/testing"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestBeaconState_LatestBlockHeader(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateLatestBlockHeader(
|
|
||||||
t,
|
|
||||||
func() (state.BeaconState, error) {
|
|
||||||
return InitializeFromProto(ðpb.BeaconStateAltair{})
|
|
||||||
},
|
|
||||||
func(BH *ethpb.BeaconBlockHeader) (state.BeaconState, error) {
|
|
||||||
return InitializeFromProto(ðpb.BeaconStateAltair{LatestBlockHeader: BH})
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_BlockRoots(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateBlockRootsNative(
|
|
||||||
t,
|
|
||||||
func() (state.BeaconState, error) {
|
|
||||||
return InitializeFromProto(ðpb.BeaconStateAltair{})
|
|
||||||
},
|
|
||||||
func(BR [][]byte) (state.BeaconState, error) {
|
|
||||||
return InitializeFromProto(ðpb.BeaconStateAltair{BlockRoots: BR})
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_BlockRootAtIndex(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateBlockRootAtIndexNative(
|
|
||||||
t,
|
|
||||||
func() (state.BeaconState, error) {
|
|
||||||
return InitializeFromProto(ðpb.BeaconStateAltair{})
|
|
||||||
},
|
|
||||||
func(BR [][]byte) (state.BeaconState, error) {
|
|
||||||
return InitializeFromProto(ðpb.BeaconStateAltair{BlockRoots: BR})
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
package v2
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
|
|
||||||
"github.com/prysmaticlabs/go-bitfield"
|
|
||||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// JustificationBits marking which epochs have been justified in the beacon chain.
|
|
||||||
func (b *BeaconState) JustificationBits() bitfield.Bitvector4 {
|
|
||||||
if b.justificationBits == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.justificationBitsVal()
|
|
||||||
}
|
|
||||||
|
|
||||||
// justificationBitsVal marking which epochs have been justified in the beacon chain.
|
|
||||||
// This assumes that a lock is already held on BeaconState.
|
|
||||||
func (b *BeaconState) justificationBitsVal() bitfield.Bitvector4 {
|
|
||||||
if b.justificationBits == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
res := make([]byte, len(b.justificationBits.Bytes()))
|
|
||||||
copy(res, b.justificationBits.Bytes())
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// PreviousJustifiedCheckpoint denoting an epoch and block root.
|
|
||||||
func (b *BeaconState) PreviousJustifiedCheckpoint() *ethpb.Checkpoint {
|
|
||||||
if b.previousJustifiedCheckpoint == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.previousJustifiedCheckpointVal()
|
|
||||||
}
|
|
||||||
|
|
||||||
// previousJustifiedCheckpointVal denoting an epoch and block root.
|
|
||||||
// This assumes that a lock is already held on BeaconState.
|
|
||||||
func (b *BeaconState) previousJustifiedCheckpointVal() *ethpb.Checkpoint {
|
|
||||||
return ethpb.CopyCheckpoint(b.previousJustifiedCheckpoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CurrentJustifiedCheckpoint denoting an epoch and block root.
|
|
||||||
func (b *BeaconState) CurrentJustifiedCheckpoint() *ethpb.Checkpoint {
|
|
||||||
if b.currentJustifiedCheckpoint == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.currentJustifiedCheckpointVal()
|
|
||||||
}
|
|
||||||
|
|
||||||
// currentJustifiedCheckpoint denoting an epoch and block root.
|
|
||||||
// This assumes that a lock is already held on BeaconState.
|
|
||||||
func (b *BeaconState) currentJustifiedCheckpointVal() *ethpb.Checkpoint {
|
|
||||||
return ethpb.CopyCheckpoint(b.currentJustifiedCheckpoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MatchCurrentJustifiedCheckpoint returns true if input justified checkpoint matches
|
|
||||||
// the current justified checkpoint in state.
|
|
||||||
func (b *BeaconState) MatchCurrentJustifiedCheckpoint(c *ethpb.Checkpoint) bool {
|
|
||||||
if b.currentJustifiedCheckpoint == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.Epoch != b.currentJustifiedCheckpoint.Epoch {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return bytes.Equal(c.Root, b.currentJustifiedCheckpoint.Root)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MatchPreviousJustifiedCheckpoint returns true if the input justified checkpoint matches
|
|
||||||
// the previous justified checkpoint in state.
|
|
||||||
func (b *BeaconState) MatchPreviousJustifiedCheckpoint(c *ethpb.Checkpoint) bool {
|
|
||||||
if b.previousJustifiedCheckpoint == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.Epoch != b.previousJustifiedCheckpoint.Epoch {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return bytes.Equal(c.Root, b.previousJustifiedCheckpoint.Root)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FinalizedCheckpoint denoting an epoch and block root.
|
|
||||||
func (b *BeaconState) FinalizedCheckpoint() *ethpb.Checkpoint {
|
|
||||||
if b.finalizedCheckpoint == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.finalizedCheckpointVal()
|
|
||||||
}
|
|
||||||
|
|
||||||
// finalizedCheckpointVal denoting an epoch and block root.
|
|
||||||
// This assumes that a lock is already held on BeaconState.
|
|
||||||
func (b *BeaconState) finalizedCheckpointVal() *ethpb.Checkpoint {
|
|
||||||
return ethpb.CopyCheckpoint(b.finalizedCheckpoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FinalizedCheckpointEpoch returns the epoch value of the finalized checkpoint.
|
|
||||||
func (b *BeaconState) FinalizedCheckpointEpoch() types.Epoch {
|
|
||||||
if b.finalizedCheckpoint == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.finalizedCheckpoint.Epoch
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
package v2
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/prysmaticlabs/go-bitfield"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
|
||||||
testtmpl "github.com/prysmaticlabs/prysm/beacon-chain/state/testing"
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestBeaconState_JustificationBitsNil(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateJustificationBitsNil(
|
|
||||||
t,
|
|
||||||
func() (state.BeaconState, error) {
|
|
||||||
return InitializeFromProtoUnsafe(ðpb.BeaconStateAltair{})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_JustificationBits(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateJustificationBits(
|
|
||||||
t,
|
|
||||||
func(bits bitfield.Bitvector4) (state.BeaconState, error) {
|
|
||||||
return InitializeFromProtoUnsafe(ðpb.BeaconStateAltair{JustificationBits: bits})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_PreviousJustifiedCheckpointNil(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStatePreviousJustifiedCheckpointNil(
|
|
||||||
t,
|
|
||||||
func() (state.BeaconState, error) {
|
|
||||||
return InitializeFromProtoUnsafe(ðpb.BeaconStateAltair{})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_PreviousJustifiedCheckpoint(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStatePreviousJustifiedCheckpoint(
|
|
||||||
t,
|
|
||||||
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
|
||||||
return InitializeFromProtoUnsafe(ðpb.BeaconStateAltair{PreviousJustifiedCheckpoint: cp})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_CurrentJustifiedCheckpointNil(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateCurrentJustifiedCheckpointNil(
|
|
||||||
t,
|
|
||||||
func() (state.BeaconState, error) {
|
|
||||||
return InitializeFromProtoUnsafe(ðpb.BeaconStateAltair{})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_CurrentJustifiedCheckpoint(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateCurrentJustifiedCheckpoint(
|
|
||||||
t,
|
|
||||||
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
|
||||||
return InitializeFromProtoUnsafe(ðpb.BeaconStateAltair{CurrentJustifiedCheckpoint: cp})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_FinalizedCheckpointNil(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateFinalizedCheckpointNil(
|
|
||||||
t,
|
|
||||||
func() (state.BeaconState, error) {
|
|
||||||
return InitializeFromProtoUnsafe(ðpb.BeaconStateAltair{})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBeaconState_FinalizedCheckpoint(t *testing.T) {
|
|
||||||
testtmpl.VerifyBeaconStateFinalizedCheckpoint(
|
|
||||||
t,
|
|
||||||
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
|
|
||||||
return InitializeFromProtoUnsafe(ðpb.BeaconStateAltair{FinalizedCheckpoint: cp})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
package v2
|
|
||||||
|
|
||||||
import (
|
|
||||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Eth1Data corresponding to the proof-of-work chain information stored in the beacon state.
|
|
||||||
func (b *BeaconState) Eth1Data() *ethpb.Eth1Data {
|
|
||||||
if b.eth1Data == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.eth1DataVal()
|
|
||||||
}
|
|
||||||
|
|
||||||
// eth1DataVal corresponding to the proof-of-work chain information stored in the beacon state.
|
|
||||||
// This assumes that a lock is already held on BeaconState.
|
|
||||||
func (b *BeaconState) eth1DataVal() *ethpb.Eth1Data {
|
|
||||||
if b.eth1Data == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return ethpb.CopyETH1Data(b.eth1Data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Eth1DataVotes corresponds to votes from Ethereum on the canonical proof-of-work chain
|
|
||||||
// data retrieved from eth1.
|
|
||||||
func (b *BeaconState) Eth1DataVotes() []*ethpb.Eth1Data {
|
|
||||||
if b.eth1DataVotes == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.eth1DataVotesVal()
|
|
||||||
}
|
|
||||||
|
|
||||||
// eth1DataVotesVal corresponds to votes from Ethereum on the canonical proof-of-work chain
|
|
||||||
// data retrieved from eth1.
|
|
||||||
// This assumes that a lock is already held on BeaconState.
|
|
||||||
func (b *BeaconState) eth1DataVotesVal() []*ethpb.Eth1Data {
|
|
||||||
if b.eth1DataVotes == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
res := make([]*ethpb.Eth1Data, len(b.eth1DataVotes))
|
|
||||||
for i := 0; i < len(res); i++ {
|
|
||||||
res[i] = ethpb.CopyETH1Data(b.eth1DataVotes[i])
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// Eth1DepositIndex corresponds to the index of the deposit made to the
|
|
||||||
// validator deposit contract at the time of this state's eth1 data.
|
|
||||||
func (b *BeaconState) Eth1DepositIndex() uint64 {
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.eth1DepositIndex
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
package v2
|
|
||||||
|
|
||||||
// CurrentEpochParticipation corresponding to participation bits on the beacon chain.
|
|
||||||
func (b *BeaconState) CurrentEpochParticipation() ([]byte, error) {
|
|
||||||
if b.currentEpochParticipation == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.currentEpochParticipationVal(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// PreviousEpochParticipation corresponding to participation bits on the beacon chain.
|
|
||||||
func (b *BeaconState) PreviousEpochParticipation() ([]byte, error) {
|
|
||||||
if b.previousEpochParticipation == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b.lock.RLock()
|
|
||||||
defer b.lock.RUnlock()
|
|
||||||
|
|
||||||
return b.previousEpochParticipationVal(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// currentEpochParticipationVal corresponding to participation bits on the beacon chain.
|
|
||||||
// This assumes that a lock is already held on BeaconState.
|
|
||||||
func (b *BeaconState) currentEpochParticipationVal() []byte {
|
|
||||||
tmp := make([]byte, len(b.currentEpochParticipation))
|
|
||||||
copy(tmp, b.currentEpochParticipation)
|
|
||||||
return tmp
|
|
||||||
}
|
|
||||||
|
|
||||||
// previousEpochParticipationVal corresponding to participation bits on the beacon chain.
|
|
||||||
// This assumes that a lock is already held on BeaconState.
|
|
||||||
func (b *BeaconState) previousEpochParticipationVal() []byte {
|
|
||||||
tmp := make([]byte, len(b.previousEpochParticipation))
|
|
||||||
copy(tmp, b.previousEpochParticipation)
|
|
||||||
return tmp
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
package v2
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
|
|
||||||
m, err := b.randaoMixAtIndex(idx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return m[:], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// randaoMixAtIndex retrieves a specific block root based on an
|
|
||||||
// input index value.
|
|
||||||
// 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 b.randaoMixes[idx], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 b.randaoMixes == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return len(b.randaoMixes)
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user