Compare commits

..

12 Commits

Author SHA1 Message Date
nisdas
3e97651512 try again 2022-04-15 18:09:28 +08:00
nisdas
5cb1cb2e15 delete sub-dirs 2022-04-15 18:04:52 +08:00
nisdas
b3cb2770df Revert "delete sub-dirs"
This reverts commit a12f6ae30a.
2022-04-15 18:04:15 +08:00
nisdas
a12f6ae30a delete sub-dirs 2022-04-15 17:57:46 +08:00
Preston Van Loon
cc23b8311a Static analysis: gocognit (#10527)
* Add gocognit to static analyzers with a very high threshold

* edit readme and sort analyzers
2022-04-15 06:29:07 +00:00
terence tsao
cbe54fe3f9 Handle nil execution block response when logging TTD (#10502) 2022-04-13 19:47:04 -07:00
Nishant Das
1b6adca3ca Handle Finalized Deposit Insertion Better (#10517) 2022-04-13 10:08:19 +02:00
Nishant Das
1651649e5a Update to 1.17.9 (#10518) 2022-04-13 05:25:13 +00:00
Potuz
56187edb98 Use forkchoice first when checking canonical status (#10516) 2022-04-12 21:34:13 -03:00
Preston Van Loon
ecad5bbffc e2e: Provide e2e config yaml to web3signer (#10123)
* e2e: Provide e2e config yaml to web3signer

* fix build for //testing/endtoend:go_default_test

* Update with web3signer with teku fixes

* buildifier

* Add slasher case for web3signer

* Update testing/endtoend/minimal_e2e_test.go

* Update web3signer to 21.10.6

* Revert "Update web3signer to 21.10.6"

This reverts commit bdf3c408f2.

* Remove slasher part of web3signer e2e tests

* Revert "Remove slasher part of web3signer e2e tests"

This reverts commit 24249802ae.

* fix slasher web3signer test

* fixing build

* updating yaml to match testnet_e2e_config.go

* trying a different order to the e2e test and adding a log

* trying different way to kill process

* handling unhandled error

* testing changes to config WIP

* fixing bazel WIP

* fixing build

* ignoring test for now to test

* fixing bazel

* Test only web3signer e2e

* rolling back some commits to test

* fixing bazel

* trying an updated web3signer version

* changing flag to match version

* trying current version of develop for web3signer

* testing not using the --network property

* addressing build error

* testing config change

* reverting to go bakc to using the network file

* testing adding epochs per sync committee period

* rolling back configs

* removing check to test

* adding log to get sync committee duties and changing bellatrix fork epoch to something large and altair to epoch 1

* fixing bazel

* updating epoch in config file

* fixing more descrepencies between the configurations

* removing un used yaml

* removing goland added duplicates

* reverting using network minimal

* fixing bug

* rolling back some changes

* rolling back some changes

* rolling back changes

* making sure web3signer test doesn't make it to bellatrix fork yet

* reverting changes I did not touch

* undo comment

* Update testing/endtoend/deps.bzl

* Apply suggestions from code review

* rm nl

* fix //testing/endtoend:go_mainnet_test

* Remove unnecessary dep

* fix //testing/endtoend:go_mainnet_test

* addressing review comments

* fixing build and internal conflict

* removing web3signer slasher test as it's unneeded due to the interface nature of key signing, the regular slashing test is enough

* fix: The validator we fetch from the binary can only run before altair, if you add that and the web3signer then these things can never run together as the web3signer sets it to before bellatrix

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
Co-authored-by: James He <james@prysmaticlabs.com>
Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2022-04-12 16:57:46 +00:00
Nishant Das
407182387b fix it all (#10511) 2022-04-12 19:50:29 +08:00
terence tsao
ad0b0b503d Move GetTerminalBlockHash to powchain engine (#10500)
* Move GetTerminalBlockHash to powchain engine

* Update service.go

* Update service.go

Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2022-04-12 10:19:07 +00:00
191 changed files with 2891 additions and 12448 deletions

View File

@@ -115,18 +115,19 @@ nogo(
"@org_golang_x_tools//go/analysis/passes/assign:go_default_library",
"@org_golang_x_tools//go/analysis/passes/inspect:go_default_library",
"@org_golang_x_tools//go/analysis/passes/asmdecl:go_default_library",
"//tools/analyzers/maligned:go_default_library",
"//tools/analyzers/comparesame:go_default_library",
"//tools/analyzers/cryptorand:go_default_library",
"//tools/analyzers/errcheck:go_default_library",
"//tools/analyzers/featureconfig:go_default_library",
"//tools/analyzers/comparesame:go_default_library",
"//tools/analyzers/shadowpredecl:go_default_library",
"//tools/analyzers/nop:go_default_library",
"//tools/analyzers/slicedirect:go_default_library",
"//tools/analyzers/interfacechecker:go_default_library",
"//tools/analyzers/gocognit:go_default_library",
"//tools/analyzers/ineffassign:go_default_library",
"//tools/analyzers/interfacechecker:go_default_library",
"//tools/analyzers/maligned:go_default_library",
"//tools/analyzers/nop:go_default_library",
"//tools/analyzers/properpermissions:go_default_library",
"//tools/analyzers/recursivelock:go_default_library",
"//tools/analyzers/shadowpredecl:go_default_library",
"//tools/analyzers/slicedirect:go_default_library",
"//tools/analyzers/uintcast:go_default_library",
] + select({
# nogo checks that fail with coverage enabled.

View File

@@ -176,7 +176,7 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_depe
go_rules_dependencies()
go_register_toolchains(
go_version = "1.17.6",
go_version = "1.17.9",
nogo = "@//:nogo",
)

View File

@@ -66,6 +66,7 @@ go_library(
"//config/params:go_default_library",
"//crypto/bls:go_default_library",
"//encoding/bytesutil:go_default_library",
"//math:go_default_library",
"//monitoring/tracing:go_default_library",
"//proto/engine/v1:go_default_library",
"//proto/eth/v1:go_default_library",

View File

@@ -273,13 +273,13 @@ func (s *Service) CurrentFork() *ethpb.Fork {
// IsCanonical returns true if the input block root is part of the canonical chain.
func (s *Service) IsCanonical(ctx context.Context, blockRoot [32]byte) (bool, error) {
// If the block has been finalized, the block will always be part of the canonical chain.
if s.cfg.BeaconDB.IsFinalizedBlock(ctx, blockRoot) {
return true, nil
// If the block has not been finalized, check fork choice store to see if the block is canonical
if s.cfg.ForkChoiceStore.HasNode(blockRoot) {
return s.cfg.ForkChoiceStore.IsCanonical(blockRoot), nil
}
// If the block has not been finalized, check fork choice store to see if the block is canonical
return s.cfg.ForkChoiceStore.IsCanonical(blockRoot), nil
// If the block has been finalized, the block will always be part of the canonical chain.
return s.cfg.BeaconDB.IsFinalizedBlock(ctx, blockRoot), nil
}
// ChainHeads returns all possible chain heads (leaves of fork choice tree).

View File

@@ -11,6 +11,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/config/params"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
mathutil "github.com/prysmaticlabs/prysm/math"
"github.com/prysmaticlabs/prysm/monitoring/tracing"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
@@ -402,10 +403,13 @@ func (s *Service) insertFinalizedDeposits(ctx context.Context, fRoot [32]byte) e
// We update the cache up to the last deposit index in the finalized block's state.
// We can be confident that these deposits will be included in some block
// because the Eth1 follow distance makes such long-range reorgs extremely unlikely.
eth1DepositIndex := int64(finalizedState.Eth1Data().DepositCount - 1)
s.cfg.DepositCache.InsertFinalizedDeposits(ctx, eth1DepositIndex)
eth1DepositIndex, err := mathutil.Int(finalizedState.Eth1DepositIndex())
if err != nil {
return errors.Wrap(err, "could not cast eth1 deposit index")
}
s.cfg.DepositCache.InsertFinalizedDeposits(ctx, int64(eth1DepositIndex))
// Deposit proofs are only used during state transition and can be safely removed to save space.
if err = s.cfg.DepositCache.PruneProofs(ctx, eth1DepositIndex); err != nil {
if err = s.cfg.DepositCache.PruneProofs(ctx, int64(eth1DepositIndex)); err != nil {
return errors.Wrap(err, "could not prune deposit proofs")
}
return nil

View File

@@ -1516,6 +1516,7 @@ func TestInsertFinalizedDeposits(t *testing.T) {
service.store.SetFinalizedCheckpt(&ethpb.Checkpoint{Root: gRoot[:]})
gs = gs.Copy()
assert.NoError(t, gs.SetEth1Data(&ethpb.Eth1Data{DepositCount: 10}))
assert.NoError(t, gs.SetEth1DepositIndex(7))
assert.NoError(t, service.cfg.StateGen.SaveState(ctx, [32]byte{'m', 'o', 'c', 'k'}, gs))
zeroSig := [96]byte{}
for i := uint64(0); i < uint64(4*params.BeaconConfig().SlotsPerEpoch); i++ {
@@ -1529,8 +1530,64 @@ func TestInsertFinalizedDeposits(t *testing.T) {
}
assert.NoError(t, service.insertFinalizedDeposits(ctx, [32]byte{'m', 'o', 'c', 'k'}))
fDeposits := depositCache.FinalizedDeposits(ctx)
assert.Equal(t, 9, int(fDeposits.MerkleTrieIndex), "Finalized deposits not inserted correctly")
deps := depositCache.AllDeposits(ctx, big.NewInt(109))
assert.Equal(t, 7, int(fDeposits.MerkleTrieIndex), "Finalized deposits not inserted correctly")
deps := depositCache.AllDeposits(ctx, big.NewInt(107))
for _, d := range deps {
assert.DeepEqual(t, [][]byte(nil), d.Proof, "Proofs are not empty")
}
}
func TestInsertFinalizedDeposits_MultipleFinalizedRoutines(t *testing.T) {
ctx := context.Background()
opts := testServiceOptsWithDB(t)
depositCache, err := depositcache.New()
require.NoError(t, err)
opts = append(opts, WithDepositCache(depositCache))
service, err := NewService(ctx, opts...)
require.NoError(t, err)
gs, _ := util.DeterministicGenesisState(t, 32)
require.NoError(t, service.saveGenesisData(ctx, gs))
gBlk, err := service.cfg.BeaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block().HashTreeRoot()
require.NoError(t, err)
service.store.SetFinalizedCheckpt(&ethpb.Checkpoint{Root: gRoot[:]})
gs = gs.Copy()
assert.NoError(t, gs.SetEth1Data(&ethpb.Eth1Data{DepositCount: 7}))
assert.NoError(t, gs.SetEth1DepositIndex(5))
assert.NoError(t, service.cfg.StateGen.SaveState(ctx, [32]byte{'m', 'o', 'c', 'k'}, gs))
gs2 := gs.Copy()
assert.NoError(t, gs2.SetEth1Data(&ethpb.Eth1Data{DepositCount: 15}))
assert.NoError(t, gs2.SetEth1DepositIndex(12))
assert.NoError(t, service.cfg.StateGen.SaveState(ctx, [32]byte{'m', 'o', 'c', 'k', '2'}, gs2))
zeroSig := [96]byte{}
for i := uint64(0); i < uint64(4*params.BeaconConfig().SlotsPerEpoch); i++ {
root := []byte(strconv.Itoa(int(i)))
assert.NoError(t, depositCache.InsertDeposit(ctx, &ethpb.Deposit{Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.FromBytes48([fieldparams.BLSPubkeyLength]byte{}),
WithdrawalCredentials: params.BeaconConfig().ZeroHash[:],
Amount: 0,
Signature: zeroSig[:],
}, Proof: [][]byte{root}}, 100+i, int64(i), bytesutil.ToBytes32(root)))
}
// Insert 3 deposits before hand.
depositCache.InsertFinalizedDeposits(ctx, 2)
assert.NoError(t, service.insertFinalizedDeposits(ctx, [32]byte{'m', 'o', 'c', 'k'}))
fDeposits := depositCache.FinalizedDeposits(ctx)
assert.Equal(t, 5, int(fDeposits.MerkleTrieIndex), "Finalized deposits not inserted correctly")
deps := depositCache.AllDeposits(ctx, big.NewInt(105))
for _, d := range deps {
assert.DeepEqual(t, [][]byte(nil), d.Proof, "Proofs are not empty")
}
// Insert New Finalized State with higher deposit count.
assert.NoError(t, service.insertFinalizedDeposits(ctx, [32]byte{'m', 'o', 'c', 'k', '2'}))
fDeposits = depositCache.FinalizedDeposits(ctx)
assert.Equal(t, 12, int(fDeposits.MerkleTrieIndex), "Finalized deposits not inserted correctly")
deps = depositCache.AllDeposits(ctx, big.NewInt(112))
for _, d := range deps {
assert.DeepEqual(t, [][]byte(nil), d.Proof, "Proofs are not empty")
}

View File

@@ -83,7 +83,8 @@ func (s *Service) VerifyLmdFfgConsistency(ctx context.Context, a *ethpb.Attestat
func (s *Service) VerifyFinalizedConsistency(ctx context.Context, root []byte) error {
// A canonical root implies the root to has an ancestor that aligns with finalized check point.
// In this case, we could exit early to save on additional computation.
if s.cfg.ForkChoiceStore.IsCanonical(bytesutil.ToBytes32(root)) {
blockRoot := bytesutil.ToBytes32(root)
if s.cfg.ForkChoiceStore.HasNode(blockRoot) && s.cfg.ForkChoiceStore.IsCanonical(blockRoot) {
return nil
}

View File

@@ -137,6 +137,22 @@ func (dc *DepositCache) InsertFinalizedDeposits(ctx context.Context, eth1Deposit
depositTrie := dc.finalizedDeposits.Deposits
insertIndex := int(dc.finalizedDeposits.MerkleTrieIndex + 1)
// Don't insert into finalized trie if there is no deposit to
// insert.
if len(dc.deposits) == 0 {
return
}
// In the event we have less deposits than we need to
// finalize we finalize till the index on which we do have it.
if len(dc.deposits) <= int(eth1DepositIndex) {
eth1DepositIndex = int64(len(dc.deposits)) - 1
}
// If we finalize to some lower deposit index, we
// ignore it.
if int(eth1DepositIndex) < insertIndex {
return
}
for _, d := range dc.deposits {
if d.Index <= dc.finalizedDeposits.MerkleTrieIndex {
continue

View File

@@ -459,7 +459,7 @@ func TestFinalizedDeposits_UtilizesPreviouslyCachedDeposits(t *testing.T) {
Index: 1,
},
}
newFinalizedDeposit := ethpb.DepositContainer{
newFinalizedDeposit := &ethpb.DepositContainer{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{2}, 48),
@@ -471,17 +471,17 @@ func TestFinalizedDeposits_UtilizesPreviouslyCachedDeposits(t *testing.T) {
}
dc.deposits = oldFinalizedDeposits
dc.InsertFinalizedDeposits(context.Background(), 1)
// Artificially exclude old deposits so that they can only be retrieved from previously finalized deposits.
dc.deposits = []*ethpb.DepositContainer{&newFinalizedDeposit}
dc.InsertFinalizedDeposits(context.Background(), 2)
dc.deposits = append(dc.deposits, []*ethpb.DepositContainer{newFinalizedDeposit}...)
cachedDeposits := dc.FinalizedDeposits(context.Background())
require.NotNil(t, cachedDeposits, "Deposits not cached")
assert.Equal(t, int64(2), cachedDeposits.MerkleTrieIndex)
assert.Equal(t, int64(1), cachedDeposits.MerkleTrieIndex)
var deps [][]byte
for _, d := range append(oldFinalizedDeposits, &newFinalizedDeposit) {
for _, d := range oldFinalizedDeposits {
hash, err := d.Deposit.Data.HashTreeRoot()
require.NoError(t, err, "Could not hash deposit data")
deps = append(deps, hash[:])
@@ -491,6 +491,140 @@ func TestFinalizedDeposits_UtilizesPreviouslyCachedDeposits(t *testing.T) {
assert.Equal(t, trie.HashTreeRoot(), cachedDeposits.Deposits.HashTreeRoot())
}
func TestFinalizedDeposits_HandleZeroDeposits(t *testing.T) {
dc, err := New()
require.NoError(t, err)
dc.InsertFinalizedDeposits(context.Background(), 2)
cachedDeposits := dc.FinalizedDeposits(context.Background())
require.NotNil(t, cachedDeposits, "Deposits not cached")
assert.Equal(t, int64(-1), cachedDeposits.MerkleTrieIndex)
}
func TestFinalizedDeposits_HandleSmallerThanExpectedDeposits(t *testing.T) {
dc, err := New()
require.NoError(t, err)
finalizedDeposits := []*ethpb.DepositContainer{
{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{0}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 0,
},
{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{1}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 1,
},
{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{2}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 2,
},
}
dc.deposits = finalizedDeposits
dc.InsertFinalizedDeposits(context.Background(), 5)
cachedDeposits := dc.FinalizedDeposits(context.Background())
require.NotNil(t, cachedDeposits, "Deposits not cached")
assert.Equal(t, int64(2), cachedDeposits.MerkleTrieIndex)
}
func TestFinalizedDeposits_HandleLowerEth1DepositIndex(t *testing.T) {
dc, err := New()
require.NoError(t, err)
finalizedDeposits := []*ethpb.DepositContainer{
{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{0}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 0,
},
{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{1}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 1,
},
{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{2}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 2,
},
{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{3}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 3,
},
{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{4}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 4,
},
{
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: bytesutil.PadTo([]byte{5}, 48),
WithdrawalCredentials: make([]byte, 32),
Signature: make([]byte, 96),
},
},
Index: 5,
},
}
dc.deposits = finalizedDeposits
dc.InsertFinalizedDeposits(context.Background(), 5)
// Reinsert finalized deposits with a lower index.
dc.InsertFinalizedDeposits(context.Background(), 2)
cachedDeposits := dc.FinalizedDeposits(context.Background())
require.NotNil(t, cachedDeposits, "Deposits not cached")
assert.Equal(t, int64(5), cachedDeposits.MerkleTrieIndex)
}
func TestFinalizedDeposits_InitializedCorrectly(t *testing.T) {
dc, err := New()
require.NoError(t, err)

View File

@@ -120,11 +120,16 @@ func (s *Service) handleExchangeConfigurationError(err error) {
// Logs the terminal total difficulty status.
func (s *Service) logTtdStatus(ctx context.Context, ttd *uint256.Int) (bool, error) {
latest, err := s.LatestExecutionBlock(ctx)
if err != nil {
switch {
case errors.Is(err, hexutil.ErrEmptyString):
return false, nil
case err != nil:
return false, err
}
if latest == nil {
case latest == nil:
return false, errors.New("latest block is nil")
case latest.TotalDifficulty == "":
return false, nil
default:
}
latestTtd, err := hexutil.DecodeBig(latest.TotalDifficulty)
if err != nil {

View File

@@ -190,6 +190,38 @@ func TestService_logTtdStatus(t *testing.T) {
require.Equal(t, false, reached)
}
func TestService_logTtdStatus_NotSyncedClient(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
defer func() {
require.NoError(t, r.Body.Close())
}()
resp := (*pb.ExecutionBlock)(nil) // Nil response when a client is not synced
respJSON := map[string]interface{}{
"jsonrpc": "2.0",
"id": 1,
"result": resp,
}
require.NoError(t, json.NewEncoder(w).Encode(respJSON))
}))
defer srv.Close()
rpcClient, err := rpc.DialHTTP(srv.URL)
require.NoError(t, err)
defer rpcClient.Close()
service := &Service{
cfg: &config{},
}
service.rpcClient = rpcClient
ttd := new(uint256.Int)
reached, err := service.logTtdStatus(context.Background(), ttd.SetUint64(24343))
require.NoError(t, err)
require.Equal(t, false, reached)
}
func emptyPayload() *pb.ExecutionPayload {
return &pb.ExecutionPayload{
ParentHash: make([]byte, fieldparams.RootLength),

View File

@@ -10,9 +10,12 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/rpc"
"github.com/holiman/uint256"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/config/params"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
pb "github.com/prysmaticlabs/prysm/proto/engine/v1"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
)
@@ -49,8 +52,8 @@ type EngineCaller interface {
ExchangeTransitionConfiguration(
ctx context.Context, cfg *pb.TransitionConfiguration,
) error
LatestExecutionBlock(ctx context.Context) (*pb.ExecutionBlock, error)
ExecutionBlockByHash(ctx context.Context, hash common.Hash) (*pb.ExecutionBlock, error)
GetTerminalBlockHash(ctx context.Context) ([]byte, bool, error)
}
// NewPayload calls the engine_newPayloadV1 method via JSON-RPC.
@@ -174,6 +177,78 @@ func (s *Service) ExchangeTransitionConfiguration(
return nil
}
// GetTerminalBlockHash returns the valid terminal block hash based on total difficulty.
//
// Spec code:
// def get_pow_block_at_terminal_total_difficulty(pow_chain: Dict[Hash32, PowBlock]) -> Optional[PowBlock]:
// # `pow_chain` abstractly represents all blocks in the PoW chain
// for block in pow_chain:
// parent = pow_chain[block.parent_hash]
// block_reached_ttd = block.total_difficulty >= TERMINAL_TOTAL_DIFFICULTY
// parent_reached_ttd = parent.total_difficulty >= TERMINAL_TOTAL_DIFFICULTY
// if block_reached_ttd and not parent_reached_ttd:
// return block
//
// return None
func (s *Service) GetTerminalBlockHash(ctx context.Context) ([]byte, bool, error) {
ttd := new(big.Int)
ttd.SetString(params.BeaconConfig().TerminalTotalDifficulty, 10)
terminalTotalDifficulty, overflows := uint256.FromBig(ttd)
if overflows {
return nil, false, errors.New("could not convert terminal total difficulty to uint256")
}
blk, err := s.LatestExecutionBlock(ctx)
if err != nil {
return nil, false, errors.Wrap(err, "could not get latest execution block")
}
if blk == nil {
return nil, false, errors.New("latest execution block is nil")
}
for {
if ctx.Err() != nil {
return nil, false, ctx.Err()
}
currentTotalDifficulty, err := tDStringToUint256(blk.TotalDifficulty)
if err != nil {
return nil, false, errors.Wrap(err, "could not convert total difficulty to uint256")
}
blockReachedTTD := currentTotalDifficulty.Cmp(terminalTotalDifficulty) >= 0
parentHash := bytesutil.ToBytes32(blk.ParentHash)
if len(blk.ParentHash) == 0 || parentHash == params.BeaconConfig().ZeroHash {
return nil, false, nil
}
parentBlk, err := s.ExecutionBlockByHash(ctx, parentHash)
if err != nil {
return nil, false, errors.Wrap(err, "could not get parent execution block")
}
if parentBlk == nil {
return nil, false, errors.New("parent execution block is nil")
}
if blockReachedTTD {
parentTotalDifficulty, err := tDStringToUint256(parentBlk.TotalDifficulty)
if err != nil {
return nil, false, errors.Wrap(err, "could not convert total difficulty to uint256")
}
parentReachedTTD := parentTotalDifficulty.Cmp(terminalTotalDifficulty) >= 0
if !parentReachedTTD {
log.WithFields(logrus.Fields{
"number": blk.Number,
"hash": fmt.Sprintf("%#x", bytesutil.Trunc(blk.Hash)),
"td": blk.TotalDifficulty,
"parentTd": parentBlk.TotalDifficulty,
"ttd": terminalTotalDifficulty,
}).Info("Retrieved terminal block hash")
return blk.Hash, true, nil
}
} else {
return nil, false, nil
}
blk = parentBlk
}
}
// LatestExecutionBlock fetches the latest execution engine block by calling
// eth_blockByNumber via JSON-RPC.
func (s *Service) LatestExecutionBlock(ctx context.Context) (*pb.ExecutionBlock, error) {
@@ -251,3 +326,15 @@ func isTimeout(e error) bool {
t, ok := e.(httpTimeoutError)
return ok && t.Timeout()
}
func tDStringToUint256(td string) (*uint256.Int, error) {
b, err := hexutil.DecodeBig(td)
if err != nil {
return nil, err
}
i, overflows := uint256.FromBig(b)
if overflows {
return nil, errors.New("total difficulty overflowed")
}
return i, nil
}

View File

@@ -418,6 +418,155 @@ func TestClient_HTTP(t *testing.T) {
})
}
func TestServer_getPowBlockHashAtTerminalTotalDifficulty(t *testing.T) {
tests := []struct {
name string
paramsTd string
currentPowBlock *pb.ExecutionBlock
parentPowBlock *pb.ExecutionBlock
errLatestExecutionBlk error
wantTerminalBlockHash []byte
wantExists bool
errString string
}{
{
name: "config td overflows",
paramsTd: "1115792089237316195423570985008687907853269984665640564039457584007913129638912",
errString: "could not convert terminal total difficulty to uint256",
},
{
name: "could not get latest execution block",
paramsTd: "1",
errLatestExecutionBlk: errors.New("blah"),
errString: "could not get latest execution block",
},
{
name: "nil latest execution block",
paramsTd: "1",
errString: "latest execution block is nil",
},
{
name: "current execution block invalid TD",
paramsTd: "1",
currentPowBlock: &pb.ExecutionBlock{
Hash: []byte{'a'},
TotalDifficulty: "1115792089237316195423570985008687907853269984665640564039457584007913129638912",
},
errString: "could not convert total difficulty to uint256",
},
{
name: "current execution block has zero hash parent",
paramsTd: "2",
currentPowBlock: &pb.ExecutionBlock{
Hash: []byte{'a'},
ParentHash: params.BeaconConfig().ZeroHash[:],
TotalDifficulty: "0x3",
},
},
{
name: "could not get parent block",
paramsTd: "2",
currentPowBlock: &pb.ExecutionBlock{
Hash: []byte{'a'},
ParentHash: []byte{'b'},
TotalDifficulty: "0x3",
},
errString: "could not get parent execution block",
},
{
name: "parent execution block invalid TD",
paramsTd: "2",
currentPowBlock: &pb.ExecutionBlock{
Hash: []byte{'a'},
ParentHash: []byte{'b'},
TotalDifficulty: "0x3",
},
parentPowBlock: &pb.ExecutionBlock{
Hash: []byte{'b'},
ParentHash: []byte{'c'},
TotalDifficulty: "1",
},
errString: "could not convert total difficulty to uint256",
},
{
name: "happy case",
paramsTd: "2",
currentPowBlock: &pb.ExecutionBlock{
Hash: []byte{'a'},
ParentHash: []byte{'b'},
TotalDifficulty: "0x3",
},
parentPowBlock: &pb.ExecutionBlock{
Hash: []byte{'b'},
ParentHash: []byte{'c'},
TotalDifficulty: "0x1",
},
wantExists: true,
wantTerminalBlockHash: []byte{'a'},
},
{
name: "ttd not reached",
paramsTd: "3",
currentPowBlock: &pb.ExecutionBlock{
Hash: []byte{'a'},
ParentHash: []byte{'b'},
TotalDifficulty: "0x2",
},
parentPowBlock: &pb.ExecutionBlock{
Hash: []byte{'b'},
ParentHash: []byte{'c'},
TotalDifficulty: "0x1",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cfg := params.BeaconConfig()
cfg.TerminalTotalDifficulty = tt.paramsTd
params.OverrideBeaconConfig(cfg)
var m map[[32]byte]*pb.ExecutionBlock
if tt.parentPowBlock != nil {
m = map[[32]byte]*pb.ExecutionBlock{
bytesutil.ToBytes32(tt.parentPowBlock.Hash): tt.parentPowBlock,
}
}
client := mocks.EngineClient{
ErrLatestExecBlock: tt.errLatestExecutionBlk,
ExecutionBlock: tt.currentPowBlock,
BlockByHashMap: m,
}
b, e, err := client.GetTerminalBlockHash(context.Background())
if tt.errString != "" {
require.ErrorContains(t, tt.errString, err)
} else {
require.NoError(t, err)
require.DeepEqual(t, tt.wantExists, e)
require.DeepEqual(t, tt.wantTerminalBlockHash, b)
}
})
}
}
func Test_tDStringToUint256(t *testing.T) {
i, err := tDStringToUint256("0x0")
require.NoError(t, err)
require.DeepEqual(t, uint256.NewInt(0), i)
i, err = tDStringToUint256("0x10000")
require.NoError(t, err)
require.DeepEqual(t, uint256.NewInt(65536), i)
_, err = tDStringToUint256("100")
require.ErrorContains(t, "hex string without 0x prefix", err)
_, err = tDStringToUint256("0xzzzzzz")
require.ErrorContains(t, "invalid hex string", err)
_, err = tDStringToUint256("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" +
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")
require.ErrorContains(t, "hex number > 256 bits", err)
}
func TestExchangeTransitionConfiguration(t *testing.T) {
fix := fixtures()
ctx := context.Background()

View File

@@ -26,6 +26,7 @@ go_library(
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
"@com_github_ethereum_go_ethereum//rpc:go_default_library",
"@com_github_holiman_uint256//:go_default_library",
"@com_github_pkg_errors//:go_default_library",
],
)

View File

@@ -2,25 +2,32 @@ package testing
import (
"context"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/holiman/uint256"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/config/params"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
pb "github.com/prysmaticlabs/prysm/proto/engine/v1"
)
// EngineClient --
type EngineClient struct {
NewPayloadResp []byte
PayloadIDBytes *pb.PayloadIDBytes
ForkChoiceUpdatedResp []byte
ExecutionPayload *pb.ExecutionPayload
ExecutionBlock *pb.ExecutionBlock
Err error
ErrLatestExecBlock error
ErrExecBlockByHash error
ErrForkchoiceUpdated error
ErrNewPayload error
BlockByHashMap map[[32]byte]*pb.ExecutionBlock
NewPayloadResp []byte
PayloadIDBytes *pb.PayloadIDBytes
ForkChoiceUpdatedResp []byte
ExecutionPayload *pb.ExecutionPayload
ExecutionBlock *pb.ExecutionBlock
Err error
ErrLatestExecBlock error
ErrExecBlockByHash error
ErrForkchoiceUpdated error
ErrNewPayload error
BlockByHashMap map[[32]byte]*pb.ExecutionBlock
TerminalBlockHash []byte
TerminalBlockHashExists bool
}
// NewPayload --
@@ -58,3 +65,52 @@ func (e *EngineClient) ExecutionBlockByHash(_ context.Context, h common.Hash) (*
}
return b, e.ErrExecBlockByHash
}
// GetTerminalBlockHash --
func (e *EngineClient) GetTerminalBlockHash(ctx context.Context) ([]byte, bool, error) {
ttd := new(big.Int)
ttd.SetString(params.BeaconConfig().TerminalTotalDifficulty, 10)
terminalTotalDifficulty, overflows := uint256.FromBig(ttd)
if overflows {
return nil, false, errors.New("could not convert terminal total difficulty to uint256")
}
blk, err := e.LatestExecutionBlock(ctx)
if err != nil {
return nil, false, errors.Wrap(err, "could not get latest execution block")
}
if blk == nil {
return nil, false, errors.New("latest execution block is nil")
}
for {
b, err := hexutil.DecodeBig(blk.TotalDifficulty)
if err != nil {
return nil, false, errors.Wrap(err, "could not convert total difficulty to uint256")
}
currentTotalDifficulty, _ := uint256.FromBig(b)
blockReachedTTD := currentTotalDifficulty.Cmp(terminalTotalDifficulty) >= 0
parentHash := bytesutil.ToBytes32(blk.ParentHash)
if len(blk.ParentHash) == 0 || parentHash == params.BeaconConfig().ZeroHash {
return nil, false, nil
}
parentBlk, err := e.ExecutionBlockByHash(ctx, parentHash)
if err != nil {
return nil, false, errors.Wrap(err, "could not get parent execution block")
}
if blockReachedTTD {
b, err := hexutil.DecodeBig(parentBlk.TotalDifficulty)
if err != nil {
return nil, false, errors.Wrap(err, "could not convert total difficulty to uint256")
}
parentTotalDifficulty, _ := uint256.FromBig(b)
parentReachedTTD := parentTotalDifficulty.Cmp(terminalTotalDifficulty) >= 0
if !parentReachedTTD {
return blk.Hash, true, nil
}
} else {
return nil, false, nil
}
blk = parentBlk
}
}

View File

@@ -77,7 +77,6 @@ go_library(
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
"@com_github_ferranbt_fastssz//:go_default_library",
"@com_github_holiman_uint256//:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prometheus_client_golang//prometheus:go_default_library",
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
@@ -162,7 +161,6 @@ go_test(
"@com_github_d4l3k_messagediff//:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_golang_mock//gomock:go_default_library",
"@com_github_holiman_uint256//:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",

View File

@@ -3,11 +3,7 @@ package validator
import (
"bytes"
"context"
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/holiman/uint256"
"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
@@ -181,79 +177,7 @@ func (vs *Server) getTerminalBlockHashIfExists(ctx context.Context) ([]byte, boo
return terminalBlockHash.Bytes(), true, nil
}
return vs.getPowBlockHashAtTerminalTotalDifficulty(ctx)
}
// This returns the valid terminal block hash based on total difficulty.
//
// Spec code:
// def get_pow_block_at_terminal_total_difficulty(pow_chain: Dict[Hash32, PowBlock]) -> Optional[PowBlock]:
// # `pow_chain` abstractly represents all blocks in the PoW chain
// for block in pow_chain:
// parent = pow_chain[block.parent_hash]
// block_reached_ttd = block.total_difficulty >= TERMINAL_TOTAL_DIFFICULTY
// parent_reached_ttd = parent.total_difficulty >= TERMINAL_TOTAL_DIFFICULTY
// if block_reached_ttd and not parent_reached_ttd:
// return block
//
// return None
func (vs *Server) getPowBlockHashAtTerminalTotalDifficulty(ctx context.Context) ([]byte, bool, error) {
ttd := new(big.Int)
ttd.SetString(params.BeaconConfig().TerminalTotalDifficulty, 10)
terminalTotalDifficulty, overflows := uint256.FromBig(ttd)
if overflows {
return nil, false, errors.New("could not convert terminal total difficulty to uint256")
}
blk, err := vs.ExecutionEngineCaller.LatestExecutionBlock(ctx)
if err != nil {
return nil, false, errors.Wrap(err, "could not get latest execution block")
}
if blk == nil {
return nil, false, errors.New("latest execution block is nil")
}
for {
if ctx.Err() != nil {
return nil, false, ctx.Err()
}
currentTotalDifficulty, err := tDStringToUint256(blk.TotalDifficulty)
if err != nil {
return nil, false, errors.Wrap(err, "could not convert total difficulty to uint256")
}
blockReachedTTD := currentTotalDifficulty.Cmp(terminalTotalDifficulty) >= 0
parentHash := bytesutil.ToBytes32(blk.ParentHash)
if len(blk.ParentHash) == 0 || parentHash == params.BeaconConfig().ZeroHash {
return nil, false, nil
}
parentBlk, err := vs.ExecutionEngineCaller.ExecutionBlockByHash(ctx, parentHash)
if err != nil {
return nil, false, errors.Wrap(err, "could not get parent execution block")
}
if parentBlk == nil {
return nil, false, errors.New("parent execution block is nil")
}
if blockReachedTTD {
parentTotalDifficulty, err := tDStringToUint256(parentBlk.TotalDifficulty)
if err != nil {
return nil, false, errors.Wrap(err, "could not convert total difficulty to uint256")
}
parentReachedTTD := parentTotalDifficulty.Cmp(terminalTotalDifficulty) >= 0
if !parentReachedTTD {
log.WithFields(logrus.Fields{
"number": blk.Number,
"hash": fmt.Sprintf("%#x", bytesutil.Trunc(blk.Hash)),
"td": blk.TotalDifficulty,
"parentTd": parentBlk.TotalDifficulty,
"ttd": terminalTotalDifficulty,
}).Info("Retrieved terminal block hash")
return blk.Hash, true, nil
}
} else {
return nil, false, nil
}
blk = parentBlk
}
return vs.ExecutionEngineCaller.GetTerminalBlockHash(ctx)
}
// activationEpochNotReached returns true if activation epoch has not been reach.
@@ -270,18 +194,6 @@ func activationEpochNotReached(slot types.Slot) bool {
return false
}
func tDStringToUint256(td string) (*uint256.Int, error) {
b, err := hexutil.DecodeBig(td)
if err != nil {
return nil, err
}
i, overflows := uint256.FromBig(b)
if overflows {
return nil, errors.New("total difficulty overflowed")
}
return i, nil
}
func emptyPayload() *enginev1.ExecutionPayload {
return &enginev1.ExecutionPayload{
ParentHash: make([]byte, fieldparams.RootLength),

View File

@@ -6,7 +6,6 @@ import (
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/holiman/uint256"
types "github.com/prysmaticlabs/eth2-types"
chainMock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
@@ -22,26 +21,6 @@ import (
"github.com/prysmaticlabs/prysm/testing/util"
)
func Test_tDStringToUint256(t *testing.T) {
i, err := tDStringToUint256("0x0")
require.NoError(t, err)
require.DeepEqual(t, uint256.NewInt(0), i)
i, err = tDStringToUint256("0x10000")
require.NoError(t, err)
require.DeepEqual(t, uint256.NewInt(65536), i)
_, err = tDStringToUint256("100")
require.ErrorContains(t, "hex string without 0x prefix", err)
_, err = tDStringToUint256("0xzzzzzz")
require.ErrorContains(t, "invalid hex string", err)
_, err = tDStringToUint256("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" +
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")
require.ErrorContains(t, "hex number > 256 bits", err)
}
func TestServer_activationEpochNotReached(t *testing.T) {
require.Equal(t, false, activationEpochNotReached(0))
@@ -154,137 +133,6 @@ func TestServer_getExecutionPayload(t *testing.T) {
}
}
func TestServer_getPowBlockHashAtTerminalTotalDifficulty(t *testing.T) {
tests := []struct {
name string
paramsTd string
currentPowBlock *pb.ExecutionBlock
parentPowBlock *pb.ExecutionBlock
errLatestExecutionBlk error
wantTerminalBlockHash []byte
wantExists bool
errString string
}{
{
name: "config td overflows",
paramsTd: "1115792089237316195423570985008687907853269984665640564039457584007913129638912",
errString: "could not convert terminal total difficulty to uint256",
},
{
name: "could not get latest execution block",
paramsTd: "1",
errLatestExecutionBlk: errors.New("blah"),
errString: "could not get latest execution block",
},
{
name: "nil latest execution block",
paramsTd: "1",
errString: "latest execution block is nil",
},
{
name: "current execution block invalid TD",
paramsTd: "1",
currentPowBlock: &pb.ExecutionBlock{
Hash: []byte{'a'},
TotalDifficulty: "1115792089237316195423570985008687907853269984665640564039457584007913129638912",
},
errString: "could not convert total difficulty to uint256",
},
{
name: "current execution block has zero hash parent",
paramsTd: "2",
currentPowBlock: &pb.ExecutionBlock{
Hash: []byte{'a'},
ParentHash: params.BeaconConfig().ZeroHash[:],
TotalDifficulty: "0x3",
},
},
{
name: "could not get parent block",
paramsTd: "2",
currentPowBlock: &pb.ExecutionBlock{
Hash: []byte{'a'},
ParentHash: []byte{'b'},
TotalDifficulty: "0x3",
},
errString: "could not get parent execution block",
},
{
name: "parent execution block invalid TD",
paramsTd: "2",
currentPowBlock: &pb.ExecutionBlock{
Hash: []byte{'a'},
ParentHash: []byte{'b'},
TotalDifficulty: "0x3",
},
parentPowBlock: &pb.ExecutionBlock{
Hash: []byte{'b'},
ParentHash: []byte{'c'},
TotalDifficulty: "1",
},
errString: "could not convert total difficulty to uint256",
},
{
name: "happy case",
paramsTd: "2",
currentPowBlock: &pb.ExecutionBlock{
Hash: []byte{'a'},
ParentHash: []byte{'b'},
TotalDifficulty: "0x3",
},
parentPowBlock: &pb.ExecutionBlock{
Hash: []byte{'b'},
ParentHash: []byte{'c'},
TotalDifficulty: "0x1",
},
wantExists: true,
wantTerminalBlockHash: []byte{'a'},
},
{
name: "ttd not reached",
paramsTd: "3",
currentPowBlock: &pb.ExecutionBlock{
Hash: []byte{'a'},
ParentHash: []byte{'b'},
TotalDifficulty: "0x2",
},
parentPowBlock: &pb.ExecutionBlock{
Hash: []byte{'b'},
ParentHash: []byte{'c'},
TotalDifficulty: "0x1",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cfg := params.BeaconConfig()
cfg.TerminalTotalDifficulty = tt.paramsTd
params.OverrideBeaconConfig(cfg)
var m map[[32]byte]*pb.ExecutionBlock
if tt.parentPowBlock != nil {
m = map[[32]byte]*pb.ExecutionBlock{
bytesutil.ToBytes32(tt.parentPowBlock.Hash): tt.parentPowBlock,
}
}
vs := &Server{
ExecutionEngineCaller: &powtesting.EngineClient{
ErrLatestExecBlock: tt.errLatestExecutionBlk,
ExecutionBlock: tt.currentPowBlock,
BlockByHashMap: m,
},
}
b, e, err := vs.getPowBlockHashAtTerminalTotalDifficulty(context.Background())
if tt.errString != "" {
require.ErrorContains(t, tt.errString, err)
} else {
require.NoError(t, err)
require.DeepEqual(t, tt.wantExists, e)
require.DeepEqual(t, tt.wantTerminalBlockHash, b)
}
})
}
}
func TestServer_getTerminalBlockHashIfExists(t *testing.T) {
tests := []struct {
name string

View File

@@ -10,6 +10,7 @@ go_library(
visibility = ["//beacon-chain:__subpackages__"],
deps = [
"//beacon-chain/state/state-native/custom-types:go_default_library",
"//beacon-chain/state/state-native/types:go_default_library",
"//beacon-chain/state/stateutil:go_default_library",
"//beacon-chain/state/types:go_default_library",
"//crypto/hash:go_default_library",

View File

@@ -16,7 +16,7 @@ type FieldTrie struct {
*sync.RWMutex
reference *stateutil.Reference
fieldLayers [][]*[32]byte
field types.FieldIndex
field types.FieldIdx
dataType types.DataType
length uint64
numOfElems int
@@ -25,7 +25,7 @@ type FieldTrie struct {
// NewFieldTrie is the constructor for the field trie data structure. It creates the corresponding
// trie according to the given parameters. Depending on whether the field is a basic/composite array
// which is either fixed/variable length, it will appropriately determine the trie.
func NewFieldTrie(field types.FieldIndex, dataType types.DataType, elements interface{}, length uint64) (*FieldTrie, error) {
func NewFieldTrie(field types.FieldIdx, dataType types.DataType, elements interface{}, length uint64) (*FieldTrie, error) {
if elements == nil {
return &FieldTrie{
field: field,

View File

@@ -7,6 +7,7 @@ import (
"github.com/pkg/errors"
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"
"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.
func ProofFromMerkleLayers(layers [][][]byte, startingLeafIndex types.FieldIndex) [][]byte {
func ProofFromMerkleLayers(layers [][][]byte, startingLeafIndex int) [][]byte {
// The merkle tree structure looks as follows:
// [[r1, r2, r3, r4], [parent1, parent2], [root]]
proof := make([][]byte, 0)
@@ -49,7 +50,7 @@ func (f *FieldTrie) validateIndices(idxs []uint64) error {
return nil
}
func validateElements(field types.FieldIndex, dataType types.DataType, elements interface{}, length uint64) error {
func validateElements(field types.FieldIdx, dataType types.DataType, elements interface{}, length uint64) error {
if dataType == types.CompressedArray {
comLength, err := field.ElemsInChunk()
if err != nil {
@@ -65,68 +66,117 @@ func validateElements(field types.FieldIndex, dataType types.DataType, elements
}
// 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.FieldIdx, indices []uint64, elements interface{}, convertAll bool) ([][32]byte, error) {
if field.Native() {
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())
}
}
switch field {
case types.BlockRoots:
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")
}
return convertBlockRoots(indices, elements, convertAll)
case types.StateRoots:
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")
}
return convertStateRoots(indices, elements, convertAll)
case types.RandaoMixes:
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")
}
return convertRandaoMixes(indices, elements, convertAll)
case types.Eth1DataVotes:
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)
return convertEth1DataVotes(indices, elements, convertAll)
case types.Validators:
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)
return convertValidators(indices, elements, convertAll)
case types.PreviousEpochAttestations, types.CurrentEpochAttestations:
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)
return convertAttestations(indices, elements, convertAll)
case types.Balances:
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)
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.
func handleByteArrays(val [][]byte, indices []uint64, convertAll bool) ([][32]byte, error) {
length := len(indices)

View File

@@ -18,7 +18,7 @@ func TestFieldTrie_NewTrie(t *testing.T) {
newState, _ := util.DeterministicGenesisState(t, 40)
// 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)
root, err := stateutil.RootsArrayHashTreeRoot(newState.StateRoots(), uint64(params.BeaconConfig().SlotsPerHistoricalRoot))
require.NoError(t, err)
@@ -30,7 +30,7 @@ func TestFieldTrie_NewTrie(t *testing.T) {
func TestFieldTrie_RecomputeTrie(t *testing.T) {
newState, _ := util.DeterministicGenesisState(t, 32)
// 10 represents the enum value of validators
trie, err := fieldtrie.NewFieldTrie(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)
changedIdx := []uint64{2, 29}
@@ -58,7 +58,7 @@ func TestFieldTrie_RecomputeTrie(t *testing.T) {
func TestFieldTrie_CopyTrieImmutable(t *testing.T) {
newState, _ := util.DeterministicGenesisState(t, 32)
// 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)
newTrie := trie.CopyTrie()

View File

@@ -0,0 +1,76 @@
load("@prysm//tools/go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"getters_attestation.go",
"getters_block.go",
"getters_checkpoint.go",
"getters_eth1.go",
"getters_misc.go",
"getters_participation.go",
"getters_payload_header.go",
"getters_randao.go",
"getters_state.go",
"getters_sync_committee.go",
"getters_validator.go",
"proofs.go",
"readonly_validator.go",
"setters_attestation.go",
"setters_block.go",
"setters_checkpoint.go",
"setters_eth1.go",
"setters_misc.go",
"setters_participation.go",
"setters_payload_header.go",
"setters_randao.go",
"setters_state.go",
"setters_sync_committee.go",
"setters_validator.go",
"ssz.go",
"state_trie.go",
"types.go",
] + select({
"//config:mainnet": ["beacon_state_mainnet.go"],
"//config:minimal": ["beacon_state_minimal.go"],
}),
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native",
visibility = [
"//beacon-chain:__subpackages__",
"//contracts/deposit:__subpackages__",
"//proto/migration:__subpackages__",
"//proto/prysm/v1alpha1:__subpackages__",
"//proto/testing:__subpackages__",
"//runtime/interop:__subpackages__",
"//slasher/rpc:__subpackages__",
"//testing/benchmark:__pkg__",
"//testing/fuzz:__pkg__",
"//testing/spectest:__subpackages__",
"//testing/util:__pkg__",
"//tools/benchmark-files-gen:__pkg__",
"//tools/pcli:__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/types:go_default_library",
"//beacon-chain/state/stateutil:go_default_library",
"//beacon-chain/state/types:go_default_library",
"//config/features:go_default_library",
"//config/fieldparams:go_default_library",
"//config/params: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_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_eth2_types//: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",
],
)

View File

@@ -1,7 +1,7 @@
//go:build !minimal
// +build !minimal
package v3
package state_native
import (
"sync"
@@ -10,14 +10,15 @@ import (
"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"
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"
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().
type BeaconState struct {
version int
genesisTime uint64 `ssz-gen:"true"`
genesisValidatorsRoot customtypes.Byte32 `ssz-gen:"true" ssz-size:"32"`
slot eth2types.Slot `ssz-gen:"true"`
@@ -33,6 +34,8 @@ type BeaconState struct {
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"`
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"`
@@ -45,11 +48,12 @@ type BeaconState struct {
latestExecutionPayloadHeader *ethpb.ExecutionPayloadHeader `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
fieldIndexesRev map[nativetypes.FieldIndex]int
dirtyFields map[nativetypes.FieldIndex]bool
dirtyIndices map[nativetypes.FieldIndex][]uint64
stateFieldLeaves map[nativetypes.FieldIndex]*fieldtrie.FieldTrie
rebuildTrie map[nativetypes.FieldIndex]bool
valMapHandler *stateutil.ValidatorMapHandler
merkleLayers [][][]byte
sharedFieldReferences map[types.FieldIndex]*stateutil.Reference
sharedFieldReferences map[nativetypes.FieldIndex]*stateutil.Reference
}

View File

@@ -1,7 +1,7 @@
//go:build minimal
// +build minimal
package v3
package state_native
import (
"sync"
@@ -10,14 +10,15 @@ import (
"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"
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"
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().
type BeaconState struct {
version int
genesisTime uint64 `ssz-gen:"true"`
genesisValidatorsRoot customtypes.Byte32 `ssz-gen:"true" ssz-size:"32"`
slot eth2types.Slot `ssz-gen:"true"`
@@ -33,6 +34,8 @@ type BeaconState struct {
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"`
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"`
@@ -45,11 +48,12 @@ type BeaconState struct {
latestExecutionPayloadHeader *ethpb.ExecutionPayloadHeader `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
fieldIndexesRev map[nativetypes.FieldIndex]int
dirtyFields map[nativetypes.FieldIndex]bool
dirtyIndices map[nativetypes.FieldIndex][]uint64
stateFieldLeaves map[nativetypes.FieldIndex]*fieldtrie.FieldTrie
rebuildTrie map[nativetypes.FieldIndex]bool
valMapHandler *stateutil.ValidatorMapHandler
merkleLayers [][][]byte
sharedFieldReferences map[types.FieldIndex]*stateutil.Reference
sharedFieldReferences map[nativetypes.FieldIndex]*stateutil.Reference
}

View File

@@ -37,4 +37,4 @@
// Although it is technically possible to remove the short-circuit conditions
// from the external function, that would require every read to obtain a lock
// even if the data was not present, leading to potential slowdowns.
package v1
package state_native

View File

@@ -1,4 +1,4 @@
package v1
package state_native
import (
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"

View File

@@ -1,4 +1,4 @@
package v1
package state_native
import (
"fmt"

View File

@@ -1,4 +1,4 @@
package v3
package state_native
import (
"bytes"

View File

@@ -1,4 +1,4 @@
package v2
package state_native
import (
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"

View File

@@ -1,9 +1,8 @@
package v1
package state_native
import (
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/runtime/version"
)
// GenesisTime of the beacon state as a uint64.
@@ -25,8 +24,8 @@ func (b *BeaconState) GenesisValidatorsRoot() []byte {
// Version of the beacon state. This method
// is strictly meant to be used without a lock
// internally.
func (_ *BeaconState) Version() int {
return version.Phase0
func (b *BeaconState) Version() int {
return b.version
}
// Slot of the current beacon chain state.

View File

@@ -1,4 +1,4 @@
package v2
package state_native
// CurrentEpochParticipation corresponding to participation bits on the beacon chain.
func (b *BeaconState) CurrentEpochParticipation() ([]byte, error) {

View File

@@ -1,4 +1,4 @@
package v3
package state_native
import (
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"

View File

@@ -1,4 +1,4 @@
package v3
package state_native
import (
"fmt"

View File

@@ -1,4 +1,4 @@
package v1
package state_native
import (
"fmt"
@@ -116,9 +116,9 @@ func (b *BeaconState) stateRootAtIndex(idx uint64) ([32]byte, error) {
return b.stateRoots[idx], nil
}
// ProtobufBeaconState transforms an input into beacon state in the form of protobuf.
// 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 ProtobufBeaconState(s interface{}) (*ethpb.BeaconState, error) {
func ProtobufBeaconStatePhase0(s interface{}) (*ethpb.BeaconState, error) {
pbState, ok := s.(*ethpb.BeaconState)
if !ok {
return nil, errors.New("input is not type ethpb.BeaconState")

View File

@@ -1,4 +1,4 @@
package v3
package state_native
import (
"github.com/prysmaticlabs/prysm/encoding/bytesutil"

View File

@@ -1,4 +1,4 @@
package v3
package state_native
import (
"fmt"
@@ -6,7 +6,6 @@ import (
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
"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"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
@@ -111,7 +110,7 @@ func (b *BeaconState) ValidatorAtIndexReadOnly(idx types.ValidatorIndex) (state.
b.lock.RLock()
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.
@@ -164,7 +163,7 @@ func (b *BeaconState) ReadFromEveryValidator(f func(idx int, val state.ReadOnlyV
b.lock.RUnlock()
for i, v := range validators {
v, err := v1.NewValidator(v)
v, err := NewValidator(v)
if err != nil {
return err
}

View File

@@ -1,4 +1,4 @@
package v1
package state_native
import (
"context"
@@ -6,6 +6,7 @@ import (
"github.com/pkg/errors"
"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"
)
@@ -48,7 +49,7 @@ func (b *BeaconState) FinalizedRootProof(ctx context.Context) ([][]byte, error)
epochRoot := bytesutil.ToBytes32(epochBuf)
proof := make([][]byte, 0)
proof = append(proof, epochRoot[:])
branch := fieldtrie.ProofFromMerkleLayers(b.merkleLayers, finalizedCheckpoint)
branch := fieldtrie.ProofFromMerkleLayers(b.merkleLayers, b.fieldIndexesRev[nativetypes.FinalizedCheckpoint])
proof = append(proof, branch...)
return proof, nil
}

View File

@@ -1,4 +1,4 @@
package v1
package state_native
import (
"github.com/pkg/errors"

View File

@@ -1,8 +1,9 @@
package v1
package state_native
import (
"fmt"
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"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
@@ -20,21 +21,21 @@ func (b *BeaconState) RotateAttestations() error {
}
func (b *BeaconState) setPreviousEpochAttestations(val []*ethpb.PendingAttestation) {
b.sharedFieldReferences[previousEpochAttestations].MinusRef()
b.sharedFieldReferences[previousEpochAttestations] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.PreviousEpochAttestations].MinusRef()
b.sharedFieldReferences[nativetypes.PreviousEpochAttestations] = stateutil.NewRef(1)
b.previousEpochAttestations = val
b.markFieldAsDirty(previousEpochAttestations)
b.rebuildTrie[previousEpochAttestations] = true
b.markFieldAsDirty(nativetypes.PreviousEpochAttestations)
b.rebuildTrie[nativetypes.PreviousEpochAttestations] = true
}
func (b *BeaconState) setCurrentEpochAttestations(val []*ethpb.PendingAttestation) {
b.sharedFieldReferences[currentEpochAttestations].MinusRef()
b.sharedFieldReferences[currentEpochAttestations] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.CurrentEpochAttestations].MinusRef()
b.sharedFieldReferences[nativetypes.CurrentEpochAttestations] = stateutil.NewRef(1)
b.currentEpochAttestations = val
b.markFieldAsDirty(currentEpochAttestations)
b.rebuildTrie[currentEpochAttestations] = true
b.markFieldAsDirty(nativetypes.CurrentEpochAttestations)
b.rebuildTrie[nativetypes.CurrentEpochAttestations] = true
}
// AppendCurrentEpochAttestations for the beacon state. Appends the new value
@@ -49,17 +50,17 @@ func (b *BeaconState) AppendCurrentEpochAttestations(val *ethpb.PendingAttestati
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.
atts = make([]*ethpb.PendingAttestation, len(b.currentEpochAttestations))
copy(atts, b.currentEpochAttestations)
b.sharedFieldReferences[currentEpochAttestations].MinusRef()
b.sharedFieldReferences[currentEpochAttestations] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.CurrentEpochAttestations].MinusRef()
b.sharedFieldReferences[nativetypes.CurrentEpochAttestations] = stateutil.NewRef(1)
}
b.currentEpochAttestations = append(atts, val)
b.markFieldAsDirty(currentEpochAttestations)
b.addDirtyIndices(currentEpochAttestations, []uint64{uint64(len(b.currentEpochAttestations) - 1)})
b.markFieldAsDirty(nativetypes.CurrentEpochAttestations)
b.addDirtyIndices(nativetypes.CurrentEpochAttestations, []uint64{uint64(len(b.currentEpochAttestations) - 1)})
return nil
}
@@ -75,15 +76,15 @@ func (b *BeaconState) AppendPreviousEpochAttestations(val *ethpb.PendingAttestat
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))
copy(atts, b.previousEpochAttestations)
b.sharedFieldReferences[previousEpochAttestations].MinusRef()
b.sharedFieldReferences[previousEpochAttestations] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.PreviousEpochAttestations].MinusRef()
b.sharedFieldReferences[nativetypes.PreviousEpochAttestations] = stateutil.NewRef(1)
}
b.previousEpochAttestations = append(atts, val)
b.markFieldAsDirty(previousEpochAttestations)
b.addDirtyIndices(previousEpochAttestations, []uint64{uint64(len(b.previousEpochAttestations) - 1)})
b.markFieldAsDirty(nativetypes.PreviousEpochAttestations)
b.addDirtyIndices(nativetypes.PreviousEpochAttestations, []uint64{uint64(len(b.previousEpochAttestations) - 1)})
return nil
}

View File

@@ -1,9 +1,10 @@
package v1
package state_native
import (
"fmt"
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"
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
@@ -15,7 +16,7 @@ func (b *BeaconState) SetLatestBlockHeader(val *ethpb.BeaconBlockHeader) error {
defer b.lock.Unlock()
b.latestBlockHeader = ethpb.CopyBeaconBlockHeader(val)
b.markFieldAsDirty(latestBlockHeader)
b.markFieldAsDirty(nativetypes.LatestBlockHeader)
return nil
}
@@ -25,8 +26,8 @@ func (b *BeaconState) SetBlockRoots(val [][]byte) error {
b.lock.Lock()
defer b.lock.Unlock()
b.sharedFieldReferences[blockRoots].MinusRef()
b.sharedFieldReferences[blockRoots] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.BlockRoots].MinusRef()
b.sharedFieldReferences[nativetypes.BlockRoots] = stateutil.NewRef(1)
var rootsArr [fieldparams.BlockRootsLength][32]byte
for i := 0; i < len(rootsArr); i++ {
@@ -34,8 +35,8 @@ func (b *BeaconState) SetBlockRoots(val [][]byte) error {
}
roots := customtypes.BlockRoots(rootsArr)
b.blockRoots = &roots
b.markFieldAsDirty(blockRoots)
b.rebuildTrie[blockRoots] = true
b.markFieldAsDirty(nativetypes.BlockRoots)
b.rebuildTrie[nativetypes.BlockRoots] = true
return nil
}
@@ -49,19 +50,19 @@ func (b *BeaconState) UpdateBlockRootAtIndex(idx uint64, blockRoot [32]byte) err
defer b.lock.Unlock()
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.
roots := *b.blockRoots
rootsCopy := roots
r = &rootsCopy
ref.MinusRef()
b.sharedFieldReferences[blockRoots] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.BlockRoots] = stateutil.NewRef(1)
}
r[idx] = blockRoot
b.blockRoots = r
b.markFieldAsDirty(blockRoots)
b.addDirtyIndices(blockRoots, []uint64{idx})
b.markFieldAsDirty(nativetypes.BlockRoots)
b.addDirtyIndices(nativetypes.BlockRoots, []uint64{idx})
return nil
}

View File

@@ -1,7 +1,8 @@
package v2
package state_native
import (
"github.com/prysmaticlabs/go-bitfield"
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
)
@@ -11,7 +12,7 @@ func (b *BeaconState) SetJustificationBits(val bitfield.Bitvector4) error {
defer b.lock.Unlock()
b.justificationBits = val
b.markFieldAsDirty(justificationBits)
b.markFieldAsDirty(nativetypes.JustificationBits)
return nil
}
@@ -21,7 +22,7 @@ func (b *BeaconState) SetPreviousJustifiedCheckpoint(val *ethpb.Checkpoint) erro
defer b.lock.Unlock()
b.previousJustifiedCheckpoint = val
b.markFieldAsDirty(previousJustifiedCheckpoint)
b.markFieldAsDirty(nativetypes.PreviousJustifiedCheckpoint)
return nil
}
@@ -31,7 +32,7 @@ func (b *BeaconState) SetCurrentJustifiedCheckpoint(val *ethpb.Checkpoint) error
defer b.lock.Unlock()
b.currentJustifiedCheckpoint = val
b.markFieldAsDirty(currentJustifiedCheckpoint)
b.markFieldAsDirty(nativetypes.CurrentJustifiedCheckpoint)
return nil
}
@@ -41,6 +42,6 @@ func (b *BeaconState) SetFinalizedCheckpoint(val *ethpb.Checkpoint) error {
defer b.lock.Unlock()
b.finalizedCheckpoint = val
b.markFieldAsDirty(finalizedCheckpoint)
b.markFieldAsDirty(nativetypes.FinalizedCheckpoint)
return nil
}

View File

@@ -1,6 +1,7 @@
package v3
package state_native
import (
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
)
@@ -11,7 +12,7 @@ func (b *BeaconState) SetEth1Data(val *ethpb.Eth1Data) error {
defer b.lock.Unlock()
b.eth1Data = val
b.markFieldAsDirty(eth1Data)
b.markFieldAsDirty(nativetypes.Eth1Data)
return nil
}
@@ -21,12 +22,12 @@ 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.sharedFieldReferences[nativetypes.Eth1DataVotes].MinusRef()
b.sharedFieldReferences[nativetypes.Eth1DataVotes] = stateutil.NewRef(1)
b.eth1DataVotes = val
b.markFieldAsDirty(eth1DataVotes)
b.rebuildTrie[eth1DataVotes] = true
b.markFieldAsDirty(nativetypes.Eth1DataVotes)
b.rebuildTrie[nativetypes.Eth1DataVotes] = true
return nil
}
@@ -36,7 +37,7 @@ func (b *BeaconState) SetEth1DepositIndex(val uint64) error {
defer b.lock.Unlock()
b.eth1DepositIndex = val
b.markFieldAsDirty(eth1DepositIndex)
b.markFieldAsDirty(nativetypes.Eth1DepositIndex)
return nil
}
@@ -47,16 +48,16 @@ func (b *BeaconState) AppendEth1DataVotes(val *ethpb.Eth1Data) error {
defer b.lock.Unlock()
votes := b.eth1DataVotes
if b.sharedFieldReferences[eth1DataVotes].Refs() > 1 {
if b.sharedFieldReferences[nativetypes.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.sharedFieldReferences[nativetypes.Eth1DataVotes].MinusRef()
b.sharedFieldReferences[nativetypes.Eth1DataVotes] = stateutil.NewRef(1)
}
b.eth1DataVotes = append(votes, val)
b.markFieldAsDirty(eth1DataVotes)
b.addDirtyIndices(eth1DataVotes, []uint64{uint64(len(b.eth1DataVotes) - 1)})
b.markFieldAsDirty(nativetypes.Eth1DataVotes)
b.addDirtyIndices(nativetypes.Eth1DataVotes, []uint64{uint64(len(b.eth1DataVotes) - 1)})
return nil
}

View File

@@ -1,10 +1,10 @@
package v1
package state_native
import (
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
stateTypes "github.com/prysmaticlabs/prysm/beacon-chain/state/types"
"github.com/prysmaticlabs/prysm/config/features"
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
"github.com/prysmaticlabs/prysm/crypto/hash"
@@ -47,7 +47,7 @@ func (b *BeaconState) SetGenesisTime(val uint64) error {
defer b.lock.Unlock()
b.genesisTime = val
b.markFieldAsDirty(genesisTime)
b.markFieldAsDirty(nativetypes.GenesisTime)
return nil
}
@@ -60,7 +60,7 @@ func (b *BeaconState) SetGenesisValidatorsRoot(val []byte) error {
return errors.New("incorrect validators root length")
}
b.genesisValidatorsRoot = bytesutil.ToBytes32(val)
b.markFieldAsDirty(genesisValidatorsRoot)
b.markFieldAsDirty(nativetypes.GenesisValidatorsRoot)
return nil
}
@@ -70,7 +70,7 @@ func (b *BeaconState) SetSlot(val types.Slot) error {
defer b.lock.Unlock()
b.slot = val
b.markFieldAsDirty(slot)
b.markFieldAsDirty(nativetypes.Slot)
return nil
}
@@ -84,7 +84,7 @@ func (b *BeaconState) SetFork(val *ethpb.Fork) error {
return errors.New("proto.Clone did not return a fork proto")
}
b.fork = fk
b.markFieldAsDirty(fork)
b.markFieldAsDirty(nativetypes.Fork)
return nil
}
@@ -94,15 +94,15 @@ func (b *BeaconState) SetHistoricalRoots(val [][]byte) error {
b.lock.Lock()
defer b.lock.Unlock()
b.sharedFieldReferences[historicalRoots].MinusRef()
b.sharedFieldReferences[historicalRoots] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.HistoricalRoots].MinusRef()
b.sharedFieldReferences[nativetypes.HistoricalRoots] = stateutil.NewRef(1)
roots := make([][32]byte, len(val))
for i, r := range val {
copy(roots[i][:], r)
}
b.historicalRoots = roots
b.markFieldAsDirty(historicalRoots)
b.markFieldAsDirty(nativetypes.HistoricalRoots)
return nil
}
@@ -113,15 +113,15 @@ func (b *BeaconState) AppendHistoricalRoots(root [32]byte) error {
defer b.lock.Unlock()
roots := b.historicalRoots
if b.sharedFieldReferences[historicalRoots].Refs() > 1 {
if b.sharedFieldReferences[nativetypes.HistoricalRoots].Refs() > 1 {
roots = make([][32]byte, len(b.historicalRoots))
copy(roots, b.historicalRoots)
b.sharedFieldReferences[historicalRoots].MinusRef()
b.sharedFieldReferences[historicalRoots] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.HistoricalRoots].MinusRef()
b.sharedFieldReferences[nativetypes.HistoricalRoots] = stateutil.NewRef(1)
}
b.historicalRoots = append(roots, root)
b.markFieldAsDirty(historicalRoots)
b.markFieldAsDirty(nativetypes.HistoricalRoots)
return nil
}
@@ -160,18 +160,18 @@ func (b *BeaconState) recomputeRoot(idx int) {
b.merkleLayers = layers
}
func (b *BeaconState) markFieldAsDirty(field stateTypes.FieldIndex) {
func (b *BeaconState) markFieldAsDirty(field nativetypes.FieldIndex) {
b.dirtyFields[field] = true
}
// addDirtyIndices adds the relevant dirty field indices, so that they
// 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] {
return
}
// Exit early if balance trie computation isn't enabled.
if !features.Get().EnableBalanceTrieComputation && index == balances {
if !features.Get().EnableBalanceTrieComputation && index == nativetypes.Balances {
return
}
totalIndicesLen := len(b.dirtyIndices[index]) + len(indices)

View File

@@ -1,6 +1,7 @@
package v2
package state_native
import (
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
)
@@ -10,12 +11,12 @@ func (b *BeaconState) SetPreviousParticipationBits(val []byte) error {
b.lock.Lock()
defer b.lock.Unlock()
b.sharedFieldReferences[previousEpochParticipationBits].MinusRef()
b.sharedFieldReferences[previousEpochParticipationBits] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.PreviousEpochParticipationBits].MinusRef()
b.sharedFieldReferences[nativetypes.PreviousEpochParticipationBits] = stateutil.NewRef(1)
b.previousEpochParticipation = val
b.markFieldAsDirty(previousEpochParticipationBits)
b.rebuildTrie[previousEpochParticipationBits] = true
b.markFieldAsDirty(nativetypes.PreviousEpochParticipationBits)
b.rebuildTrie[nativetypes.PreviousEpochParticipationBits] = true
return nil
}
@@ -25,12 +26,12 @@ func (b *BeaconState) SetCurrentParticipationBits(val []byte) error {
b.lock.Lock()
defer b.lock.Unlock()
b.sharedFieldReferences[currentEpochParticipationBits].MinusRef()
b.sharedFieldReferences[currentEpochParticipationBits] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.CurrentEpochParticipationBits].MinusRef()
b.sharedFieldReferences[nativetypes.CurrentEpochParticipationBits] = stateutil.NewRef(1)
b.currentEpochParticipation = val
b.markFieldAsDirty(currentEpochParticipationBits)
b.rebuildTrie[currentEpochParticipationBits] = true
b.markFieldAsDirty(nativetypes.CurrentEpochParticipationBits)
b.rebuildTrie[nativetypes.CurrentEpochParticipationBits] = true
return nil
}
@@ -41,17 +42,17 @@ func (b *BeaconState) AppendCurrentParticipationBits(val byte) error {
defer b.lock.Unlock()
participation := b.currentEpochParticipation
if b.sharedFieldReferences[currentEpochParticipationBits].Refs() > 1 {
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[currentEpochParticipationBits].MinusRef()
b.sharedFieldReferences[currentEpochParticipationBits] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.CurrentEpochParticipationBits].MinusRef()
b.sharedFieldReferences[nativetypes.CurrentEpochParticipationBits] = stateutil.NewRef(1)
}
b.currentEpochParticipation = append(participation, val)
b.markFieldAsDirty(currentEpochParticipationBits)
b.addDirtyIndices(currentEpochParticipationBits, []uint64{uint64(len(b.currentEpochParticipation) - 1)})
b.markFieldAsDirty(nativetypes.CurrentEpochParticipationBits)
b.addDirtyIndices(nativetypes.CurrentEpochParticipationBits, []uint64{uint64(len(b.currentEpochParticipation) - 1)})
return nil
}
@@ -62,16 +63,16 @@ func (b *BeaconState) AppendPreviousParticipationBits(val byte) error {
defer b.lock.Unlock()
bits := b.previousEpochParticipation
if b.sharedFieldReferences[previousEpochParticipationBits].Refs() > 1 {
if b.sharedFieldReferences[nativetypes.PreviousEpochParticipationBits].Refs() > 1 {
bits = make([]byte, len(b.previousEpochParticipation))
copy(bits, b.previousEpochParticipation)
b.sharedFieldReferences[previousEpochParticipationBits].MinusRef()
b.sharedFieldReferences[previousEpochParticipationBits] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.PreviousEpochParticipationBits].MinusRef()
b.sharedFieldReferences[nativetypes.PreviousEpochParticipationBits] = stateutil.NewRef(1)
}
b.previousEpochParticipation = append(bits, val)
b.markFieldAsDirty(previousEpochParticipationBits)
b.addDirtyIndices(previousEpochParticipationBits, []uint64{uint64(len(b.previousEpochParticipation) - 1)})
b.markFieldAsDirty(nativetypes.PreviousEpochParticipationBits)
b.addDirtyIndices(nativetypes.PreviousEpochParticipationBits, []uint64{uint64(len(b.previousEpochParticipation) - 1)})
return nil
}
@@ -82,12 +83,12 @@ func (b *BeaconState) ModifyPreviousParticipationBits(mutator func(val []byte) (
b.lock.Lock()
participation := b.previousEpochParticipation
if b.sharedFieldReferences[previousEpochParticipationBits].Refs() > 1 {
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[previousEpochParticipationBits].MinusRef()
b.sharedFieldReferences[previousEpochParticipationBits] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.PreviousEpochParticipationBits].MinusRef()
b.sharedFieldReferences[nativetypes.PreviousEpochParticipationBits] = stateutil.NewRef(1)
}
// Lock is released so that mutator can
// acquire it.
@@ -101,8 +102,8 @@ func (b *BeaconState) ModifyPreviousParticipationBits(mutator func(val []byte) (
b.lock.Lock()
defer b.lock.Unlock()
b.previousEpochParticipation = participation
b.markFieldAsDirty(previousEpochParticipationBits)
b.rebuildTrie[previousEpochParticipationBits] = true
b.markFieldAsDirty(nativetypes.PreviousEpochParticipationBits)
b.rebuildTrie[nativetypes.PreviousEpochParticipationBits] = true
return nil
}
@@ -112,12 +113,12 @@ func (b *BeaconState) ModifyCurrentParticipationBits(mutator func(val []byte) ([
b.lock.Lock()
participation := b.currentEpochParticipation
if b.sharedFieldReferences[currentEpochParticipationBits].Refs() > 1 {
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[currentEpochParticipationBits].MinusRef()
b.sharedFieldReferences[currentEpochParticipationBits] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.CurrentEpochParticipationBits].MinusRef()
b.sharedFieldReferences[nativetypes.CurrentEpochParticipationBits] = stateutil.NewRef(1)
}
// Lock is released so that mutator can
// acquire it.
@@ -131,7 +132,7 @@ func (b *BeaconState) ModifyCurrentParticipationBits(mutator func(val []byte) ([
b.lock.Lock()
defer b.lock.Unlock()
b.currentEpochParticipation = participation
b.markFieldAsDirty(currentEpochParticipationBits)
b.rebuildTrie[currentEpochParticipationBits] = true
b.markFieldAsDirty(nativetypes.CurrentEpochParticipationBits)
b.rebuildTrie[nativetypes.CurrentEpochParticipationBits] = true
return nil
}

View File

@@ -1,6 +1,9 @@
package v3
package state_native
import ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
import (
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
)
// SetLatestExecutionPayloadHeader for the beacon state.
func (b *BeaconState) SetLatestExecutionPayloadHeader(val *ethpb.ExecutionPayloadHeader) error {
@@ -8,6 +11,6 @@ func (b *BeaconState) SetLatestExecutionPayloadHeader(val *ethpb.ExecutionPayloa
defer b.lock.Unlock()
b.latestExecutionPayloadHeader = val
b.markFieldAsDirty(latestExecutionPayloadHeader)
b.markFieldAsDirty(nativetypes.LatestExecutionPayloadHeader)
return nil
}

View File

@@ -1,8 +1,9 @@
package v1
package state_native
import (
"github.com/pkg/errors"
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"
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
@@ -14,8 +15,8 @@ func (b *BeaconState) SetRandaoMixes(val [][]byte) error {
b.lock.Lock()
defer b.lock.Unlock()
b.sharedFieldReferences[randaoMixes].MinusRef()
b.sharedFieldReferences[randaoMixes] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.RandaoMixes].MinusRef()
b.sharedFieldReferences[nativetypes.RandaoMixes] = stateutil.NewRef(1)
var mixesArr [fieldparams.RandaoMixesLength][32]byte
for i := 0; i < len(mixesArr); i++ {
@@ -23,8 +24,8 @@ func (b *BeaconState) SetRandaoMixes(val [][]byte) error {
}
mixes := customtypes.RandaoMixes(mixesArr)
b.randaoMixes = &mixes
b.markFieldAsDirty(randaoMixes)
b.rebuildTrie[randaoMixes] = true
b.markFieldAsDirty(nativetypes.RandaoMixes)
b.rebuildTrie[nativetypes.RandaoMixes] = true
return nil
}
@@ -38,19 +39,19 @@ func (b *BeaconState) UpdateRandaoMixesAtIndex(idx uint64, val []byte) error {
defer b.lock.Unlock()
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.
m := *b.randaoMixes
mCopy := m
mixes = &mCopy
b.sharedFieldReferences[randaoMixes].MinusRef()
b.sharedFieldReferences[randaoMixes] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.RandaoMixes].MinusRef()
b.sharedFieldReferences[nativetypes.RandaoMixes] = stateutil.NewRef(1)
}
mixes[idx] = bytesutil.ToBytes32(val)
b.randaoMixes = mixes
b.markFieldAsDirty(randaoMixes)
b.addDirtyIndices(randaoMixes, []uint64{idx})
b.markFieldAsDirty(nativetypes.RandaoMixes)
b.addDirtyIndices(nativetypes.RandaoMixes, []uint64{idx})
return nil
}

View File

@@ -1,8 +1,9 @@
package v1
package state_native
import (
"github.com/pkg/errors"
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"
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
)
@@ -13,8 +14,8 @@ func (b *BeaconState) SetStateRoots(val [][]byte) error {
b.lock.Lock()
defer b.lock.Unlock()
b.sharedFieldReferences[stateRoots].MinusRef()
b.sharedFieldReferences[stateRoots] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.StateRoots].MinusRef()
b.sharedFieldReferences[nativetypes.StateRoots] = stateutil.NewRef(1)
var rootsArr [fieldparams.StateRootsLength][32]byte
for i := 0; i < len(rootsArr); i++ {
@@ -22,8 +23,8 @@ func (b *BeaconState) SetStateRoots(val [][]byte) error {
}
roots := customtypes.StateRoots(rootsArr)
b.stateRoots = &roots
b.markFieldAsDirty(stateRoots)
b.rebuildTrie[stateRoots] = true
b.markFieldAsDirty(nativetypes.StateRoots)
b.rebuildTrie[nativetypes.StateRoots] = true
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.
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.
roots := *b.stateRoots
rootsCopy := roots
r = &rootsCopy
ref.MinusRef()
b.sharedFieldReferences[stateRoots] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.StateRoots] = stateutil.NewRef(1)
}
r[idx] = stateRoot
b.stateRoots = r
b.markFieldAsDirty(stateRoots)
b.addDirtyIndices(stateRoots, []uint64{idx})
b.markFieldAsDirty(nativetypes.StateRoots)
b.addDirtyIndices(nativetypes.StateRoots, []uint64{idx})
return nil
}

View File

@@ -1,6 +1,7 @@
package v3
package state_native
import (
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
)
@@ -10,7 +11,7 @@ func (b *BeaconState) SetCurrentSyncCommittee(val *ethpb.SyncCommittee) error {
defer b.lock.Unlock()
b.currentSyncCommittee = val
b.markFieldAsDirty(currentSyncCommittee)
b.markFieldAsDirty(nativetypes.CurrentSyncCommittee)
return nil
}
@@ -20,6 +21,6 @@ func (b *BeaconState) SetNextSyncCommittee(val *ethpb.SyncCommittee) error {
defer b.lock.Unlock()
b.nextSyncCommittee = val
b.markFieldAsDirty(nextSyncCommittee)
b.markFieldAsDirty(nativetypes.NextSyncCommittee)
return nil
}

View File

@@ -1,8 +1,9 @@
package v3
package state_native
import (
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
nativetypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/types"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
@@ -15,10 +16,10 @@ func (b *BeaconState) SetValidators(val []*ethpb.Validator) error {
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.sharedFieldReferences[nativetypes.Validators].MinusRef()
b.sharedFieldReferences[nativetypes.Validators] = stateutil.NewRef(1)
b.markFieldAsDirty(nativetypes.Validators)
b.rebuildTrie[nativetypes.Validators] = true
b.valMapHandler = stateutil.NewValMapHandler(b.validators)
return nil
}
@@ -28,10 +29,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 {
b.lock.Lock()
v := b.validators
if ref := b.sharedFieldReferences[validators]; ref.Refs() > 1 {
if ref := b.sharedFieldReferences[nativetypes.Validators]; ref.Refs() > 1 {
v = b.validatorsReferences()
ref.MinusRef()
b.sharedFieldReferences[validators] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.Validators] = stateutil.NewRef(1)
}
b.lock.Unlock()
var changedVals []uint64
@@ -50,8 +51,8 @@ func (b *BeaconState) ApplyToEveryValidator(f func(idx int, val *ethpb.Validator
defer b.lock.Unlock()
b.validators = v
b.markFieldAsDirty(validators)
b.addDirtyIndices(validators, changedVals)
b.markFieldAsDirty(nativetypes.Validators)
b.addDirtyIndices(nativetypes.Validators, changedVals)
return nil
}
@@ -66,16 +67,16 @@ func (b *BeaconState) UpdateValidatorAtIndex(idx types.ValidatorIndex, val *ethp
defer b.lock.Unlock()
v := b.validators
if ref := b.sharedFieldReferences[validators]; ref.Refs() > 1 {
if ref := b.sharedFieldReferences[nativetypes.Validators]; ref.Refs() > 1 {
v = b.validatorsReferences()
ref.MinusRef()
b.sharedFieldReferences[validators] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.Validators] = stateutil.NewRef(1)
}
v[idx] = val
b.validators = v
b.markFieldAsDirty(validators)
b.addDirtyIndices(validators, []uint64{uint64(idx)})
b.markFieldAsDirty(nativetypes.Validators)
b.addDirtyIndices(nativetypes.Validators, []uint64{uint64(idx)})
return nil
}
@@ -86,12 +87,12 @@ 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.sharedFieldReferences[nativetypes.Balances].MinusRef()
b.sharedFieldReferences[nativetypes.Balances] = stateutil.NewRef(1)
b.balances = val
b.markFieldAsDirty(balances)
b.rebuildTrie[balances] = true
b.markFieldAsDirty(nativetypes.Balances)
b.rebuildTrie[nativetypes.Balances] = true
return nil
}
@@ -105,16 +106,16 @@ func (b *BeaconState) UpdateBalancesAtIndex(idx types.ValidatorIndex, val uint64
defer b.lock.Unlock()
bals := b.balances
if b.sharedFieldReferences[balances].Refs() > 1 {
if b.sharedFieldReferences[nativetypes.Balances].Refs() > 1 {
bals = b.balancesVal()
b.sharedFieldReferences[balances].MinusRef()
b.sharedFieldReferences[balances] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.Balances].MinusRef()
b.sharedFieldReferences[nativetypes.Balances] = stateutil.NewRef(1)
}
bals[idx] = val
b.balances = bals
b.markFieldAsDirty(balances)
b.addDirtyIndices(balances, []uint64{uint64(idx)})
b.markFieldAsDirty(nativetypes.Balances)
b.addDirtyIndices(nativetypes.Balances, []uint64{uint64(idx)})
return nil
}
@@ -124,11 +125,11 @@ 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.sharedFieldReferences[nativetypes.Slashings].MinusRef()
b.sharedFieldReferences[nativetypes.Slashings] = stateutil.NewRef(1)
b.slashings = val
b.markFieldAsDirty(slashings)
b.markFieldAsDirty(nativetypes.Slashings)
return nil
}
@@ -142,17 +143,17 @@ func (b *BeaconState) UpdateSlashingsAtIndex(idx, val uint64) error {
defer b.lock.Unlock()
s := b.slashings
if b.sharedFieldReferences[slashings].Refs() > 1 {
if b.sharedFieldReferences[nativetypes.Slashings].Refs() > 1 {
s = b.slashingsVal()
b.sharedFieldReferences[slashings].MinusRef()
b.sharedFieldReferences[slashings] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.Slashings].MinusRef()
b.sharedFieldReferences[nativetypes.Slashings] = stateutil.NewRef(1)
}
s[idx] = val
b.slashings = s
b.markFieldAsDirty(slashings)
b.markFieldAsDirty(nativetypes.Slashings)
return nil
}
@@ -163,10 +164,10 @@ func (b *BeaconState) AppendValidator(val *ethpb.Validator) error {
defer b.lock.Unlock()
vals := b.validators
if b.sharedFieldReferences[validators].Refs() > 1 {
if b.sharedFieldReferences[nativetypes.Validators].Refs() > 1 {
vals = b.validatorsReferences()
b.sharedFieldReferences[validators].MinusRef()
b.sharedFieldReferences[validators] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.Validators].MinusRef()
b.sharedFieldReferences[nativetypes.Validators] = stateutil.NewRef(1)
}
// append validator to slice
@@ -175,8 +176,8 @@ func (b *BeaconState) AppendValidator(val *ethpb.Validator) error {
b.valMapHandler.Set(bytesutil.ToBytes48(val.PublicKey), valIdx)
b.markFieldAsDirty(validators)
b.addDirtyIndices(validators, []uint64{uint64(valIdx)})
b.markFieldAsDirty(nativetypes.Validators)
b.addDirtyIndices(nativetypes.Validators, []uint64{uint64(valIdx)})
return nil
}
@@ -187,16 +188,16 @@ func (b *BeaconState) AppendBalance(bal uint64) error {
defer b.lock.Unlock()
bals := b.balances
if b.sharedFieldReferences[balances].Refs() > 1 {
if b.sharedFieldReferences[nativetypes.Balances].Refs() > 1 {
bals = b.balancesVal()
b.sharedFieldReferences[balances].MinusRef()
b.sharedFieldReferences[balances] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.Balances].MinusRef()
b.sharedFieldReferences[nativetypes.Balances] = stateutil.NewRef(1)
}
b.balances = append(bals, bal)
balIdx := len(b.balances) - 1
b.markFieldAsDirty(balances)
b.addDirtyIndices(balances, []uint64{uint64(balIdx)})
b.markFieldAsDirty(nativetypes.Balances)
b.addDirtyIndices(nativetypes.Balances, []uint64{uint64(balIdx)})
return nil
}
@@ -206,14 +207,14 @@ func (b *BeaconState) AppendInactivityScore(s uint64) error {
defer b.lock.Unlock()
scores := b.inactivityScores
if b.sharedFieldReferences[inactivityScores].Refs() > 1 {
if b.sharedFieldReferences[nativetypes.InactivityScores].Refs() > 1 {
scores = b.inactivityScoresVal()
b.sharedFieldReferences[inactivityScores].MinusRef()
b.sharedFieldReferences[inactivityScores] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.InactivityScores].MinusRef()
b.sharedFieldReferences[nativetypes.InactivityScores] = stateutil.NewRef(1)
}
b.inactivityScores = append(scores, s)
b.markFieldAsDirty(inactivityScores)
b.markFieldAsDirty(nativetypes.InactivityScores)
return nil
}
@@ -223,10 +224,10 @@ func (b *BeaconState) SetInactivityScores(val []uint64) error {
b.lock.Lock()
defer b.lock.Unlock()
b.sharedFieldReferences[inactivityScores].MinusRef()
b.sharedFieldReferences[inactivityScores] = stateutil.NewRef(1)
b.sharedFieldReferences[nativetypes.InactivityScores].MinusRef()
b.sharedFieldReferences[nativetypes.InactivityScores] = stateutil.NewRef(1)
b.inactivityScores = val
b.markFieldAsDirty(inactivityScores)
b.markFieldAsDirty(nativetypes.InactivityScores)
return nil
}

View 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
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
package state_native
import (
"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"
)
// 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

View 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"],
)

View File

@@ -0,0 +1,124 @@
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(stateVersion 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 ""
}
}
// 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 (f 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 v1 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
// State Fields Added in Altair.
InactivityScores
CurrentSyncCommittee
NextSyncCommittee
// State fields added in Bellatrix.
LatestExecutionPayloadHeader
)

View File

@@ -1,134 +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 = [
"doc.go",
"field_roots.go",
"getters_attestation.go",
"getters_block.go",
"getters_checkpoint.go",
"getters_eth1.go",
"getters_misc.go",
"getters_randao.go",
"getters_state.go",
"getters_validator.go",
"proofs.go",
"readonly_validator.go",
"setters_attestation.go",
"setters_block.go",
"setters_checkpoint.go",
"setters_eth1.go",
"setters_misc.go",
"setters_randao.go",
"setters_state.go",
"setters_validator.go",
"state_trie.go",
"types.go",
"unsupported_getters.go",
"unsupported_setters.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/v1",
visibility = [
"//beacon-chain:__subpackages__",
"//contracts/deposit:__subpackages__",
"//proto/migration:__subpackages__",
"//proto/prysm/v1alpha1:__subpackages__",
"//proto/testing:__subpackages__",
"//runtime/interop:__subpackages__",
"//slasher/rpc:__subpackages__",
"//testing/benchmark:__pkg__",
"//testing/fuzz:__pkg__",
"//testing/spectest:__subpackages__",
"//testing/util:__pkg__",
"//tools/benchmark-files-gen:__pkg__",
"//tools/pcli:__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/stateutil:go_default_library",
"//beacon-chain/state/types:go_default_library",
"//config/features:go_default_library",
"//config/fieldparams:go_default_library",
"//config/params: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_eth2_types//: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",
],
)
# gazelle:exclude types_bench_test.go
go_test(
name = "go_default_test",
srcs = [
"getters_attestation_test.go",
"getters_block_test.go",
"getters_test.go",
"getters_validator_test.go",
"proofs_test.go",
"readonly_validator_test.go",
"references_test.go",
"setters_attestation_test.go",
"state_test.go",
"state_trie_test.go",
"types_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",
"//config/features:go_default_library",
"//config/fieldparams:go_default_library",
"//config/params:go_default_library",
"//container/trie:go_default_library",
"//encoding/bytesutil:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//runtime/interop:go_default_library",
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
"//testing/util:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
"@com_github_sirupsen_logrus//: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",
"//proto/prysm/v1alpha1:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
],
objs = [
"BeaconState[no-htr]",
],
)

View File

@@ -1,51 +0,0 @@
//go:build !minimal
// +build !minimal
package v1
import (
"sync"
eth2types "github.com/prysmaticlabs/eth2-types"
"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"
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
}

View File

@@ -1,82 +0,0 @@
//go:build !minimal
// +build !minimal
package v1
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("previousEpochAttestations")
require.Equal(t, true, ok, "Required field not found")
v = f.Tag.Get("ssz-max")
assert.Equal(t, strconv.Itoa(fieldparams.PreviousEpochAttestationsLength), v)
f, ok = bsType.FieldByName("currentEpochAttestations")
require.Equal(t, true, ok, "Required field not found")
v = f.Tag.Get("ssz-max")
assert.Equal(t, strconv.Itoa(fieldparams.CurrentEpochAttestationsLength), 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)
}

View File

@@ -1,51 +0,0 @@
//go:build minimal
// +build minimal
package v1
import (
"sync"
eth2types "github.com/prysmaticlabs/eth2-types"
"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"
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
}

View File

@@ -1,82 +0,0 @@
//go:build minimal
// +build minimal
package v1
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("previousEpochAttestations")
require.Equal(t, true, ok, "Required field not found")
v = f.Tag.Get("ssz-max")
assert.Equal(t, strconv.Itoa(fieldparams.PreviousEpochAttestationsLength), v)
f, ok = bsType.FieldByName("currentEpochAttestations")
require.Equal(t, true, ok, "Required field not found")
v = f.Tag.Get("ssz-max")
assert.Equal(t, strconv.Itoa(fieldparams.CurrentEpochAttestationsLength), 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)
}

View File

@@ -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)
}

View File

@@ -1,493 +0,0 @@
// Code generated by fastssz. DO NOT EDIT.
// Hash: 2e923b42b8e4fcc278301da6506b212334a78169cb32c70e0d66a636435b8925
package v1
import (
ssz "github.com/ferranbt/fastssz"
eth2types "github.com/prysmaticlabs/eth2-types"
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
}

View File

@@ -1,46 +0,0 @@
package v1
import (
"testing"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/testing/require"
)
func TestBeaconState_PreviousEpochAttestations(t *testing.T) {
s, err := InitializeFromProto(&ethpb.BeaconState{})
require.NoError(t, err)
atts, err := s.PreviousEpochAttestations()
require.NoError(t, err)
require.DeepEqual(t, []*ethpb.PendingAttestation(nil), atts)
want := []*ethpb.PendingAttestation{{ProposerIndex: 100}}
s, err = InitializeFromProto(&ethpb.BeaconState{PreviousEpochAttestations: want})
require.NoError(t, err)
got, err := s.PreviousEpochAttestations()
require.NoError(t, err)
require.DeepEqual(t, want, got)
// Test copy does not mutate.
got[0].ProposerIndex = 101
require.DeepNotEqual(t, want, got)
}
func TestBeaconState_CurrentEpochAttestations(t *testing.T) {
s, err := InitializeFromProto(&ethpb.BeaconState{})
require.NoError(t, err)
atts, err := s.CurrentEpochAttestations()
require.NoError(t, err)
require.DeepEqual(t, []*ethpb.PendingAttestation(nil), atts)
want := []*ethpb.PendingAttestation{{ProposerIndex: 101}}
s, err = InitializeFromProto(&ethpb.BeaconState{CurrentEpochAttestations: want})
require.NoError(t, err)
got, err := s.CurrentEpochAttestations()
require.NoError(t, err)
require.DeepEqual(t, want, got)
// Test copy does not mutate.
got[0].ProposerIndex = 102
require.DeepNotEqual(t, want, got)
}

View File

@@ -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(&ethpb.BeaconState{})
},
func(BH *ethpb.BeaconBlockHeader) (state.BeaconState, error) {
return InitializeFromProto(&ethpb.BeaconState{LatestBlockHeader: BH})
},
)
}
func TestBeaconState_BlockRoots(t *testing.T) {
testtmpl.VerifyBeaconStateBlockRootsNative(
t,
func() (state.BeaconState, error) {
return InitializeFromProto(&ethpb.BeaconState{})
},
func(BR [][]byte) (state.BeaconState, error) {
return InitializeFromProto(&ethpb.BeaconState{BlockRoots: BR})
},
)
}
func TestBeaconState_BlockRootAtIndex(t *testing.T) {
testtmpl.VerifyBeaconStateBlockRootAtIndexNative(
t,
func() (state.BeaconState, error) {
return InitializeFromProto(&ethpb.BeaconState{})
},
func(BR [][]byte) (state.BeaconState, error) {
return InitializeFromProto(&ethpb.BeaconState{BlockRoots: BR})
},
)
}

View File

@@ -1,124 +0,0 @@
package v1
import (
"bytes"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/go-bitfield"
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
}

View File

@@ -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(&ethpb.BeaconState{})
})
}
func TestBeaconState_JustificationBits(t *testing.T) {
testtmpl.VerifyBeaconStateJustificationBits(
t,
func(bits bitfield.Bitvector4) (state.BeaconState, error) {
return InitializeFromProtoUnsafe(&ethpb.BeaconState{JustificationBits: bits})
})
}
func TestBeaconState_PreviousJustifiedCheckpointNil(t *testing.T) {
testtmpl.VerifyBeaconStatePreviousJustifiedCheckpointNil(
t,
func() (state.BeaconState, error) {
return InitializeFromProtoUnsafe(&ethpb.BeaconState{})
})
}
func TestBeaconState_PreviousJustifiedCheckpoint(t *testing.T) {
testtmpl.VerifyBeaconStatePreviousJustifiedCheckpoint(
t,
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
return InitializeFromProtoUnsafe(&ethpb.BeaconState{PreviousJustifiedCheckpoint: cp})
})
}
func TestBeaconState_CurrentJustifiedCheckpointNil(t *testing.T) {
testtmpl.VerifyBeaconStateCurrentJustifiedCheckpointNil(
t,
func() (state.BeaconState, error) {
return InitializeFromProtoUnsafe(&ethpb.BeaconState{})
})
}
func TestBeaconState_CurrentJustifiedCheckpoint(t *testing.T) {
testtmpl.VerifyBeaconStateCurrentJustifiedCheckpoint(
t,
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
return InitializeFromProtoUnsafe(&ethpb.BeaconState{CurrentJustifiedCheckpoint: cp})
})
}
func TestBeaconState_FinalizedCheckpointNil(t *testing.T) {
testtmpl.VerifyBeaconStateFinalizedCheckpointNil(
t,
func() (state.BeaconState, error) {
return InitializeFromProtoUnsafe(&ethpb.BeaconState{})
})
}
func TestBeaconState_FinalizedCheckpoint(t *testing.T) {
testtmpl.VerifyBeaconStateFinalizedCheckpoint(
t,
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
return InitializeFromProtoUnsafe(&ethpb.BeaconState{FinalizedCheckpoint: cp})
})
}

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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(&ethpb.BeaconState{Slot: 1})
})
}
func TestBeaconState_MatchCurrentJustifiedCheckpt(t *testing.T) {
testtmpl.VerifyBeaconStateMatchCurrentJustifiedCheckptNative(
t,
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
return InitializeFromProto(&ethpb.BeaconState{CurrentJustifiedCheckpoint: cp})
},
)
}
func TestBeaconState_MatchPreviousJustifiedCheckpt(t *testing.T) {
testtmpl.VerifyBeaconStateMatchPreviousJustifiedCheckptNative(
t,
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
return InitializeFromProto(&ethpb.BeaconState{PreviousJustifiedCheckpoint: cp})
},
)
}
func TestBeaconState_ValidatorByPubkey(t *testing.T) {
testtmpl.VerifyBeaconStateValidatorByPubkey(t, func() (state.BeaconState, error) {
return InitializeFromProto(&ethpb.BeaconState{})
})
}

View File

@@ -1,250 +0,0 @@
package v1
import (
"fmt"
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
"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 &ethpb.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
}

View File

@@ -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(&ethpb.BeaconState{
Validators: nil,
})
})
}

View File

@@ -1,64 +0,0 @@
package v1_test
import (
"context"
"testing"
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/v1"
"github.com/prysmaticlabs/prysm/container/trie"
"github.com/prysmaticlabs/prysm/testing/require"
"github.com/prysmaticlabs/prysm/testing/util"
)
func TestBeaconStateMerkleProofs(t *testing.T) {
ctx := context.Background()
st, _ := util.DeterministicGenesisState(t, 256)
htr, err := st.HashTreeRoot(ctx)
require.NoError(t, err)
t.Run("current sync committee", func(t *testing.T) {
_, err := st.CurrentSyncCommitteeProof(ctx)
require.ErrorContains(t, "unsupported", err)
})
t.Run("next sync committee", func(t *testing.T) {
_, err := st.NextSyncCommitteeProof(ctx)
require.ErrorContains(t, "unsupported", err)
})
t.Run("finalized root", func(t *testing.T) {
finalizedRoot := st.FinalizedCheckpoint().Root
proof, err := st.FinalizedRootProof(ctx)
require.NoError(t, err)
gIndex := v1.FinalizedRootGeneralizedIndex()
valid := trie.VerifyMerkleProof(htr[:], finalizedRoot, gIndex, proof)
require.Equal(t, true, valid)
})
t.Run("recomputes root on dirty fields", func(t *testing.T) {
currentRoot, err := st.HashTreeRoot(ctx)
require.NoError(t, err)
cpt := st.FinalizedCheckpoint()
require.NoError(t, err)
// Edit the checkpoint.
cpt.Epoch = 100
require.NoError(t, st.SetFinalizedCheckpoint(cpt))
// Produce a proof for the finalized root.
proof, err := st.FinalizedRootProof(ctx)
require.NoError(t, err)
// We expect the previous step to have triggered
// a recomputation of dirty fields in the beacon state, resulting
// in a new hash tree root as the finalized checkpoint had previously
// 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.
finalizedRoot := st.FinalizedCheckpoint().Root
gIndex := v1.FinalizedRootGeneralizedIndex()
valid := trie.VerifyMerkleProof(currentRoot[:], finalizedRoot, gIndex, proof)
require.Equal(t, false, valid)
newRoot, err := st.HashTreeRoot(ctx)
require.NoError(t, err)
valid = trie.VerifyMerkleProof(newRoot[:], finalizedRoot, gIndex, proof)
require.Equal(t, true, valid)
})
}

View File

@@ -1,74 +0,0 @@
package v1_test
import (
"testing"
types "github.com/prysmaticlabs/eth2-types"
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/v1"
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/testing/assert"
"github.com/prysmaticlabs/prysm/testing/require"
)
func TestReadOnlyValidator_ReturnsErrorOnNil(t *testing.T) {
if _, err := v1.NewValidator(nil); err != v1.ErrNilWrappedValidator {
t.Errorf("Wrong error returned. Got %v, wanted %v", err, v1.ErrNilWrappedValidator)
}
}
func TestReadOnlyValidator_EffectiveBalance(t *testing.T) {
bal := uint64(234)
v, err := v1.NewValidator(&ethpb.Validator{EffectiveBalance: bal})
require.NoError(t, err)
assert.Equal(t, bal, v.EffectiveBalance())
}
func TestReadOnlyValidator_ActivationEligibilityEpoch(t *testing.T) {
epoch := types.Epoch(234)
v, err := v1.NewValidator(&ethpb.Validator{ActivationEligibilityEpoch: epoch})
require.NoError(t, err)
assert.Equal(t, epoch, v.ActivationEligibilityEpoch())
}
func TestReadOnlyValidator_ActivationEpoch(t *testing.T) {
epoch := types.Epoch(234)
v, err := v1.NewValidator(&ethpb.Validator{ActivationEpoch: epoch})
require.NoError(t, err)
assert.Equal(t, epoch, v.ActivationEpoch())
}
func TestReadOnlyValidator_WithdrawableEpoch(t *testing.T) {
epoch := types.Epoch(234)
v, err := v1.NewValidator(&ethpb.Validator{WithdrawableEpoch: epoch})
require.NoError(t, err)
assert.Equal(t, epoch, v.WithdrawableEpoch())
}
func TestReadOnlyValidator_ExitEpoch(t *testing.T) {
epoch := types.Epoch(234)
v, err := v1.NewValidator(&ethpb.Validator{ExitEpoch: epoch})
require.NoError(t, err)
assert.Equal(t, epoch, v.ExitEpoch())
}
func TestReadOnlyValidator_PublicKey(t *testing.T) {
key := [fieldparams.BLSPubkeyLength]byte{0xFA, 0xCC}
v, err := v1.NewValidator(&ethpb.Validator{PublicKey: key[:]})
require.NoError(t, err)
assert.Equal(t, key, v.PublicKey())
}
func TestReadOnlyValidator_WithdrawalCredentials(t *testing.T) {
creds := []byte{0xFA, 0xCC}
v, err := v1.NewValidator(&ethpb.Validator{WithdrawalCredentials: creds})
require.NoError(t, err)
assert.DeepEqual(t, creds, v.WithdrawalCredentials())
}
func TestReadOnlyValidator_Slashed(t *testing.T) {
slashed := true
v, err := v1.NewValidator(&ethpb.Validator{Slashed: slashed})
require.NoError(t, err)
assert.Equal(t, slashed, v.Slashed())
}

View File

@@ -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(&ethpb.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(&ethpb.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(&ethpb.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(&ethpb.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(&ethpb.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, &ethpb.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, &ethpb.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
}
}
}

View File

@@ -1,26 +0,0 @@
package v1
import (
"testing"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/testing/require"
)
func TestBeaconState_RotateAttestations(t *testing.T) {
st, err := InitializeFromProto(&ethpb.BeaconState{
Slot: 1,
CurrentEpochAttestations: []*ethpb.PendingAttestation{{Data: &ethpb.AttestationData{Slot: 456}}},
PreviousEpochAttestations: []*ethpb.PendingAttestation{{Data: &ethpb.AttestationData{Slot: 123}}},
})
require.NoError(t, err)
require.NoError(t, st.RotateAttestations())
currEpochAtts, err := st.CurrentEpochAttestations()
require.NoError(t, err)
require.Equal(t, 0, len(currEpochAtts))
prevEpochAtts, err := st.PreviousEpochAttestations()
require.NoError(t, err)
require.Equal(t, types.Slot(456), prevEpochAtts[0].Data.Slot)
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -1,201 +0,0 @@
package v1
import (
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
"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
}

View File

@@ -1,208 +0,0 @@
package v1
import (
"context"
"strconv"
"sync"
"testing"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/go-bitfield"
"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/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/testing/assert"
"github.com/prysmaticlabs/prysm/testing/require"
)
func TestValidatorMap_DistinctCopy(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, &ethpb.Validator{
PublicKey: someKey[:],
WithdrawalCredentials: someRoot[:],
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
Slashed: false,
ActivationEligibilityEpoch: 1,
ActivationEpoch: 1,
ExitEpoch: 1,
WithdrawableEpoch: 1,
})
}
handler := stateutil.NewValMapHandler(vals)
newHandler := handler.Copy()
wantedPubkey := strconv.Itoa(22)
handler.Set(bytesutil.ToBytes48([]byte(wantedPubkey)), 27)
val1, _ := handler.Get(bytesutil.ToBytes48([]byte(wantedPubkey)))
val2, _ := newHandler.Get(bytesutil.ToBytes48([]byte(wantedPubkey)))
assert.NotEqual(t, val1, val2, "Values are supposed to be unequal due to copy")
}
func TestBeaconState_NoDeadlock(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, &ethpb.Validator{
PublicKey: someKey[:],
WithdrawalCredentials: someRoot[:],
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
Slashed: false,
ActivationEligibilityEpoch: 1,
ActivationEpoch: 1,
ExitEpoch: 1,
WithdrawableEpoch: 1,
})
}
st, err := InitializeFromProtoUnsafe(&ethpb.BeaconState{
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 TestStateTrie_IsNil(t *testing.T) {
var emptyState *BeaconState
assert.Equal(t, true, emptyState.IsNil())
}
func TestBeaconState_AppendBalanceWithTrie(t *testing.T) {
count := uint64(100)
vals := make([]*ethpb.Validator, 0, count)
bals := make([]uint64, 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, &ethpb.Validator{
PublicKey: someKey[:],
WithdrawalCredentials: someRoot[:],
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
Slashed: false,
ActivationEligibilityEpoch: 1,
ActivationEpoch: 1,
ExitEpoch: 1,
WithdrawableEpoch: 1,
})
bals = append(bals, params.BeaconConfig().MaxEffectiveBalance)
}
zeroHash := params.BeaconConfig().ZeroHash
mockblockRoots := make([][]byte, params.BeaconConfig().SlotsPerHistoricalRoot)
for i := 0; i < len(mockblockRoots); i++ {
mockblockRoots[i] = zeroHash[:]
}
mockstateRoots := make([][]byte, params.BeaconConfig().SlotsPerHistoricalRoot)
for i := 0; i < len(mockstateRoots); i++ {
mockstateRoots[i] = zeroHash[:]
}
mockrandaoMixes := make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector)
for i := 0; i < len(mockrandaoMixes); i++ {
mockrandaoMixes[i] = zeroHash[:]
}
st, err := InitializeFromProto(&ethpb.BeaconState{
Slot: 1,
GenesisValidatorsRoot: make([]byte, 32),
Fork: &ethpb.Fork{
PreviousVersion: make([]byte, 4),
CurrentVersion: make([]byte, 4),
Epoch: 0,
},
LatestBlockHeader: &ethpb.BeaconBlockHeader{
ParentRoot: make([]byte, fieldparams.RootLength),
StateRoot: make([]byte, fieldparams.RootLength),
BodyRoot: make([]byte, fieldparams.RootLength),
},
Validators: vals,
Balances: bals,
Eth1Data: &ethpb.Eth1Data{
DepositRoot: make([]byte, 32),
BlockHash: make([]byte, 32),
},
BlockRoots: mockblockRoots,
StateRoots: mockstateRoots,
RandaoMixes: mockrandaoMixes,
JustificationBits: bitfield.NewBitvector4(),
PreviousJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
CurrentJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
Slashings: make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector),
})
assert.NoError(t, err)
_, err = st.HashTreeRoot(context.Background())
assert.NoError(t, err)
for i := 0; i < 100; i++ {
if i%2 == 0 {
assert.NoError(t, st.UpdateBalancesAtIndex(types.ValidatorIndex(i), 1000))
}
if i%3 == 0 {
assert.NoError(t, st.AppendBalance(1000))
}
}
_, err = st.HashTreeRoot(context.Background())
assert.NoError(t, err)
s, ok := st.(*BeaconState)
require.Equal(t, true, ok)
newRt := bytesutil.ToBytes32(s.merkleLayers[0][balances])
wantedRt, err := stateutil.Uint64ListRootWithRegistryLimit(s.Balances())
assert.NoError(t, err)
assert.Equal(t, wantedRt, newRt, "state roots are unequal")
}
func TestBeaconState_ModifyPreviousParticipationBits(t *testing.T) {
st, err := InitializeFromProtoUnsafe(&ethpb.BeaconState{})
assert.NoError(t, err)
assert.ErrorContains(t, "ModifyPreviousParticipationBits is not supported for phase 0 beacon state", st.ModifyPreviousParticipationBits(func(val []byte) ([]byte, error) {
return nil, nil
}))
}
func TestBeaconState_ModifyCurrentParticipationBits(t *testing.T) {
st, err := InitializeFromProtoUnsafe(&ethpb.BeaconState{})
assert.NoError(t, err)
assert.ErrorContains(t, "ModifyCurrentParticipationBits is not supported for phase 0 beacon state", st.ModifyCurrentParticipationBits(func(val []byte) ([]byte, error) {
return nil, nil
}))
}

View File

@@ -1,479 +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"
"github.com/prysmaticlabs/prysm/config/features"
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 features.Get().EnableBalanceTrieComputation {
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)
}
return stateutil.Uint64ListRootWithRegistryLimit(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
}

View File

@@ -1,278 +0,0 @@
package v1_test
import (
"bytes"
"context"
"testing"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/v1"
"github.com/prysmaticlabs/prysm/config/features"
"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 TestMain(m *testing.M) {
resetCfg := features.InitWithReset(&features.Flags{EnableBalanceTrieComputation: true})
defer resetCfg()
m.Run()
}
func TestInitializeFromProto(t *testing.T) {
testState, _ := util.DeterministicGenesisState(t, 64)
pbState, err := v1.ProtobufBeaconState(testState.InnerStateUnsafe())
require.NoError(t, err)
type test struct {
name string
state *ethpb.BeaconState
error string
}
initTests := []test{
{
name: "nil state",
state: nil,
error: "received nil state",
},
{
name: "nil validators",
state: &ethpb.BeaconState{
Slot: 4,
Validators: nil,
},
},
{
name: "empty state",
state: &ethpb.BeaconState{},
},
{
name: "full state",
state: pbState,
},
}
for _, tt := range initTests {
t.Run(tt.name, func(t *testing.T) {
_, err := v1.InitializeFromProto(tt.state)
if tt.error != "" {
assert.ErrorContains(t, tt.error, err)
} else {
assert.NoError(t, err)
}
})
}
}
func TestInitializeFromProtoUnsafe(t *testing.T) {
testState, _ := util.DeterministicGenesisState(t, 64)
pbState, err := v1.ProtobufBeaconState(testState.InnerStateUnsafe())
require.NoError(t, err)
type test struct {
name string
state *ethpb.BeaconState
error string
}
initTests := []test{
{
name: "nil state",
state: nil,
error: "received nil state",
},
{
name: "nil validators",
state: &ethpb.BeaconState{
Slot: 4,
Validators: nil,
},
},
{
name: "empty state",
state: &ethpb.BeaconState{},
},
{
name: "full state",
state: pbState,
},
}
for _, tt := range initTests {
t.Run(tt.name, func(t *testing.T) {
_, err := v1.InitializeFromProtoUnsafe(tt.state)
if tt.error != "" {
assert.ErrorContains(t, tt.error, err)
} else {
assert.NoError(t, err)
}
})
}
}
func TestBeaconState_HashTreeRoot(t *testing.T) {
testState, _ := util.DeterministicGenesisState(t, 64)
type test struct {
name string
stateModify func(beaconState state.BeaconState) (state.BeaconState, error)
error string
}
initTests := []test{
{
name: "unchanged state",
stateModify: func(beaconState state.BeaconState) (state.BeaconState, error) {
return beaconState, nil
},
error: "",
},
{
name: "different slot",
stateModify: func(beaconState state.BeaconState) (state.BeaconState, error) {
if err := beaconState.SetSlot(5); err != nil {
return nil, err
}
return beaconState, nil
},
error: "",
},
{
name: "different validator balance",
stateModify: func(beaconState state.BeaconState) (state.BeaconState, error) {
val, err := beaconState.ValidatorAtIndex(5)
if err != nil {
return nil, err
}
val.EffectiveBalance = params.BeaconConfig().MaxEffectiveBalance - params.BeaconConfig().EffectiveBalanceIncrement
if err := beaconState.UpdateValidatorAtIndex(5, val); err != nil {
return nil, err
}
return beaconState, nil
},
error: "",
},
}
var err error
var oldHTR []byte
for _, tt := range initTests {
t.Run(tt.name, func(t *testing.T) {
testState, err = tt.stateModify(testState)
assert.NoError(t, err)
root, err := testState.HashTreeRoot(context.Background())
if err == nil && tt.error != "" {
t.Errorf("Expected error, expected %v, recevied %v", tt.error, err)
}
pbState, err := v1.ProtobufBeaconState(testState.InnerStateUnsafe())
require.NoError(t, err)
genericHTR, err := pbState.HashTreeRoot()
if err == nil && tt.error != "" {
t.Errorf("Expected error, expected %v, recevied %v", tt.error, err)
}
assert.DeepNotEqual(t, []byte{}, root[:], "Received empty hash tree root")
assert.DeepEqual(t, genericHTR[:], root[:], "Expected hash tree root to match generic")
if len(oldHTR) != 0 && bytes.Equal(root[:], oldHTR) {
t.Errorf("Expected HTR to change, received %#x == old %#x", root, oldHTR)
}
oldHTR = root[:]
})
}
}
func TestBeaconState_HashTreeRoot_FieldTrie(t *testing.T) {
testState, _ := util.DeterministicGenesisState(t, 64)
type test struct {
name string
stateModify func(state.BeaconState) (state.BeaconState, error)
error string
}
initTests := []test{
{
name: "unchanged state",
stateModify: func(beaconState state.BeaconState) (state.BeaconState, error) {
return beaconState, nil
},
error: "",
},
{
name: "different slot",
stateModify: func(beaconState state.BeaconState) (state.BeaconState, error) {
if err := beaconState.SetSlot(5); err != nil {
return nil, err
}
return beaconState, nil
},
error: "",
},
{
name: "different validator balance",
stateModify: func(beaconState state.BeaconState) (state.BeaconState, error) {
val, err := beaconState.ValidatorAtIndex(5)
if err != nil {
return nil, err
}
val.EffectiveBalance = params.BeaconConfig().MaxEffectiveBalance - params.BeaconConfig().EffectiveBalanceIncrement
if err := beaconState.UpdateValidatorAtIndex(5, val); err != nil {
return nil, err
}
return beaconState, nil
},
error: "",
},
}
var err error
var oldHTR []byte
for _, tt := range initTests {
t.Run(tt.name, func(t *testing.T) {
testState, err = tt.stateModify(testState)
assert.NoError(t, err)
root, err := testState.HashTreeRoot(context.Background())
if err == nil && tt.error != "" {
t.Errorf("Expected error, expected %v, recevied %v", tt.error, err)
}
pbState, err := v1.ProtobufBeaconState(testState.InnerStateUnsafe())
require.NoError(t, err)
genericHTR, err := pbState.HashTreeRoot()
if err == nil && tt.error != "" {
t.Errorf("Expected error, expected %v, recevied %v", tt.error, err)
}
assert.DeepNotEqual(t, []byte{}, root[:], "Received empty hash tree root")
assert.DeepEqual(t, genericHTR[:], root[:], "Expected hash tree root to match generic")
if len(oldHTR) != 0 && bytes.Equal(root[:], oldHTR) {
t.Errorf("Expected HTR to change, received %#x == old %#x", root, oldHTR)
}
oldHTR = root[:]
})
}
}
func TestBeaconState_AppendValidator_DoesntMutateCopy(t *testing.T) {
st0, err := util.NewBeaconState()
require.NoError(t, err)
st1 := st0.Copy()
originalCount := st1.NumValidators()
val := &ethpb.Validator{Slashed: true}
assert.NoError(t, st0.AppendValidator(val))
assert.Equal(t, originalCount, st1.NumValidators(), "st1 NumValidators mutated")
_, 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")
}
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)
})
}

View File

@@ -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
)

View File

@@ -1,236 +0,0 @@
package v1_test
import (
"context"
"reflect"
"strconv"
"testing"
v1 "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/v1"
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
"github.com/prysmaticlabs/prysm/config/params"
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/runtime/interop"
"github.com/prysmaticlabs/prysm/testing/assert"
"github.com/prysmaticlabs/prysm/testing/require"
log "github.com/sirupsen/logrus"
"google.golang.org/protobuf/proto"
)
func TestBeaconState_ProtoBeaconStateCompatibility(t *testing.T) {
params.SetupTestConfigCleanup(t)
cfg := params.MinimalSpecConfig()
cfg.SlotsPerHistoricalRoot = fieldparams.BlockRootsLength
cfg.EpochsPerHistoricalVector = fieldparams.RandaoMixesLength
params.OverrideBeaconConfig(cfg)
ctx := context.Background()
genesis := setupGenesisState(t, 64)
customState, err := v1.InitializeFromProto(genesis)
require.NoError(t, err)
cloned, ok := proto.Clone(genesis).(*ethpb.BeaconState)
assert.Equal(t, true, ok, "Object is not of type *ethpb.BeaconState")
custom := customState.CloneInnerState()
assert.DeepSSZEqual(t, cloned, custom)
r1, err := customState.HashTreeRoot(ctx)
require.NoError(t, err)
beaconState, err := v1.InitializeFromProto(genesis)
require.NoError(t, err)
r2, err := beaconState.HashTreeRoot(context.Background())
require.NoError(t, err)
assert.Equal(t, r1, r2, "Mismatched roots")
// We then write to the the state and compare hash tree roots again.
balances := genesis.Balances
balances[0] = 3823
require.NoError(t, customState.SetBalances(balances))
r1, err = customState.HashTreeRoot(ctx)
require.NoError(t, err)
genesis.Balances = balances
beaconState, err = v1.InitializeFromProto(genesis)
require.NoError(t, err)
r2, err = beaconState.HashTreeRoot(context.Background())
require.NoError(t, err)
assert.Equal(t, r1, r2, "Mismatched roots")
}
func setupGenesisState(tb testing.TB, count uint64) *ethpb.BeaconState {
genesisState, _, err := interop.GenerateGenesisState(context.Background(), 0, count)
require.NoError(tb, err, "Could not generate genesis beacon state")
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)))
genesisState.Validators = append(genesisState.Validators, &ethpb.Validator{
PublicKey: someKey[:],
WithdrawalCredentials: someRoot[:],
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
Slashed: false,
ActivationEligibilityEpoch: 1,
ActivationEpoch: 1,
ExitEpoch: 1,
WithdrawableEpoch: 1,
})
genesisState.Balances = append(genesisState.Balances, params.BeaconConfig().MaxEffectiveBalance)
}
return genesisState
}
func BenchmarkCloneValidators_Proto(b *testing.B) {
b.StopTimer()
validators := make([]*ethpb.Validator, 16384)
somePubKey := [fieldparams.BLSPubkeyLength]byte{1, 2, 3}
someRoot := [32]byte{3, 4, 5}
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
PublicKey: somePubKey[:],
WithdrawalCredentials: someRoot[:],
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
Slashed: false,
ActivationEligibilityEpoch: params.BeaconConfig().FarFutureEpoch,
ActivationEpoch: 3,
ExitEpoch: 4,
WithdrawableEpoch: 5,
}
}
b.StartTimer()
for i := 0; i < b.N; i++ {
cloneValidatorsWithProto(validators)
}
}
func BenchmarkCloneValidators_Manual(b *testing.B) {
b.StopTimer()
validators := make([]*ethpb.Validator, 16384)
somePubKey := [fieldparams.BLSPubkeyLength]byte{1, 2, 3}
someRoot := [32]byte{3, 4, 5}
for i := 0; i < len(validators); i++ {
validators[i] = &ethpb.Validator{
PublicKey: somePubKey[:],
WithdrawalCredentials: someRoot[:],
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
Slashed: false,
ActivationEligibilityEpoch: params.BeaconConfig().FarFutureEpoch,
ActivationEpoch: 3,
ExitEpoch: 4,
WithdrawableEpoch: 5,
}
}
b.StartTimer()
for i := 0; i < b.N; i++ {
cloneValidatorsManually(validators)
}
}
func BenchmarkStateClone_Proto(b *testing.B) {
b.StopTimer()
params.SetupTestConfigCleanup(b)
params.OverrideBeaconConfig(params.MinimalSpecConfig())
genesis := setupGenesisState(b, 64)
b.StartTimer()
for i := 0; i < b.N; i++ {
_, ok := proto.Clone(genesis).(*ethpb.BeaconState)
assert.Equal(b, true, ok, "Entity is not of type *ethpb.BeaconState")
}
}
func BenchmarkStateClone_Manual(b *testing.B) {
b.StopTimer()
params.SetupTestConfigCleanup(b)
params.OverrideBeaconConfig(params.MinimalSpecConfig())
genesis := setupGenesisState(b, 64)
st, err := v1.InitializeFromProto(genesis)
require.NoError(b, err)
b.StartTimer()
for i := 0; i < b.N; i++ {
_ = st.CloneInnerState()
}
}
func cloneValidatorsWithProto(vals []*ethpb.Validator) []*ethpb.Validator {
var ok bool
res := make([]*ethpb.Validator, len(vals))
for i := 0; i < len(res); i++ {
res[i], ok = proto.Clone(vals[i]).(*ethpb.Validator)
if !ok {
log.Debug("Entity is not of type *ethpb.Validator")
}
}
return res
}
func cloneValidatorsManually(vals []*ethpb.Validator) []*ethpb.Validator {
res := make([]*ethpb.Validator, len(vals))
for i := 0; i < len(res); i++ {
val := vals[i]
res[i] = &ethpb.Validator{
PublicKey: val.PublicKey,
WithdrawalCredentials: val.WithdrawalCredentials,
EffectiveBalance: val.EffectiveBalance,
Slashed: val.Slashed,
ActivationEligibilityEpoch: val.ActivationEligibilityEpoch,
ActivationEpoch: val.ActivationEpoch,
ExitEpoch: val.ExitEpoch,
WithdrawableEpoch: val.WithdrawableEpoch,
}
}
return res
}
func TestBeaconState_ImmutabilityWithSharedResources(t *testing.T) {
params.SetupTestConfigCleanup(t)
params.OverrideBeaconConfig(params.MinimalSpecConfig())
genesis := setupGenesisState(t, 64)
a, err := v1.InitializeFromProto(genesis)
require.NoError(t, err)
b := a.Copy()
// Randao mixes
require.DeepEqual(t, a.RandaoMixes(), b.RandaoMixes(), "Test precondition failed, fields are not equal")
require.NoError(t, a.UpdateRandaoMixesAtIndex(1, []byte("foo")))
if reflect.DeepEqual(a.RandaoMixes(), b.RandaoMixes()) {
t.Error("Expect a.RandaoMixes() to be different from b.RandaoMixes()")
}
// Validators
require.DeepEqual(t, a.Validators(), b.Validators(), "Test precondition failed, fields are not equal")
require.NoError(t, a.UpdateValidatorAtIndex(1, &ethpb.Validator{Slashed: true}))
if reflect.DeepEqual(a.Validators(), b.Validators()) {
t.Error("Expect a.Validators() to be different from b.Validators()")
}
// State Roots
require.DeepEqual(t, a.StateRoots(), b.StateRoots(), "Test precondition failed, fields are not equal")
require.NoError(t, a.UpdateStateRootAtIndex(1, bytesutil.ToBytes32([]byte("foo"))))
if reflect.DeepEqual(a.StateRoots(), b.StateRoots()) {
t.Fatal("Expected a.StateRoots() to be different from b.StateRoots()")
}
// Block Roots
require.DeepEqual(t, a.BlockRoots(), b.BlockRoots(), "Test precondition failed, fields are not equal")
require.NoError(t, a.UpdateBlockRootAtIndex(1, bytesutil.ToBytes32([]byte("foo"))))
if reflect.DeepEqual(a.BlockRoots(), b.BlockRoots()) {
t.Fatal("Expected a.BlockRoots() to be different from b.BlockRoots()")
}
}
func TestForkManualCopy_OK(t *testing.T) {
params.SetupTestConfigCleanup(t)
params.OverrideBeaconConfig(params.MinimalSpecConfig())
genesis := setupGenesisState(t, 64)
a, err := v1.InitializeFromProto(genesis)
require.NoError(t, err)
wantedFork := &ethpb.Fork{
PreviousVersion: []byte{'a', 'b', 'c'},
CurrentVersion: []byte{'d', 'e', 'f'},
Epoch: 0,
}
require.NoError(t, a.SetFork(wantedFork))
pbState, err := v1.ProtobufBeaconState(a.InnerStateUnsafe())
require.NoError(t, err)
require.DeepEqual(t, pbState.Fork, wantedFork)
}

View File

@@ -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")
}

View File

@@ -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")
}

View File

@@ -1,121 +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/features:go_default_library",
"//config/fieldparams:go_default_library",
"//config/params: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_eth2_types//: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/features:go_default_library",
"//config/fieldparams:go_default_library",
"//config/params: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_eth2_types//: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",
"//proto/prysm/v1alpha1:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
],
objs = [
"BeaconState[no-htr]",
],
)

View File

@@ -1,54 +0,0 @@
//go:build !minimal
// +build !minimal
package v2
import (
"sync"
eth2types "github.com/prysmaticlabs/eth2-types"
"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"
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
}

View File

@@ -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)
}

View File

@@ -1,54 +0,0 @@
//go:build minimal
// +build minimal
package v2
import (
"sync"
eth2types "github.com/prysmaticlabs/eth2-types"
"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"
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
}

View File

@@ -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)
}

View File

@@ -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")
}

View File

@@ -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)
}

View File

@@ -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")
}

View File

@@ -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))
}

View File

@@ -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)
}

View File

@@ -1,505 +0,0 @@
// Code generated by fastssz. DO NOT EDIT.
// Hash: ec98b14e43fd11e74e0d9e705a7afe74a77706c3e215d7940b11411859873f4b
package v2
import (
ssz "github.com/ferranbt/fastssz"
eth2types "github.com/prysmaticlabs/eth2-types"
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
}

View File

@@ -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 := &ethpb.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
}

View File

@@ -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(&ethpb.BeaconStateAltair{})
},
func(BH *ethpb.BeaconBlockHeader) (state.BeaconState, error) {
return InitializeFromProto(&ethpb.BeaconStateAltair{LatestBlockHeader: BH})
},
)
}
func TestBeaconState_BlockRoots(t *testing.T) {
testtmpl.VerifyBeaconStateBlockRootsNative(
t,
func() (state.BeaconState, error) {
return InitializeFromProto(&ethpb.BeaconStateAltair{})
},
func(BR [][]byte) (state.BeaconState, error) {
return InitializeFromProto(&ethpb.BeaconStateAltair{BlockRoots: BR})
},
)
}
func TestBeaconState_BlockRootAtIndex(t *testing.T) {
testtmpl.VerifyBeaconStateBlockRootAtIndexNative(
t,
func() (state.BeaconState, error) {
return InitializeFromProto(&ethpb.BeaconStateAltair{})
},
func(BR [][]byte) (state.BeaconState, error) {
return InitializeFromProto(&ethpb.BeaconStateAltair{BlockRoots: BR})
},
)
}

View File

@@ -1,124 +0,0 @@
package v2
import (
"bytes"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/go-bitfield"
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
}

View File

@@ -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(&ethpb.BeaconStateAltair{})
})
}
func TestBeaconState_JustificationBits(t *testing.T) {
testtmpl.VerifyBeaconStateJustificationBits(
t,
func(bits bitfield.Bitvector4) (state.BeaconState, error) {
return InitializeFromProtoUnsafe(&ethpb.BeaconStateAltair{JustificationBits: bits})
})
}
func TestBeaconState_PreviousJustifiedCheckpointNil(t *testing.T) {
testtmpl.VerifyBeaconStatePreviousJustifiedCheckpointNil(
t,
func() (state.BeaconState, error) {
return InitializeFromProtoUnsafe(&ethpb.BeaconStateAltair{})
})
}
func TestBeaconState_PreviousJustifiedCheckpoint(t *testing.T) {
testtmpl.VerifyBeaconStatePreviousJustifiedCheckpoint(
t,
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
return InitializeFromProtoUnsafe(&ethpb.BeaconStateAltair{PreviousJustifiedCheckpoint: cp})
})
}
func TestBeaconState_CurrentJustifiedCheckpointNil(t *testing.T) {
testtmpl.VerifyBeaconStateCurrentJustifiedCheckpointNil(
t,
func() (state.BeaconState, error) {
return InitializeFromProtoUnsafe(&ethpb.BeaconStateAltair{})
})
}
func TestBeaconState_CurrentJustifiedCheckpoint(t *testing.T) {
testtmpl.VerifyBeaconStateCurrentJustifiedCheckpoint(
t,
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
return InitializeFromProtoUnsafe(&ethpb.BeaconStateAltair{CurrentJustifiedCheckpoint: cp})
})
}
func TestBeaconState_FinalizedCheckpointNil(t *testing.T) {
testtmpl.VerifyBeaconStateFinalizedCheckpointNil(
t,
func() (state.BeaconState, error) {
return InitializeFromProtoUnsafe(&ethpb.BeaconStateAltair{})
})
}
func TestBeaconState_FinalizedCheckpoint(t *testing.T) {
testtmpl.VerifyBeaconStateFinalizedCheckpoint(
t,
func(cp *ethpb.Checkpoint) (state.BeaconState, error) {
return InitializeFromProtoUnsafe(&ethpb.BeaconStateAltair{FinalizedCheckpoint: cp})
})
}

Some files were not shown because too many files have changed in this diff Show More