mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 13:58:09 -05:00
Compare commits
19 Commits
builder
...
methodical
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cec76aa833 | ||
|
|
578fea73d7 | ||
|
|
7fcadbe3ef | ||
|
|
fce9e6883d | ||
|
|
5ee66a4a68 | ||
|
|
f4c7fb6182 | ||
|
|
077dcdc643 | ||
|
|
1fa864cb1a | ||
|
|
6357860cc2 | ||
|
|
cc1ea81d4a | ||
|
|
dd65622441 | ||
|
|
6c39301f33 | ||
|
|
5b12f5a27d | ||
|
|
105d73d59b | ||
|
|
db687bf56d | ||
|
|
f0403afb25 | ||
|
|
3f309968d4 | ||
|
|
52acaceb3f | ||
|
|
5216402f66 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -35,3 +35,6 @@ bin
|
||||
|
||||
# p2p metaData
|
||||
metaData
|
||||
|
||||
# execution API authentication
|
||||
jwt.hex
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
[](https://buildkite.com/prysmatic-labs/prysm)
|
||||
[](https://goreportcard.com/report/github.com/prysmaticlabs/prysm)
|
||||
[](https://github.com/ethereum/consensus-specs/tree/v1.1.10)
|
||||
[](https://github.com/ethereum/consensus-specs/tree/v1.2.0-rc.1)
|
||||
[](https://github.com/ethereum/execution-apis/tree/v1.0.0-alpha.9/src/engine)
|
||||
[](https://discord.gg/CTYGPUJ)
|
||||
|
||||
This is the core repository for Prysm, a [Golang](https://golang.org/) implementation of the [Ethereum Consensus](https://ethereum.org/en/eth2/) specification, developed by [Prysmatic Labs](https://prysmaticlabs.com). See the [Changelog](https://github.com/prysmaticlabs/prysm/releases) for details of the latest releases and upcoming breaking changes.
|
||||
|
||||
@@ -29,7 +29,7 @@ go_test(
|
||||
data = glob(["testdata/**"]),
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/config/params"
|
||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
@@ -98,7 +98,7 @@ func TestClient_RegisterValidator(t *testing.T) {
|
||||
}
|
||||
reg := ð.SignedValidatorRegistrationV1{
|
||||
Message: ð.ValidatorRegistrationV1{
|
||||
FeeRecipient: ezDecode(t, fieldparams.EthBurnAddressHex),
|
||||
FeeRecipient: ezDecode(t, params.BeaconConfig().EthBurnAddressHex),
|
||||
GasLimit: 23,
|
||||
Timestamp: 42,
|
||||
Pubkey: ezDecode(t, "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a"),
|
||||
|
||||
@@ -337,7 +337,7 @@ func TestService_ChainHeads_ProtoArray(t *testing.T) {
|
||||
state, blkRoot, err = prepareForkchoiceState(ctx, 102, [32]byte{'c'}, [32]byte{'b'}, params.BeaconConfig().ZeroHash, 0, 0)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, c.cfg.ForkChoiceStore.InsertNode(ctx, state, blkRoot))
|
||||
state, blkRoot, err = prepareForkchoiceState(ctx, 103, [32]byte{'d'}, [32]byte{}, params.BeaconConfig().ZeroHash, 0, 0)
|
||||
state, blkRoot, err = prepareForkchoiceState(ctx, 103, [32]byte{'d'}, [32]byte{'a'}, params.BeaconConfig().ZeroHash, 0, 0)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, c.cfg.ForkChoiceStore.InsertNode(ctx, state, blkRoot))
|
||||
state, blkRoot, err = prepareForkchoiceState(ctx, 104, [32]byte{'e'}, [32]byte{'b'}, params.BeaconConfig().ZeroHash, 0, 0)
|
||||
@@ -349,10 +349,19 @@ func TestService_ChainHeads_ProtoArray(t *testing.T) {
|
||||
require.DeepEqual(t, []types.Slot{102, 103, 104}, slots)
|
||||
}
|
||||
|
||||
//
|
||||
// A <- B <- C
|
||||
// \ \
|
||||
// \ ---------- E
|
||||
// ---------- D
|
||||
|
||||
func TestService_ChainHeads_DoublyLinkedTree(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
c := &Service{cfg: &config{ForkChoiceStore: doublylinkedtree.New(0, 0)}}
|
||||
state, blkRoot, err := prepareForkchoiceState(ctx, 100, [32]byte{'a'}, [32]byte{}, params.BeaconConfig().ZeroHash, 0, 0)
|
||||
state, blkRoot, err := prepareForkchoiceState(ctx, 0, [32]byte{}, [32]byte{}, params.BeaconConfig().ZeroHash, 0, 0)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, c.cfg.ForkChoiceStore.InsertNode(ctx, state, blkRoot))
|
||||
state, blkRoot, err = prepareForkchoiceState(ctx, 100, [32]byte{'a'}, [32]byte{}, params.BeaconConfig().ZeroHash, 0, 0)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, c.cfg.ForkChoiceStore.InsertNode(ctx, state, blkRoot))
|
||||
state, blkRoot, err = prepareForkchoiceState(ctx, 101, [32]byte{'b'}, [32]byte{'a'}, params.BeaconConfig().ZeroHash, 0, 0)
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/db/kv"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/config/params"
|
||||
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||
@@ -270,10 +269,10 @@ func (s *Service) getPayloadAttribute(ctx context.Context, st state.BeaconState,
|
||||
recipient, err := s.cfg.BeaconDB.FeeRecipientByValidatorID(ctx, proposerID)
|
||||
switch {
|
||||
case errors.Is(err, kv.ErrNotFoundFeeRecipient):
|
||||
if feeRecipient.String() == fieldparams.EthBurnAddressHex {
|
||||
if feeRecipient.String() == params.BeaconConfig().EthBurnAddressHex {
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"validatorIndex": proposerID,
|
||||
"burnAddress": fieldparams.EthBurnAddressHex,
|
||||
"burnAddress": params.BeaconConfig().EthBurnAddressHex,
|
||||
}).Warn("Fee recipient is currently using the burn address, " +
|
||||
"you will not be rewarded transaction fees on this setting. " +
|
||||
"Please set a different eth address as the fee recipient. " +
|
||||
|
||||
@@ -806,7 +806,7 @@ func Test_GetPayloadAttribute(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, true, hasPayload)
|
||||
require.Equal(t, suggestedVid, vId)
|
||||
require.Equal(t, fieldparams.EthBurnAddressHex, common.BytesToAddress(attr.SuggestedFeeRecipient).String())
|
||||
require.Equal(t, params.BeaconConfig().EthBurnAddressHex, common.BytesToAddress(attr.SuggestedFeeRecipient).String())
|
||||
require.LogsContain(t, hook, "Fee recipient is currently using the burn address")
|
||||
|
||||
// Cache hit, advance state, has fee recipient
|
||||
|
||||
@@ -459,9 +459,12 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []interfaces.SignedBeac
|
||||
if err := s.cfg.ForkChoiceStore.InsertNode(ctx, preState, lastBR); err != nil {
|
||||
return errors.Wrap(err, "could not insert last block in batch to forkchoice")
|
||||
}
|
||||
// Prune forkchoice store
|
||||
if err := s.cfg.ForkChoiceStore.Prune(ctx, s.ensureRootNotZeros(bytesutil.ToBytes32(fCheckpoints[len(blks)-1].Root))); err != nil {
|
||||
return errors.Wrap(err, "could not prune fork choice nodes")
|
||||
// Prune forkchoice store only if the new finalized checkpoint is higher
|
||||
// than the finalized checkpoint in forkchoice store.
|
||||
if fCheckpoints[len(blks)-1].Epoch > s.cfg.ForkChoiceStore.FinalizedEpoch() {
|
||||
if err := s.cfg.ForkChoiceStore.Prune(ctx, s.ensureRootNotZeros(bytesutil.ToBytes32(fCheckpoints[len(blks)-1].Root))); err != nil {
|
||||
return errors.Wrap(err, "could not prune fork choice nodes")
|
||||
}
|
||||
}
|
||||
|
||||
// Set their optimistic status
|
||||
|
||||
@@ -343,6 +343,69 @@ func TestStore_OnBlockBatch_ProtoArray(t *testing.T) {
|
||||
require.Equal(t, types.Epoch(2), service.cfg.ForkChoiceStore.JustifiedEpoch())
|
||||
}
|
||||
|
||||
func TestStore_OnBlockBatch_PruneOK(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
beaconDB := testDB.SetupDB(t)
|
||||
|
||||
opts := []Option{
|
||||
WithDatabase(beaconDB),
|
||||
WithStateGen(stategen.New(beaconDB)),
|
||||
}
|
||||
service, err := NewService(ctx, opts...)
|
||||
require.NoError(t, err)
|
||||
|
||||
genesisStateRoot := [32]byte{}
|
||||
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
|
||||
wsb, err := wrapper.WrappedSignedBeaconBlock(genesis)
|
||||
require.NoError(t, err)
|
||||
assert.NoError(t, beaconDB.SaveBlock(ctx, wsb))
|
||||
gRoot, err := genesis.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
service.cfg.ForkChoiceStore = protoarray.New(0, 0)
|
||||
wsb, err = wrapper.WrappedSignedBeaconBlock(genesis)
|
||||
require.NoError(t, err)
|
||||
service.saveInitSyncBlock(gRoot, wsb)
|
||||
|
||||
st, keys := util.DeterministicGenesisState(t, 64)
|
||||
|
||||
bState := st.Copy()
|
||||
|
||||
var blks []interfaces.SignedBeaconBlock
|
||||
var blkRoots [][32]byte
|
||||
var firstState state.BeaconState
|
||||
for i := 1; i < 128; i++ {
|
||||
b, err := util.GenerateFullBlock(bState, keys, util.DefaultBlockGenConfig(), types.Slot(i))
|
||||
require.NoError(t, err)
|
||||
wsb, err := wrapper.WrappedSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
bState, err = transition.ExecuteStateTransition(ctx, bState, wsb)
|
||||
if i == 32 {
|
||||
firstState = bState.Copy()
|
||||
}
|
||||
require.NoError(t, err)
|
||||
root, err := b.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
wsb, err = wrapper.WrappedSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
service.saveInitSyncBlock(root, wsb)
|
||||
wsb, err = wrapper.WrappedSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
blks = append(blks, wsb)
|
||||
blkRoots = append(blkRoots, root)
|
||||
}
|
||||
|
||||
for i := 0; i < 32; i++ {
|
||||
require.NoError(t, beaconDB.SaveBlock(context.Background(), blks[i]))
|
||||
}
|
||||
service.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Root: blkRoots[31][:], Epoch: 1}, [32]byte{'a'})
|
||||
service.store.SetJustifiedCheckptAndPayloadHash(ðpb.Checkpoint{Root: blkRoots[31][:], Epoch: 1}, [32]byte{'b'})
|
||||
require.NoError(t, service.cfg.StateGen.SaveState(ctx, blkRoots[31], firstState))
|
||||
require.NoError(t, service.cfg.ForkChoiceStore.InsertNode(ctx, firstState, blkRoots[31]))
|
||||
err = service.onBlockBatch(ctx, blks[32:], blkRoots[32:])
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestStore_OnBlockBatch_DoublyLinkedTree(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
beaconDB := testDB.SetupDB(t)
|
||||
|
||||
@@ -206,7 +206,7 @@ func (s *Service) StartFromSavedState(saved state.BeaconState) error {
|
||||
s.store = store.New(justified, finalized)
|
||||
|
||||
var forkChoicer f.ForkChoicer
|
||||
fRoot := bytesutil.ToBytes32(finalized.Root)
|
||||
fRoot := s.ensureRootNotZeros(bytesutil.ToBytes32(finalized.Root))
|
||||
if features.Get().EnableForkChoiceDoublyLinkedTree {
|
||||
forkChoicer = doublylinkedtree.New(justified.Epoch, finalized.Epoch)
|
||||
} else {
|
||||
|
||||
@@ -62,6 +62,7 @@ type ChainService struct {
|
||||
Genesis time.Time
|
||||
ForkChoiceStore forkchoice.ForkChoicer
|
||||
ReceiveBlockMockErr error
|
||||
OptimisticCheckRootReceived [32]byte
|
||||
}
|
||||
|
||||
// ForkChoicer mocks the same method in the chain service
|
||||
@@ -447,7 +448,8 @@ func (s *ChainService) IsOptimistic(_ context.Context) (bool, error) {
|
||||
}
|
||||
|
||||
// IsOptimisticForRoot mocks the same method in the chain service.
|
||||
func (s *ChainService) IsOptimisticForRoot(_ context.Context, _ [32]byte) (bool, error) {
|
||||
func (s *ChainService) IsOptimisticForRoot(_ context.Context, root [32]byte) (bool, error) {
|
||||
s.OptimisticCheckRootReceived = root
|
||||
return s.Optimistic, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ load("@prysm//tools/go:def.bzl", "go_library")
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"error.go",
|
||||
"metric.go",
|
||||
"option.go",
|
||||
"service.go",
|
||||
],
|
||||
@@ -10,13 +12,19 @@ go_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//api/client/builder:go_default_library",
|
||||
"//beacon-chain/blockchain:go_default_library",
|
||||
"//beacon-chain/db:go_default_library",
|
||||
"//cmd/beacon-chain/flags:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//network:go_default_library",
|
||||
"//network/authorization:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus:go_default_library",
|
||||
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
|
||||
"@com_github_urfave_cli_v2//:go_default_library",
|
||||
"@io_opencensus_go//trace:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
7
beacon-chain/builder/error.go
Normal file
7
beacon-chain/builder/error.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package builder
|
||||
|
||||
import "github.com/pkg/errors"
|
||||
|
||||
var (
|
||||
ErrNotRunning = errors.New("builder is not running")
|
||||
)
|
||||
37
beacon-chain/builder/metric.go
Normal file
37
beacon-chain/builder/metric.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
)
|
||||
|
||||
var (
|
||||
submitBlindedBlockLatency = promauto.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "submit_blinded_block_latency_milliseconds",
|
||||
Help: "Captures RPC latency for submitting blinded block in milliseconds",
|
||||
Buckets: []float64{1, 2, 5, 10, 20, 50, 100, 200, 500, 1000},
|
||||
},
|
||||
)
|
||||
getHeaderLatency = promauto.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "get_header_latency_milliseconds",
|
||||
Help: "Captures RPC latency for get header in milliseconds",
|
||||
Buckets: []float64{1, 2, 5, 10, 20, 50, 100, 200, 500, 1000},
|
||||
},
|
||||
)
|
||||
getStatusLatency = promauto.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "get_status_latency_milliseconds",
|
||||
Help: "Captures RPC latency for get status in milliseconds",
|
||||
Buckets: []float64{1, 2, 5, 10, 20, 50, 100, 200, 500, 1000},
|
||||
},
|
||||
)
|
||||
registerValidatorLatency = promauto.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "register_validator_latency_milliseconds",
|
||||
Help: "Captures RPC latency for register validator in milliseconds",
|
||||
Buckets: []float64{1, 2, 5, 10, 20, 50, 100, 200, 500, 1000},
|
||||
},
|
||||
)
|
||||
)
|
||||
@@ -1,6 +1,7 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
|
||||
"github.com/prysmaticlabs/prysm/network"
|
||||
"github.com/prysmaticlabs/prysm/network/authorization"
|
||||
@@ -26,6 +27,14 @@ func WithBuilderEndpoints(endpoint string) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithDatabase sets the database for the beacon chain builder service.
|
||||
func WithDatabase(database db.HeadAccessDatabase) Option {
|
||||
return func(s *Service) error {
|
||||
s.cfg.beaconDB = database
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func covertEndPoint(ep string) network.Endpoint {
|
||||
return network.Endpoint{
|
||||
Url: ep,
|
||||
|
||||
@@ -2,26 +2,33 @@ package builder
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/api/client/builder"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/db"
|
||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/network"
|
||||
v1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
// BlockBuilder defines the interface for interacting with the block builder
|
||||
type BlockBuilder interface {
|
||||
SubmitBlindedBlock(ctx context.Context, block *ethpb.SignedBlindedBeaconBlockBellatrix) (*v1.ExecutionPayload, error)
|
||||
GetHeader(ctx context.Context, slot types.Slot, parentHash [32]byte, pubKey [48]byte) (*ethpb.SignedBuilderBid, error)
|
||||
Status() error
|
||||
Status(ctx context.Context) error
|
||||
RegisterValidator(ctx context.Context, reg *ethpb.SignedValidatorRegistrationV1) error
|
||||
}
|
||||
|
||||
// config defines a config struct for dependencies into the service.
|
||||
type config struct {
|
||||
builderEndpoint network.Endpoint
|
||||
beaconDB db.HeadAccessDatabase
|
||||
headFetcher blockchain.HeadFetcher
|
||||
}
|
||||
|
||||
// Service defines a service that provides a client for interacting with the beacon chain and MEV relay network.
|
||||
@@ -56,22 +63,59 @@ func (*Service) Stop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SubmitBlindedBlock is currently a stub.
|
||||
func (*Service) SubmitBlindedBlock(context.Context, *ethpb.SignedBlindedBeaconBlockBellatrix) (*v1.ExecutionPayload, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
// SubmitBlindedBlock submits a blinded block to the builder relay network.
|
||||
func (s *Service) SubmitBlindedBlock(ctx context.Context, b *ethpb.SignedBlindedBeaconBlockBellatrix) (*v1.ExecutionPayload, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "builder.SubmitBlindedBlock")
|
||||
defer span.End()
|
||||
start := time.Now()
|
||||
defer func() {
|
||||
submitBlindedBlockLatency.Observe(float64(time.Since(start).Milliseconds()))
|
||||
}()
|
||||
|
||||
return s.c.SubmitBlindedBlock(ctx, b)
|
||||
}
|
||||
|
||||
// GetHeader is currently a stub.
|
||||
func (*Service) GetHeader(context.Context, types.Slot, [32]byte, [48]byte) (*ethpb.SignedBuilderBid, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
// GetHeader retrieves the header for a given slot and parent hash from the builder relay network.
|
||||
func (s *Service) GetHeader(ctx context.Context, slot types.Slot, parentHash [32]byte, pubKey [48]byte) (*ethpb.SignedBuilderBid, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "builder.GetHeader")
|
||||
defer span.End()
|
||||
start := time.Now()
|
||||
defer func() {
|
||||
getHeaderLatency.Observe(float64(time.Since(start).Milliseconds()))
|
||||
}()
|
||||
|
||||
return s.c.GetHeader(ctx, slot, parentHash, pubKey)
|
||||
}
|
||||
|
||||
// Status is currently a stub.
|
||||
func (*Service) Status() error {
|
||||
return errors.New("not implemented")
|
||||
// Status retrieves the status of the builder relay network.
|
||||
func (s *Service) Status(ctx context.Context) error {
|
||||
ctx, span := trace.StartSpan(ctx, "builder.Status")
|
||||
defer span.End()
|
||||
start := time.Now()
|
||||
defer func() {
|
||||
getStatusLatency.Observe(float64(time.Since(start).Milliseconds()))
|
||||
}()
|
||||
|
||||
return s.c.Status(ctx)
|
||||
}
|
||||
|
||||
// RegisterValidator is currently a stub.
|
||||
func (*Service) RegisterValidator(context.Context, *ethpb.SignedValidatorRegistrationV1) error {
|
||||
return errors.New("not implemented")
|
||||
// RegisterValidator registers a validator with the builder relay network.
|
||||
// It also saves the registration object to the DB.
|
||||
func (s *Service) RegisterValidator(ctx context.Context, reg *ethpb.SignedValidatorRegistrationV1) error {
|
||||
ctx, span := trace.StartSpan(ctx, "builder.RegisterValidator")
|
||||
defer span.End()
|
||||
start := time.Now()
|
||||
defer func() {
|
||||
registerValidatorLatency.Observe(float64(time.Since(start).Milliseconds()))
|
||||
}()
|
||||
|
||||
idx, exists := s.cfg.headFetcher.HeadPublicKeyToValidatorIndex(bytesutil.ToBytes48(reg.Message.Pubkey))
|
||||
if !exists {
|
||||
return nil // If the pubkey is not found, it is not a validator. Do nothing.
|
||||
}
|
||||
if err := s.c.RegisterValidator(ctx, reg); err != nil {
|
||||
return errors.Wrap(err, "could not register validator")
|
||||
}
|
||||
|
||||
return s.cfg.beaconDB.SaveRegistrationsByValidatorIDs(ctx, []types.ValidatorIndex{idx}, []*ethpb.ValidatorRegistrationV1{reg.Message})
|
||||
}
|
||||
|
||||
@@ -23,14 +23,14 @@ type ReadOnlyDatabase interface {
|
||||
Block(ctx context.Context, blockRoot [32]byte) (interfaces.SignedBeaconBlock, error)
|
||||
Blocks(ctx context.Context, f *filters.QueryFilter) ([]interfaces.SignedBeaconBlock, [][32]byte, error)
|
||||
BlockRoots(ctx context.Context, f *filters.QueryFilter) ([][32]byte, error)
|
||||
BlocksBySlot(ctx context.Context, slot types.Slot) (bool, []interfaces.SignedBeaconBlock, error)
|
||||
BlocksBySlot(ctx context.Context, slot types.Slot) ([]interfaces.SignedBeaconBlock, error)
|
||||
BlockRootsBySlot(ctx context.Context, slot types.Slot) (bool, [][32]byte, error)
|
||||
HasBlock(ctx context.Context, blockRoot [32]byte) bool
|
||||
GenesisBlock(ctx context.Context) (interfaces.SignedBeaconBlock, error)
|
||||
GenesisBlockRoot(ctx context.Context) ([32]byte, error)
|
||||
IsFinalizedBlock(ctx context.Context, blockRoot [32]byte) bool
|
||||
FinalizedChildBlock(ctx context.Context, blockRoot [32]byte) (interfaces.SignedBeaconBlock, error)
|
||||
HighestSlotBlocksBelow(ctx context.Context, slot types.Slot) ([]interfaces.SignedBeaconBlock, error)
|
||||
HighestRootsBelowSlot(ctx context.Context, slot types.Slot) (types.Slot, [][32]byte, error)
|
||||
// State related methods.
|
||||
State(ctx context.Context, blockRoot [32]byte) (state.BeaconState, error)
|
||||
StateOrError(ctx context.Context, blockRoot [32]byte) (state.BeaconState, error)
|
||||
@@ -86,6 +86,7 @@ type NoHeadAccessDatabase interface {
|
||||
RunMigrations(ctx context.Context) error
|
||||
// Fee reicipients operations.
|
||||
SaveFeeRecipientsByValidatorIDs(ctx context.Context, ids []types.ValidatorIndex, addrs []common.Address) error
|
||||
SaveRegistrationsByValidatorIDs(ctx context.Context, ids []types.ValidatorIndex, regs []*ethpb.ValidatorRegistrationV1) error
|
||||
|
||||
CleanUpDirtyStates(ctx context.Context, slotsPerArchivedPoint types.Slot) error
|
||||
}
|
||||
|
||||
@@ -185,17 +185,19 @@ func (s *Store) HasBlock(ctx context.Context, blockRoot [32]byte) bool {
|
||||
}
|
||||
|
||||
// BlocksBySlot retrieves a list of beacon blocks and its respective roots by slot.
|
||||
func (s *Store) BlocksBySlot(ctx context.Context, slot types.Slot) (bool, []interfaces.SignedBeaconBlock, error) {
|
||||
func (s *Store) BlocksBySlot(ctx context.Context, slot types.Slot) ([]interfaces.SignedBeaconBlock, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "BeaconDB.BlocksBySlot")
|
||||
defer span.End()
|
||||
blocks := make([]interfaces.SignedBeaconBlock, 0)
|
||||
|
||||
blocks := make([]interfaces.SignedBeaconBlock, 0)
|
||||
err := s.db.View(func(tx *bolt.Tx) error {
|
||||
bkt := tx.Bucket(blocksBucket)
|
||||
|
||||
keys := blockRootsBySlot(ctx, tx, slot)
|
||||
for i := 0; i < len(keys); i++ {
|
||||
encoded := bkt.Get(keys[i])
|
||||
roots, err := blockRootsBySlot(ctx, tx, slot)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not retrieve blocks by slot")
|
||||
}
|
||||
for _, r := range roots {
|
||||
encoded := bkt.Get(r[:])
|
||||
blk, err := unmarshalBlock(ctx, encoded)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -204,7 +206,7 @@ func (s *Store) BlocksBySlot(ctx context.Context, slot types.Slot) (bool, []inte
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return len(blocks) > 0, blocks, err
|
||||
return blocks, err
|
||||
}
|
||||
|
||||
// BlockRootsBySlot retrieves a list of beacon block roots by slot
|
||||
@@ -213,11 +215,9 @@ func (s *Store) BlockRootsBySlot(ctx context.Context, slot types.Slot) (bool, []
|
||||
defer span.End()
|
||||
blockRoots := make([][32]byte, 0)
|
||||
err := s.db.View(func(tx *bolt.Tx) error {
|
||||
keys := blockRootsBySlot(ctx, tx, slot)
|
||||
for i := 0; i < len(keys); i++ {
|
||||
blockRoots = append(blockRoots, bytesutil.ToBytes32(keys[i]))
|
||||
}
|
||||
return nil
|
||||
var err error
|
||||
blockRoots, err = blockRootsBySlot(ctx, tx, slot)
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return false, nil, errors.Wrap(err, "could not retrieve block roots by slot")
|
||||
@@ -398,14 +398,17 @@ func (s *Store) SaveBackfillBlockRoot(ctx context.Context, blockRoot [32]byte) e
|
||||
})
|
||||
}
|
||||
|
||||
// HighestSlotBlocksBelow returns the block with the highest slot below the input slot from the db.
|
||||
func (s *Store) HighestSlotBlocksBelow(ctx context.Context, slot types.Slot) ([]interfaces.SignedBeaconBlock, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "BeaconDB.HighestSlotBlocksBelow")
|
||||
// HighestRootsBelowSlot returns roots from the database slot index from the highest slot below the input slot.
|
||||
// The slot value at the beginning of the return list is the slot where the roots were found. This is helpful so that
|
||||
// calling code can make decisions based on the slot without resolving the blocks to discover their slot (for instance
|
||||
// checking which root is canonical in fork choice, which operates purely on roots,
|
||||
// then if no canonical block is found, continuing to search through lower slots).
|
||||
func (s *Store) HighestRootsBelowSlot(ctx context.Context, slot types.Slot) (fs types.Slot, roots [][32]byte, err error) {
|
||||
ctx, span := trace.StartSpan(ctx, "BeaconDB.HighestRootsBelowSlot")
|
||||
defer span.End()
|
||||
|
||||
var root [32]byte
|
||||
sk := bytesutil.Uint64ToBytesBigEndian(uint64(slot))
|
||||
err := s.db.View(func(tx *bolt.Tx) error {
|
||||
err = s.db.View(func(tx *bolt.Tx) error {
|
||||
bkt := tx.Bucket(blockSlotIndicesBucket)
|
||||
c := bkt.Cursor()
|
||||
// The documentation for Seek says:
|
||||
@@ -430,34 +433,28 @@ func (s *Store) HighestSlotBlocksBelow(ctx context.Context, slot types.Slot) ([]
|
||||
if r == nil {
|
||||
continue
|
||||
}
|
||||
bs := bytesutil.BytesToSlotBigEndian(sl)
|
||||
fs = bytesutil.BytesToSlotBigEndian(sl)
|
||||
// Iterating through the index using .Prev will move from higher to lower, so the first key we find behind
|
||||
// the requested slot must be the highest block below that slot.
|
||||
if slot > bs {
|
||||
root = bytesutil.ToBytes32(r)
|
||||
break
|
||||
if slot > fs {
|
||||
roots, err = splitRoots(r)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error parsing packed roots %#x", r)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return 0, nil, err
|
||||
}
|
||||
if len(roots) == 0 || (len(roots) == 1 && roots[0] == params.BeaconConfig().ZeroHash) {
|
||||
gr, err := s.GenesisBlockRoot(ctx)
|
||||
return 0, [][32]byte{gr}, err
|
||||
}
|
||||
|
||||
var blk interfaces.SignedBeaconBlock
|
||||
if root != params.BeaconConfig().ZeroHash {
|
||||
blk, err = s.Block(ctx, root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if blk == nil || blk.IsNil() {
|
||||
blk, err = s.GenesisBlock(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return []interfaces.SignedBeaconBlock{blk}, nil
|
||||
return fs, roots, nil
|
||||
}
|
||||
|
||||
// FeeRecipientByValidatorID returns the fee recipient for a validator id.
|
||||
@@ -681,21 +678,22 @@ func blockRootsBySlotRange(
|
||||
}
|
||||
|
||||
// blockRootsBySlot retrieves the block roots by slot
|
||||
func blockRootsBySlot(ctx context.Context, tx *bolt.Tx, slot types.Slot) [][]byte {
|
||||
func blockRootsBySlot(ctx context.Context, tx *bolt.Tx, slot types.Slot) ([][32]byte, error) {
|
||||
_, span := trace.StartSpan(ctx, "BeaconDB.blockRootsBySlot")
|
||||
defer span.End()
|
||||
|
||||
roots := make([][]byte, 0)
|
||||
bkt := tx.Bucket(blockSlotIndicesBucket)
|
||||
key := bytesutil.SlotToBytesBigEndian(slot)
|
||||
c := bkt.Cursor()
|
||||
k, v := c.Seek(key)
|
||||
if k != nil && bytes.Equal(k, key) {
|
||||
for i := 0; i < len(v); i += 32 {
|
||||
roots = append(roots, v[i:i+32])
|
||||
r, err := splitRoots(v)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "corrupt value in block slot index for slot=%d", slot)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
return roots
|
||||
return [][32]byte{}, nil
|
||||
}
|
||||
|
||||
// createBlockIndicesFromBlock takes in a beacon block and returns
|
||||
|
||||
@@ -517,18 +517,32 @@ func TestStore_SaveBlock_CanGetHighestAt(t *testing.T) {
|
||||
require.NoError(t, db.SaveBlock(ctx, block2))
|
||||
require.NoError(t, db.SaveBlock(ctx, block3))
|
||||
|
||||
highestAt, err := db.HighestSlotBlocksBelow(ctx, 2)
|
||||
_, roots, err := db.HighestRootsBelowSlot(ctx, 2)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, false, len(highestAt) <= 0, "Got empty highest at slice")
|
||||
assert.Equal(t, true, proto.Equal(block1.Proto(), highestAt[0].Proto()), "Wanted: %v, received: %v", block1, highestAt[0])
|
||||
highestAt, err = db.HighestSlotBlocksBelow(ctx, 11)
|
||||
assert.Equal(t, false, len(roots) <= 0, "Got empty highest at slice")
|
||||
require.Equal(t, 1, len(roots))
|
||||
root := roots[0]
|
||||
b, err := db.Block(ctx, root)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, false, len(highestAt) <= 0, "Got empty highest at slice")
|
||||
assert.Equal(t, true, proto.Equal(block2.Proto(), highestAt[0].Proto()), "Wanted: %v, received: %v", block2, highestAt[0])
|
||||
highestAt, err = db.HighestSlotBlocksBelow(ctx, 101)
|
||||
assert.Equal(t, true, proto.Equal(block1.Proto(), b.Proto()), "Wanted: %v, received: %v", block1, b)
|
||||
|
||||
_, roots, err = db.HighestRootsBelowSlot(ctx, 11)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, false, len(highestAt) <= 0, "Got empty highest at slice")
|
||||
assert.Equal(t, true, proto.Equal(block3.Proto(), highestAt[0].Proto()), "Wanted: %v, received: %v", block3, highestAt[0])
|
||||
assert.Equal(t, false, len(roots) <= 0, "Got empty highest at slice")
|
||||
require.Equal(t, 1, len(roots))
|
||||
root = roots[0]
|
||||
b, err = db.Block(ctx, root)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, proto.Equal(block2.Proto(), b.Proto()), "Wanted: %v, received: %v", block2, b)
|
||||
|
||||
_, roots, err = db.HighestRootsBelowSlot(ctx, 101)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, false, len(roots) <= 0, "Got empty highest at slice")
|
||||
require.Equal(t, 1, len(roots))
|
||||
root = roots[0]
|
||||
b, err = db.Block(ctx, root)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, proto.Equal(block3.Proto(), b.Proto()), "Wanted: %v, received: %v", block3, b)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -549,15 +563,29 @@ func TestStore_GenesisBlock_CanGetHighestAt(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, db.SaveBlock(ctx, block1))
|
||||
|
||||
highestAt, err := db.HighestSlotBlocksBelow(ctx, 2)
|
||||
_, roots, err := db.HighestRootsBelowSlot(ctx, 2)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, proto.Equal(block1.Proto(), highestAt[0].Proto()), "Wanted: %v, received: %v", block1, highestAt[0])
|
||||
highestAt, err = db.HighestSlotBlocksBelow(ctx, 1)
|
||||
require.Equal(t, 1, len(roots))
|
||||
root := roots[0]
|
||||
b, err := db.Block(ctx, root)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, proto.Equal(genesisBlock.Proto(), highestAt[0].Proto()), "Wanted: %v, received: %v", genesisBlock, highestAt[0])
|
||||
highestAt, err = db.HighestSlotBlocksBelow(ctx, 0)
|
||||
assert.Equal(t, true, proto.Equal(block1.Proto(), b.Proto()), "Wanted: %v, received: %v", block1, b)
|
||||
|
||||
_, roots, err = db.HighestRootsBelowSlot(ctx, 1)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, proto.Equal(genesisBlock.Proto(), highestAt[0].Proto()), "Wanted: %v, received: %v", genesisBlock, highestAt[0])
|
||||
require.Equal(t, 1, len(roots))
|
||||
root = roots[0]
|
||||
b, err = db.Block(ctx, root)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, proto.Equal(genesisBlock.Proto(), b.Proto()), "Wanted: %v, received: %v", genesisBlock, b)
|
||||
|
||||
_, roots, err = db.HighestRootsBelowSlot(ctx, 0)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(roots))
|
||||
root = roots[0]
|
||||
b, err = db.Block(ctx, root)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, proto.Equal(genesisBlock.Proto(), b.Proto()), "Wanted: %v, received: %v", genesisBlock, b)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -638,22 +666,21 @@ func TestStore_BlocksBySlot_BlockRootsBySlot(t *testing.T) {
|
||||
r3, err := b3.Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
hasBlocks, retrievedBlocks, err := db.BlocksBySlot(ctx, 1)
|
||||
retrievedBlocks, err := db.BlocksBySlot(ctx, 1)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 0, len(retrievedBlocks), "Unexpected number of blocks received, expected none")
|
||||
assert.Equal(t, false, hasBlocks, "Expected no blocks")
|
||||
hasBlocks, retrievedBlocks, err = db.BlocksBySlot(ctx, 20)
|
||||
retrievedBlocks, err = db.BlocksBySlot(ctx, 20)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, true, proto.Equal(b1.Proto(), retrievedBlocks[0].Proto()), "Wanted: %v, received: %v", b1, retrievedBlocks[0])
|
||||
assert.Equal(t, true, hasBlocks, "Expected to have blocks")
|
||||
hasBlocks, retrievedBlocks, err = db.BlocksBySlot(ctx, 100)
|
||||
assert.Equal(t, true, len(retrievedBlocks) > 0, "Expected to have blocks")
|
||||
retrievedBlocks, err = db.BlocksBySlot(ctx, 100)
|
||||
require.NoError(t, err)
|
||||
if len(retrievedBlocks) != 2 {
|
||||
t.Fatalf("Expected 2 blocks, received %d blocks", len(retrievedBlocks))
|
||||
}
|
||||
assert.Equal(t, true, proto.Equal(b2.Proto(), retrievedBlocks[0].Proto()), "Wanted: %v, received: %v", b2, retrievedBlocks[0])
|
||||
assert.Equal(t, true, proto.Equal(b3.Proto(), retrievedBlocks[1].Proto()), "Wanted: %v, received: %v", b3, retrievedBlocks[1])
|
||||
assert.Equal(t, true, hasBlocks, "Expected to have blocks")
|
||||
assert.Equal(t, true, len(retrievedBlocks) > 0, "Expected to have blocks")
|
||||
|
||||
hasBlockRoots, retrievedBlockRoots, err := db.BlockRootsBySlot(ctx, 1)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||
bolt "go.etcd.io/bbolt"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
@@ -99,3 +101,16 @@ func deleteValueForIndices(ctx context.Context, indicesByBucket map[string][]byt
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var errMisalignedRootList = errors.New("incorrectly packed root list, length is not a multiple of 32")
|
||||
|
||||
func splitRoots(b []byte) ([][32]byte, error) {
|
||||
rl := make([][32]byte, 0)
|
||||
if len(b)%32 != 0 {
|
||||
return nil, errors.Wrapf(errMisalignedRootList, "root list len=%d", len(b))
|
||||
}
|
||||
for s, f := 0, 32; f <= len(b); s, f = f, f+32 {
|
||||
rl = append(rl, bytesutil.ToBytes32(b[s:f]))
|
||||
}
|
||||
return rl, nil
|
||||
}
|
||||
|
||||
@@ -138,3 +138,60 @@ func Test_deleteValueForIndices(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func testPack(bs [][32]byte) []byte {
|
||||
r := make([]byte, 0)
|
||||
for _, b := range bs {
|
||||
r = append(r, b[:]...)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func TestSplitRoots(t *testing.T) {
|
||||
bt := make([][32]byte, 0)
|
||||
for _, x := range []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} {
|
||||
var b [32]byte
|
||||
for i := 0; i < 32; i++ {
|
||||
b[i] = x
|
||||
}
|
||||
bt = append(bt, b)
|
||||
}
|
||||
cases := []struct {
|
||||
name string
|
||||
b []byte
|
||||
expect [][32]byte
|
||||
err error
|
||||
}{
|
||||
{
|
||||
name: "misaligned",
|
||||
b: make([]byte, 61),
|
||||
err: errMisalignedRootList,
|
||||
},
|
||||
{
|
||||
name: "happy",
|
||||
b: testPack(bt[0:5]),
|
||||
expect: bt[0:5],
|
||||
},
|
||||
{
|
||||
name: "single",
|
||||
b: testPack([][32]byte{bt[0]}),
|
||||
expect: [][32]byte{bt[0]},
|
||||
},
|
||||
{
|
||||
name: "empty",
|
||||
b: []byte{},
|
||||
expect: [][32]byte{},
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
r, err := splitRoots(c.b)
|
||||
if c.err != nil {
|
||||
require.ErrorIs(t, err, c.err)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, c.expect, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -435,6 +435,8 @@ func (f *ForkChoice) CommonAncestorRoot(ctx context.Context, r1 [32]byte, r2 [32
|
||||
if n1.slot > n2.slot {
|
||||
n1 = n1.parent
|
||||
// Reaches the end of the tree and unable to find common ancestor.
|
||||
// This should not happen at runtime as the finalized
|
||||
// node has to be a common ancestor
|
||||
if n1 == nil {
|
||||
return [32]byte{}, forkchoice.ErrUnknownCommonAncestor
|
||||
}
|
||||
|
||||
@@ -535,9 +535,17 @@ func TestStore_CommonAncestor(t *testing.T) {
|
||||
require.ErrorIs(t, err, ErrNilNode)
|
||||
_, err = f.CommonAncestorRoot(ctx, [32]byte{'z'}, [32]byte{'a'})
|
||||
require.ErrorIs(t, err, ErrNilNode)
|
||||
state, blkRoot, err = prepareForkchoiceState(ctx, 100, [32]byte{'y'}, [32]byte{'z'}, [32]byte{}, 1, 1)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, f.InsertNode(ctx, state, blkRoot))
|
||||
n := &Node{
|
||||
slot: 100,
|
||||
root: [32]byte{'y'},
|
||||
justifiedEpoch: 1,
|
||||
unrealizedJustifiedEpoch: 1,
|
||||
finalizedEpoch: 1,
|
||||
unrealizedFinalizedEpoch: 1,
|
||||
optimistic: true,
|
||||
}
|
||||
|
||||
f.store.nodeByRoot[[32]byte{'y'}] = n
|
||||
// broken link
|
||||
_, err = f.CommonAncestorRoot(ctx, [32]byte{'y'}, [32]byte{'a'})
|
||||
require.ErrorIs(t, err, forkchoice.ErrUnknownCommonAncestor)
|
||||
|
||||
@@ -125,19 +125,20 @@ func (s *Store) insert(ctx context.Context,
|
||||
|
||||
s.nodeByPayload[payloadHash] = n
|
||||
s.nodeByRoot[root] = n
|
||||
if parent != nil {
|
||||
if parent == nil {
|
||||
if s.treeRootNode == nil {
|
||||
s.treeRootNode = n
|
||||
s.headNode = n
|
||||
} else {
|
||||
return errInvalidParentRoot
|
||||
}
|
||||
} else {
|
||||
parent.children = append(parent.children, n)
|
||||
if err := s.treeRootNode.updateBestDescendant(ctx, s.justifiedEpoch, s.finalizedEpoch); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Set the node as root if the store was empty
|
||||
if s.treeRootNode == nil {
|
||||
s.treeRootNode = n
|
||||
s.headNode = n
|
||||
}
|
||||
|
||||
// Update metrics.
|
||||
processedBlockCount.Inc()
|
||||
nodeCount.Set(float64(len(s.nodeByRoot)))
|
||||
|
||||
@@ -10,21 +10,21 @@ var (
|
||||
prometheus.HistogramOpts{
|
||||
Name: "new_payload_v1_latency_milliseconds",
|
||||
Help: "Captures RPC latency for newPayloadV1 in milliseconds",
|
||||
Buckets: []float64{1, 2, 5, 10, 20, 50, 100, 200, 500, 1000},
|
||||
Buckets: []float64{25, 50, 100, 200, 500, 1000, 2000, 4000},
|
||||
},
|
||||
)
|
||||
getPayloadLatency = promauto.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "get_payload_v1_latency_milliseconds",
|
||||
Help: "Captures RPC latency for getPayloadV1 in milliseconds",
|
||||
Buckets: []float64{1, 2, 5, 10, 20, 50, 100, 200, 500, 1000},
|
||||
Buckets: []float64{25, 50, 100, 200, 500, 1000, 2000, 4000},
|
||||
},
|
||||
)
|
||||
forkchoiceUpdatedLatency = promauto.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "forkchoice_updated_v1_latency_milliseconds",
|
||||
Help: "Captures RPC latency for forkchoiceUpdatedV1 in milliseconds",
|
||||
Buckets: []float64{1, 2, 5, 10, 20, 50, 100, 200, 500, 1000},
|
||||
Buckets: []float64{25, 50, 100, 200, 500, 1000, 2000, 4000},
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
@@ -70,10 +70,14 @@ func (bs *Server) GetWeakSubjectivity(ctx context.Context, _ *empty.Empty) (*eth
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "could not get weak subjectivity slot: %v", err)
|
||||
}
|
||||
cbr, cb, err := bs.CanonicalHistory.BlockForSlot(ctx, wsSlot)
|
||||
cbr, err := bs.CanonicalHistory.BlockRootForSlot(ctx, wsSlot)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, fmt.Sprintf("could not find highest block below slot %d", wsSlot))
|
||||
}
|
||||
cb, err := bs.BeaconDB.Block(ctx, cbr)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, fmt.Sprintf("block with root %#x from slot index %d not found in db", cbr, wsSlot))
|
||||
}
|
||||
stateRoot := bytesutil.ToBytes32(cb.Block().StateRoot())
|
||||
log.Printf("weak subjectivity checkpoint reported as epoch=%d, block root=%#x, state root=%#x", wsEpoch, cbr, stateRoot)
|
||||
return ðpbv1.WeakSubjectivityResponse{
|
||||
@@ -150,7 +154,7 @@ func (bs *Server) ListBlockHeaders(ctx context.Context, req *ethpbv1.BlockHeader
|
||||
if req.Slot != nil {
|
||||
slot = *req.Slot
|
||||
}
|
||||
_, blks, err = bs.BeaconDB.BlocksBySlot(ctx, slot)
|
||||
blks, err = bs.BeaconDB.BlocksBySlot(ctx, slot)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not retrieve blocks for slot %d: %v", req.Slot, err)
|
||||
}
|
||||
@@ -754,7 +758,7 @@ func (bs *Server) blockFromBlockID(ctx context.Context, blockId []byte) (interfa
|
||||
e := newBlockIdParseError(err)
|
||||
return nil, &e
|
||||
}
|
||||
_, blks, err := bs.BeaconDB.BlocksBySlot(ctx, types.Slot(slot))
|
||||
blks, err := bs.BeaconDB.BlocksBySlot(ctx, types.Slot(slot))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not retrieve blocks for slot %d", slot)
|
||||
}
|
||||
|
||||
@@ -1527,8 +1527,8 @@ func TestServer_GetBlockSSZ(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ok, blocks, err := beaconDB.BlocksBySlot(ctx, 30)
|
||||
require.Equal(t, true, ok)
|
||||
blocks, err := beaconDB.BlocksBySlot(ctx, 30)
|
||||
require.Equal(t, true, len(blocks) > 0)
|
||||
require.NoError(t, err)
|
||||
sszBlock, err := blocks[0].MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
@@ -1567,8 +1567,8 @@ func TestServer_GetBlockSSZV2(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ok, blocks, err := beaconDB.BlocksBySlot(ctx, 30)
|
||||
require.Equal(t, true, ok)
|
||||
blocks, err := beaconDB.BlocksBySlot(ctx, 30)
|
||||
require.Equal(t, true, len(blocks) > 0)
|
||||
require.NoError(t, err)
|
||||
sszBlock, err := blocks[0].MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
@@ -1606,8 +1606,8 @@ func TestServer_GetBlockSSZV2(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ok, blocks, err := beaconDB.BlocksBySlot(ctx, 30)
|
||||
require.Equal(t, true, ok)
|
||||
blocks, err := beaconDB.BlocksBySlot(ctx, 30)
|
||||
require.Equal(t, true, len(blocks) > 0)
|
||||
require.NoError(t, err)
|
||||
sszBlock, err := blocks[0].MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
@@ -1645,8 +1645,8 @@ func TestServer_GetBlockSSZV2(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ok, blocks, err := beaconDB.BlocksBySlot(ctx, 30)
|
||||
require.Equal(t, true, ok)
|
||||
blocks, err := beaconDB.BlocksBySlot(ctx, 30)
|
||||
require.Equal(t, true, len(blocks) > 0)
|
||||
require.NoError(t, err)
|
||||
sszBlock, err := blocks[0].MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
@@ -9,6 +10,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/sync"
|
||||
"github.com/prysmaticlabs/prysm/config/params"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
@@ -40,12 +42,15 @@ func ValidateSync(ctx context.Context, syncChecker sync.Checker, headFetcher blo
|
||||
|
||||
// IsOptimistic checks whether the latest block header of the passed in beacon state is the header of an optimistic block.
|
||||
func IsOptimistic(ctx context.Context, st state.BeaconState, optimisticSyncFetcher blockchain.OptimisticModeFetcher) (bool, error) {
|
||||
root, err := st.HashTreeRoot(ctx)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "could not get state root")
|
||||
}
|
||||
header := st.LatestBlockHeader()
|
||||
header.StateRoot = root[:]
|
||||
// This happens when the block at the state's slot is not missing.
|
||||
if bytes.Equal(header.StateRoot, params.BeaconConfig().ZeroHash[:]) {
|
||||
root, err := st.HashTreeRoot(ctx)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "could not get state root")
|
||||
}
|
||||
header.StateRoot = root[:]
|
||||
}
|
||||
headRoot, err := header.HashTreeRoot()
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "could not get header root")
|
||||
|
||||
@@ -69,4 +69,29 @@ func TestIsOptimistic(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, false, o)
|
||||
})
|
||||
t.Run("zero state root", func(t *testing.T) {
|
||||
zeroRootSt, err := util.NewBeaconState()
|
||||
require.NoError(t, err)
|
||||
h := zeroRootSt.LatestBlockHeader()
|
||||
h.StateRoot = make([]byte, 32)
|
||||
require.NoError(t, zeroRootSt.SetLatestBlockHeader(h))
|
||||
mockOptSyncFetcher := &chainmock.ChainService{}
|
||||
_, err = IsOptimistic(ctx, st, mockOptSyncFetcher)
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(
|
||||
t,
|
||||
[32]byte{0xfc, 0x0, 0xe9, 0x6d, 0xb, 0x8b, 0x2, 0x2f, 0x61, 0xeb, 0x92, 0x10, 0xfd, 0x80, 0x84, 0x2b, 0x26, 0x61, 0xdc, 0x94, 0x5f, 0x7a, 0xf0, 0x0, 0xbc, 0x38, 0x6, 0x38, 0x71, 0x95, 0x43, 0x1},
|
||||
mockOptSyncFetcher.OptimisticCheckRootReceived,
|
||||
)
|
||||
})
|
||||
t.Run("non-zero state root", func(t *testing.T) {
|
||||
mockOptSyncFetcher := &chainmock.ChainService{}
|
||||
_, err = IsOptimistic(ctx, st, mockOptSyncFetcher)
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(
|
||||
t,
|
||||
[32]byte{0xfc, 0x0, 0xe9, 0x6d, 0xb, 0x8b, 0x2, 0x2f, 0x61, 0xeb, 0x92, 0x10, 0xfd, 0x80, 0x84, 0x2b, 0x26, 0x61, 0xdc, 0x94, 0x5f, 0x7a, 0xf0, 0x0, 0xbc, 0x38, 0x6, 0x38, 0x71, 0x95, 0x43, 0x1},
|
||||
mockOptSyncFetcher.OptimisticCheckRootReceived,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -209,11 +209,11 @@ func (bs *Server) listBlocksForRoot(ctx context.Context, _ *ethpb.ListBlocksRequ
|
||||
|
||||
// listBlocksForSlot retrieves all blocks for the provided slot.
|
||||
func (bs *Server) listBlocksForSlot(ctx context.Context, req *ethpb.ListBlocksRequest, q *ethpb.ListBlocksRequest_Slot) ([]blockContainer, int, string, error) {
|
||||
hasBlocks, blks, err := bs.BeaconDB.BlocksBySlot(ctx, q.Slot)
|
||||
blks, err := bs.BeaconDB.BlocksBySlot(ctx, q.Slot)
|
||||
if err != nil {
|
||||
return nil, 0, strconv.Itoa(0), status.Errorf(codes.Internal, "Could not retrieve blocks for slot %d: %v", q.Slot, err)
|
||||
}
|
||||
if !hasBlocks {
|
||||
if len(blks) == 0 {
|
||||
return []blockContainer{}, 0, strconv.Itoa(0), nil
|
||||
}
|
||||
|
||||
@@ -393,6 +393,10 @@ func (bs *Server) chainHeadRetrieval(ctx context.Context) (*ethpb.ChainHead, err
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "Could not get head block")
|
||||
}
|
||||
optimisticStatus, err := bs.OptimisticModeFetcher.IsOptimistic(ctx)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "Could not get optimistic status")
|
||||
}
|
||||
if err := wrapper.BeaconBlockIsNil(headBlock); err != nil {
|
||||
return nil, status.Errorf(codes.NotFound, "Head block of chain was nil: %v", err)
|
||||
}
|
||||
@@ -474,5 +478,6 @@ func (bs *Server) chainHeadRetrieval(ctx context.Context) (*ethpb.ChainHead, err
|
||||
PreviousJustifiedSlot: pjSlot,
|
||||
PreviousJustifiedEpoch: prevJustifiedCheckpoint.Epoch,
|
||||
PreviousJustifiedBlockRoot: prevJustifiedCheckpoint.Root,
|
||||
OptimisticStatus: optimisticStatus,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -426,6 +426,7 @@ func TestServer_GetChainHead_NoGenesis(t *testing.T) {
|
||||
FinalizedCheckPoint: s.FinalizedCheckpoint(),
|
||||
CurrentJustifiedCheckPoint: s.CurrentJustifiedCheckpoint(),
|
||||
PreviousJustifiedCheckPoint: s.PreviousJustifiedCheckpoint()},
|
||||
OptimisticModeFetcher: &chainMock.ChainService{},
|
||||
}
|
||||
_, err = bs.GetChainHead(context.Background(), nil)
|
||||
require.ErrorContains(t, "Could not get genesis block", err)
|
||||
@@ -461,6 +462,7 @@ func TestServer_GetChainHead_NoFinalizedBlock(t *testing.T) {
|
||||
FinalizedCheckPoint: s.FinalizedCheckpoint(),
|
||||
CurrentJustifiedCheckPoint: s.CurrentJustifiedCheckpoint(),
|
||||
PreviousJustifiedCheckPoint: s.PreviousJustifiedCheckpoint()},
|
||||
OptimisticModeFetcher: &chainMock.ChainService{},
|
||||
}
|
||||
|
||||
_, err = bs.GetChainHead(context.Background(), nil)
|
||||
@@ -469,7 +471,8 @@ func TestServer_GetChainHead_NoFinalizedBlock(t *testing.T) {
|
||||
|
||||
func TestServer_GetChainHead_NoHeadBlock(t *testing.T) {
|
||||
bs := &Server{
|
||||
HeadFetcher: &chainMock.ChainService{Block: nil},
|
||||
HeadFetcher: &chainMock.ChainService{Block: nil},
|
||||
OptimisticModeFetcher: &chainMock.ChainService{},
|
||||
}
|
||||
_, err := bs.GetChainHead(context.Background(), nil)
|
||||
assert.ErrorContains(t, "Head block of chain was nil", err)
|
||||
@@ -531,8 +534,9 @@ func TestServer_GetChainHead(t *testing.T) {
|
||||
wsb, err = wrapper.WrappedSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
bs := &Server{
|
||||
BeaconDB: db,
|
||||
HeadFetcher: &chainMock.ChainService{Block: wsb, State: s},
|
||||
BeaconDB: db,
|
||||
HeadFetcher: &chainMock.ChainService{Block: wsb, State: s},
|
||||
OptimisticModeFetcher: &chainMock.ChainService{},
|
||||
FinalizationFetcher: &chainMock.ChainService{
|
||||
FinalizedCheckPoint: s.FinalizedCheckpoint(),
|
||||
CurrentJustifiedCheckPoint: s.CurrentJustifiedCheckpoint(),
|
||||
@@ -550,6 +554,7 @@ func TestServer_GetChainHead(t *testing.T) {
|
||||
assert.DeepEqual(t, pjRoot[:], head.PreviousJustifiedBlockRoot, "Unexpected PreviousJustifiedBlockRoot")
|
||||
assert.DeepEqual(t, jRoot[:], head.JustifiedBlockRoot, "Unexpected JustifiedBlockRoot")
|
||||
assert.DeepEqual(t, fRoot[:], head.FinalizedBlockRoot, "Unexpected FinalizedBlockRoot")
|
||||
assert.Equal(t, false, head.OptimisticStatus)
|
||||
}
|
||||
|
||||
func TestServer_StreamChainHead_ContextCanceled(t *testing.T) {
|
||||
@@ -645,6 +650,7 @@ func TestServer_StreamChainHead_OnHeadUpdated(t *testing.T) {
|
||||
FinalizedCheckPoint: s.FinalizedCheckpoint(),
|
||||
CurrentJustifiedCheckPoint: s.CurrentJustifiedCheckpoint(),
|
||||
PreviousJustifiedCheckPoint: s.PreviousJustifiedCheckpoint()},
|
||||
OptimisticModeFetcher: &chainMock.ChainService{},
|
||||
}
|
||||
exitRoutine := make(chan bool)
|
||||
ctrl := gomock.NewController(t)
|
||||
|
||||
@@ -47,4 +47,5 @@ type Server struct {
|
||||
SyncChecker sync.Checker
|
||||
ReplayerBuilder stategen.ReplayerBuilder
|
||||
HeadUpdater blockchain.HeadUpdater
|
||||
OptimisticModeFetcher blockchain.OptimisticModeFetcher
|
||||
}
|
||||
|
||||
@@ -127,10 +127,10 @@ func (vs *Server) getExecutionPayload(ctx context.Context, slot types.Slot, vIdx
|
||||
case errors.As(err, kv.ErrNotFoundFeeRecipient):
|
||||
// If fee recipient is not found in DB and not set from beacon node CLI,
|
||||
// use the burn address.
|
||||
if feeRecipient.String() == fieldparams.EthBurnAddressHex {
|
||||
if feeRecipient.String() == params.BeaconConfig().EthBurnAddressHex {
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"validatorIndex": vIdx,
|
||||
"burnAddress": fieldparams.EthBurnAddressHex,
|
||||
"burnAddress": params.BeaconConfig().EthBurnAddressHex,
|
||||
}).Warn("Fee recipient is currently using the burn address, " +
|
||||
"you will not be rewarded transaction fees on this setting. " +
|
||||
"Please set a different eth address as the fee recipient. " +
|
||||
|
||||
@@ -268,6 +268,7 @@ func (s *Service) Start() {
|
||||
AttestationsPool: s.cfg.AttestationsPool,
|
||||
SlashingsPool: s.cfg.SlashingsPool,
|
||||
HeadUpdater: s.cfg.HeadUpdater,
|
||||
OptimisticModeFetcher: s.cfg.OptimisticModeFetcher,
|
||||
HeadFetcher: s.cfg.HeadFetcher,
|
||||
FinalizationFetcher: s.cfg.FinalizationFetcher,
|
||||
CanonicalFetcher: s.cfg.CanonicalFetcher,
|
||||
|
||||
@@ -292,11 +292,11 @@ func (p *StateProvider) stateRootBySlot(ctx context.Context, slot types.Slot) ([
|
||||
if slot > currentSlot {
|
||||
return nil, errors.New("slot cannot be in the future")
|
||||
}
|
||||
found, blks, err := p.BeaconDB.BlocksBySlot(ctx, slot)
|
||||
blks, err := p.BeaconDB.BlocksBySlot(ctx, slot)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get blocks")
|
||||
}
|
||||
if !found {
|
||||
if len(blks) == 0 {
|
||||
return nil, errors.New("no block exists")
|
||||
}
|
||||
if len(blks) != 1 {
|
||||
|
||||
@@ -15,7 +15,6 @@ go_library(
|
||||
"//beacon-chain/state/types:go_default_library",
|
||||
"//crypto/hash:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//encoding/ssz:go_default_library",
|
||||
"//math:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/types"
|
||||
"github.com/prysmaticlabs/prysm/crypto/hash"
|
||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/encoding/ssz"
|
||||
pmath "github.com/prysmaticlabs/prysm/math"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||
@@ -353,17 +352,7 @@ func handlePendingAttestationSlice(val []*ethpb.PendingAttestation, indices []ui
|
||||
// handleBalanceSlice returns the root of a slice of validator balances.
|
||||
func handleBalanceSlice(val, indices []uint64, convertAll bool) ([][32]byte, error) {
|
||||
if convertAll {
|
||||
balancesMarshaling := make([][]byte, len(val))
|
||||
for i, b := range val {
|
||||
balanceBuf := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(balanceBuf, b)
|
||||
balancesMarshaling[i] = balanceBuf
|
||||
}
|
||||
balancesChunks, err := ssz.PackByChunk(balancesMarshaling)
|
||||
if err != nil {
|
||||
return [][32]byte{}, errors.Wrap(err, "could not pack balances into chunks")
|
||||
}
|
||||
return balancesChunks, nil
|
||||
return stateutil.PackUint64IntoChunks(val)
|
||||
}
|
||||
if len(val) > 0 {
|
||||
numOfElems, err := types.Balances.ElemsInChunk()
|
||||
|
||||
@@ -199,6 +199,8 @@ func InitializeFromProtoUnsafePhase0(st *ethpb.BeaconState) (state.BeaconState,
|
||||
b.sharedFieldReferences[nativetypes.CurrentEpochAttestations] = stateutil.NewRef(1)
|
||||
|
||||
state.StateCount.Inc()
|
||||
// Finalizer runs when dst is being destroyed in garbage collection.
|
||||
runtime.SetFinalizer(b, finalizerCleanup)
|
||||
return b, nil
|
||||
}
|
||||
|
||||
@@ -287,6 +289,8 @@ func InitializeFromProtoUnsafeAltair(st *ethpb.BeaconStateAltair) (state.BeaconS
|
||||
b.sharedFieldReferences[nativetypes.InactivityScores] = stateutil.NewRef(1) // New in Altair.
|
||||
|
||||
state.StateCount.Inc()
|
||||
// Finalizer runs when dst is being destroyed in garbage collection.
|
||||
runtime.SetFinalizer(b, finalizerCleanup)
|
||||
return b, nil
|
||||
}
|
||||
|
||||
@@ -377,6 +381,8 @@ func InitializeFromProtoUnsafeBellatrix(st *ethpb.BeaconStateBellatrix) (state.B
|
||||
b.sharedFieldReferences[nativetypes.LatestExecutionPayloadHeader] = stateutil.NewRef(1) // New in Bellatrix.
|
||||
|
||||
state.StateCount.Inc()
|
||||
// Finalizer runs when dst is being destroyed in garbage collection.
|
||||
runtime.SetFinalizer(b, finalizerCleanup)
|
||||
return b, nil
|
||||
}
|
||||
|
||||
@@ -495,31 +501,7 @@ func (b *BeaconState) Copy() state.BeaconState {
|
||||
|
||||
state.StateCount.Inc()
|
||||
// Finalizer runs when dst is being destroyed in garbage collection.
|
||||
runtime.SetFinalizer(dst, func(b *BeaconState) {
|
||||
for field, v := range b.sharedFieldReferences {
|
||||
v.MinusRef()
|
||||
if b.stateFieldLeaves[field].FieldReference() != nil {
|
||||
b.stateFieldLeaves[field].FieldReference().MinusRef()
|
||||
}
|
||||
|
||||
}
|
||||
for i := range b.dirtyFields {
|
||||
delete(b.dirtyFields, i)
|
||||
}
|
||||
for i := range b.rebuildTrie {
|
||||
delete(b.rebuildTrie, i)
|
||||
}
|
||||
for i := range b.dirtyIndices {
|
||||
delete(b.dirtyIndices, i)
|
||||
}
|
||||
for i := range b.sharedFieldReferences {
|
||||
delete(b.sharedFieldReferences, i)
|
||||
}
|
||||
for i := range b.stateFieldLeaves {
|
||||
delete(b.stateFieldLeaves, i)
|
||||
}
|
||||
state.StateCount.Sub(1)
|
||||
})
|
||||
runtime.SetFinalizer(dst, finalizerCleanup)
|
||||
return dst
|
||||
}
|
||||
|
||||
@@ -792,3 +774,29 @@ func (b *BeaconState) resetFieldTrie(index nativetypes.FieldIndex, elements inte
|
||||
b.dirtyIndices[index] = []uint64{}
|
||||
return nil
|
||||
}
|
||||
|
||||
func finalizerCleanup(b *BeaconState) {
|
||||
for field, v := range b.sharedFieldReferences {
|
||||
v.MinusRef()
|
||||
if b.stateFieldLeaves[field].FieldReference() != nil {
|
||||
b.stateFieldLeaves[field].FieldReference().MinusRef()
|
||||
}
|
||||
|
||||
}
|
||||
for i := range b.dirtyFields {
|
||||
delete(b.dirtyFields, i)
|
||||
}
|
||||
for i := range b.rebuildTrie {
|
||||
delete(b.rebuildTrie, i)
|
||||
}
|
||||
for i := range b.dirtyIndices {
|
||||
delete(b.dirtyIndices, i)
|
||||
}
|
||||
for i := range b.sharedFieldReferences {
|
||||
delete(b.sharedFieldReferences, i)
|
||||
}
|
||||
for i := range b.stateFieldLeaves {
|
||||
delete(b.stateFieldLeaves, i)
|
||||
}
|
||||
state.StateCount.Sub(1)
|
||||
}
|
||||
|
||||
@@ -46,73 +46,58 @@ func (c *CanonicalHistory) ReplayerForSlot(target types.Slot) Replayer {
|
||||
return &stateReplayer{chainer: c, method: forSlot, target: target}
|
||||
}
|
||||
|
||||
func (c *CanonicalHistory) BlockForSlot(ctx context.Context, target types.Slot) ([32]byte, interfaces.SignedBeaconBlock, error) {
|
||||
currentSlot := c.cs.CurrentSlot()
|
||||
if target > currentSlot {
|
||||
return [32]byte{}, nil, errors.Wrap(ErrFutureSlotRequested, fmt.Sprintf("requested=%d, current=%d", target, currentSlot))
|
||||
func (c *CanonicalHistory) BlockRootForSlot(ctx context.Context, target types.Slot) ([32]byte, error) {
|
||||
if currentSlot := c.cs.CurrentSlot(); target > currentSlot {
|
||||
return [32]byte{}, errors.Wrap(ErrFutureSlotRequested, fmt.Sprintf("requested=%d, current=%d", target, currentSlot))
|
||||
}
|
||||
for target > 0 {
|
||||
|
||||
slotAbove := target + 1
|
||||
// don't bother searching for candidate roots when we know the target slot is genesis
|
||||
for slotAbove > 1 {
|
||||
if ctx.Err() != nil {
|
||||
return [32]byte{}, nil, errors.Wrap(ctx.Err(), "context canceled during canonicalBlockForSlot")
|
||||
return [32]byte{}, errors.Wrap(ctx.Err(), "context canceled during canonicalBlockForSlot")
|
||||
}
|
||||
hbs, err := c.h.HighestSlotBlocksBelow(ctx, target+1)
|
||||
slot, roots, err := c.h.HighestRootsBelowSlot(ctx, slotAbove)
|
||||
if err != nil {
|
||||
return [32]byte{}, nil, errors.Wrap(err, fmt.Sprintf("error finding highest block w/ slot <= %d", target))
|
||||
return [32]byte{}, errors.Wrap(err, fmt.Sprintf("error finding highest block w/ slot < %d", slotAbove))
|
||||
}
|
||||
if len(hbs) == 0 {
|
||||
return [32]byte{}, nil, errors.Wrap(ErrNoBlocksBelowSlot, fmt.Sprintf("slot=%d", target))
|
||||
if len(roots) == 0 {
|
||||
return [32]byte{}, errors.Wrap(ErrNoBlocksBelowSlot, fmt.Sprintf("slot=%d", slotAbove))
|
||||
}
|
||||
r, b, err := c.bestForSlot(ctx, hbs)
|
||||
r, err := c.bestForSlot(ctx, roots)
|
||||
if err == nil {
|
||||
// we found a valid, canonical block!
|
||||
return r, b, nil
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// we found a block, but it wasn't considered canonical - keep looking
|
||||
if errors.Is(err, ErrNoCanonicalBlockForSlot) {
|
||||
// break once we've seen slot 0 (and prevent underflow)
|
||||
if hbs[0].Block().Slot() == params.BeaconConfig().GenesisSlot {
|
||||
if slot == params.BeaconConfig().GenesisSlot {
|
||||
break
|
||||
}
|
||||
target = hbs[0].Block().Slot() - 1
|
||||
slotAbove = slot
|
||||
continue
|
||||
}
|
||||
return [32]byte{}, nil, err
|
||||
return [32]byte{}, err
|
||||
}
|
||||
b, err := c.h.GenesisBlock(ctx)
|
||||
if err != nil {
|
||||
return [32]byte{}, nil, errors.Wrap(err, "db error while retrieving genesis block")
|
||||
}
|
||||
root, _, err := c.bestForSlot(ctx, []interfaces.SignedBeaconBlock{b})
|
||||
if err != nil {
|
||||
return [32]byte{}, nil, errors.Wrap(err, "problem retrieving genesis block")
|
||||
}
|
||||
return root, b, nil
|
||||
|
||||
return c.h.GenesisBlockRoot(ctx)
|
||||
}
|
||||
|
||||
// bestForSlot encapsulates several messy realities of the underlying db code, looping through multiple blocks,
|
||||
// performing null/validity checks, and using CanonicalChecker to only pick canonical blocks.
|
||||
func (c *CanonicalHistory) bestForSlot(ctx context.Context, hbs []interfaces.SignedBeaconBlock) ([32]byte, interfaces.SignedBeaconBlock, error) {
|
||||
for _, b := range hbs {
|
||||
if wrapper.BeaconBlockIsNil(b) != nil {
|
||||
continue
|
||||
}
|
||||
root, err := b.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
// use this error message to wrap a sentinel error for error type matching
|
||||
wrapped := errors.Wrap(ErrInvalidDBBlock, err.Error())
|
||||
msg := fmt.Sprintf("could not compute hash_tree_root for block at slot=%d", b.Block().Slot())
|
||||
return [32]byte{}, nil, errors.Wrap(wrapped, msg)
|
||||
}
|
||||
func (c *CanonicalHistory) bestForSlot(ctx context.Context, roots [][32]byte) ([32]byte, error) {
|
||||
for _, root := range roots {
|
||||
canon, err := c.cc.IsCanonical(ctx, root)
|
||||
if err != nil {
|
||||
return [32]byte{}, nil, errors.Wrap(err, "replayer could not check if block is canonical")
|
||||
return [32]byte{}, errors.Wrap(err, "replayer could not check if block is canonical")
|
||||
}
|
||||
if canon {
|
||||
return root, b, nil
|
||||
return root, nil
|
||||
}
|
||||
}
|
||||
return [32]byte{}, nil, errors.Wrap(ErrNoCanonicalBlockForSlot, "no good block for slot")
|
||||
return [32]byte{}, errors.Wrap(ErrNoCanonicalBlockForSlot, "no good block for slot")
|
||||
}
|
||||
|
||||
// ChainForSlot creates a value that satisfies the Replayer interface via db queries
|
||||
@@ -122,9 +107,13 @@ func (c *CanonicalHistory) bestForSlot(ctx context.Context, hbs []interfaces.Sig
|
||||
func (c *CanonicalHistory) chainForSlot(ctx context.Context, target types.Slot) (state.BeaconState, []interfaces.SignedBeaconBlock, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "canonicalChainer.chainForSlot")
|
||||
defer span.End()
|
||||
_, b, err := c.BlockForSlot(ctx, target)
|
||||
r, err := c.BlockRootForSlot(ctx, target)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, fmt.Sprintf("unable to find replay data for slot=%d", target))
|
||||
return nil, nil, errors.Wrapf(err, "no canonical block root found below slot=%d", target)
|
||||
}
|
||||
b, err := c.h.Block(ctx, r)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrapf(err, "unable to retrieve canonical block for slot, root=%#x", r)
|
||||
}
|
||||
s, descendants, err := c.ancestorChain(ctx, b)
|
||||
if err != nil {
|
||||
|
||||
@@ -12,8 +12,6 @@ import (
|
||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/testing/require"
|
||||
)
|
||||
|
||||
@@ -21,7 +19,7 @@ func TestBlockForSlotFuture(t *testing.T) {
|
||||
ch := &CanonicalHistory{
|
||||
cs: &mockCurrentSlotter{Slot: 0},
|
||||
}
|
||||
_, _, err := ch.BlockForSlot(context.Background(), 1)
|
||||
_, err := ch.BlockRootForSlot(context.Background(), 1)
|
||||
require.ErrorIs(t, err, ErrFutureSlotRequested)
|
||||
}
|
||||
|
||||
@@ -34,84 +32,54 @@ func TestChainForSlotFuture(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBestForSlot(t *testing.T) {
|
||||
nilBlock, err := wrapper.WrappedSignedBeaconBlock(ðpb.SignedBeaconBlock{})
|
||||
require.NoError(t, err)
|
||||
nilBody, err := wrapper.WrappedSignedBeaconBlock(ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{}})
|
||||
require.NoError(t, err)
|
||||
derp := errors.New("fake hash tree root method no hash good")
|
||||
badHTR := &mock.SignedBeaconBlock{BeaconBlock: &mock.BeaconBlock{HtrErr: derp, BeaconBlockBody: &mock.BeaconBlockBody{}}}
|
||||
var goodHTR [32]byte
|
||||
copy(goodHTR[:], []byte{23})
|
||||
var betterHTR [32]byte
|
||||
copy(betterHTR[:], []byte{42})
|
||||
good := &mock.SignedBeaconBlock{BeaconBlock: &mock.BeaconBlock{BeaconBlockBody: &mock.BeaconBlockBody{}, Htr: goodHTR}}
|
||||
better := &mock.SignedBeaconBlock{BeaconBlock: &mock.BeaconBlock{BeaconBlockBody: &mock.BeaconBlockBody{}, Htr: betterHTR}}
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
err error
|
||||
blocks []interfaces.SignedBeaconBlock
|
||||
best interfaces.SignedBeaconBlock
|
||||
roots [][32]byte
|
||||
root [32]byte
|
||||
cc CanonicalChecker
|
||||
}{
|
||||
{
|
||||
name: "empty list",
|
||||
err: ErrNoCanonicalBlockForSlot,
|
||||
blocks: []interfaces.SignedBeaconBlock{},
|
||||
name: "empty list",
|
||||
err: ErrNoCanonicalBlockForSlot,
|
||||
roots: [][32]byte{},
|
||||
},
|
||||
{
|
||||
name: "empty SignedBeaconBlock",
|
||||
err: ErrNoCanonicalBlockForSlot,
|
||||
blocks: []interfaces.SignedBeaconBlock{nil},
|
||||
name: "IsCanonical fail",
|
||||
roots: [][32]byte{goodHTR, betterHTR},
|
||||
cc: &mockCanonicalChecker{is: true, err: derp},
|
||||
err: derp,
|
||||
},
|
||||
{
|
||||
name: "empty BeaconBlock",
|
||||
err: ErrNoCanonicalBlockForSlot,
|
||||
blocks: []interfaces.SignedBeaconBlock{nilBlock},
|
||||
name: "all non-canonical",
|
||||
err: ErrNoCanonicalBlockForSlot,
|
||||
roots: [][32]byte{goodHTR, betterHTR},
|
||||
cc: &mockCanonicalChecker{is: false},
|
||||
},
|
||||
{
|
||||
name: "empty BeaconBlockBody",
|
||||
err: ErrNoCanonicalBlockForSlot,
|
||||
blocks: []interfaces.SignedBeaconBlock{nilBody},
|
||||
name: "one canonical",
|
||||
cc: &mockCanonicalChecker{is: true},
|
||||
root: goodHTR,
|
||||
roots: [][32]byte{goodHTR},
|
||||
},
|
||||
{
|
||||
name: "bad HTR",
|
||||
err: ErrInvalidDBBlock,
|
||||
blocks: []interfaces.SignedBeaconBlock{badHTR},
|
||||
name: "all canonical",
|
||||
cc: &mockCanonicalChecker{is: true},
|
||||
root: betterHTR,
|
||||
roots: [][32]byte{betterHTR, goodHTR},
|
||||
},
|
||||
{
|
||||
name: "IsCanonical fail",
|
||||
blocks: []interfaces.SignedBeaconBlock{good, better},
|
||||
cc: &mockCanonicalChecker{is: true, err: derp},
|
||||
err: derp,
|
||||
},
|
||||
{
|
||||
name: "all non-canonical",
|
||||
err: ErrNoCanonicalBlockForSlot,
|
||||
blocks: []interfaces.SignedBeaconBlock{good, better},
|
||||
cc: &mockCanonicalChecker{is: false},
|
||||
},
|
||||
{
|
||||
name: "one canonical",
|
||||
blocks: []interfaces.SignedBeaconBlock{good},
|
||||
cc: &mockCanonicalChecker{is: true},
|
||||
root: goodHTR,
|
||||
best: good,
|
||||
},
|
||||
{
|
||||
name: "all canonical",
|
||||
blocks: []interfaces.SignedBeaconBlock{better, good},
|
||||
cc: &mockCanonicalChecker{is: true},
|
||||
root: betterHTR,
|
||||
best: better,
|
||||
},
|
||||
{
|
||||
name: "first wins",
|
||||
blocks: []interfaces.SignedBeaconBlock{good, better},
|
||||
cc: &mockCanonicalChecker{is: true},
|
||||
root: goodHTR,
|
||||
best: good,
|
||||
name: "first wins",
|
||||
cc: &mockCanonicalChecker{is: true},
|
||||
root: goodHTR,
|
||||
roots: [][32]byte{goodHTR, betterHTR},
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
@@ -121,10 +89,9 @@ func TestBestForSlot(t *testing.T) {
|
||||
chk = c.cc
|
||||
}
|
||||
ch := &CanonicalHistory{cc: chk}
|
||||
r, b, err := ch.bestForSlot(context.Background(), c.blocks)
|
||||
r, err := ch.bestForSlot(context.Background(), c.roots)
|
||||
if c.err == nil {
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, c.best, b)
|
||||
require.Equal(t, c.root, r)
|
||||
} else {
|
||||
require.ErrorIs(t, err, c.err)
|
||||
@@ -164,13 +131,11 @@ func TestCanonicalBlockForSlotHappy(t *testing.T) {
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
bs, err := hist.HighestSlotBlocksBelow(ctx, c.slot+1)
|
||||
_, rs, err := hist.HighestRootsBelowSlot(ctx, c.slot+1)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(bs), 1)
|
||||
r, err := bs[0].Block().HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, hist.slotMap[c.highest], r)
|
||||
cr, _, err := ch.BlockForSlot(ctx, c.slot)
|
||||
require.Equal(t, len(rs), 1)
|
||||
require.Equal(t, hist.slotMap[c.highest], rs[0])
|
||||
cr, err := ch.BlockRootForSlot(ctx, c.slot)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, hist.slotMap[c.canon], cr)
|
||||
})
|
||||
@@ -187,47 +152,49 @@ func TestCanonicalBlockForSlotNonHappy(t *testing.T) {
|
||||
}
|
||||
hist := newMockHistory(t, specs, end+1)
|
||||
|
||||
genesis, err := hist.GenesisBlockRoot(ctx)
|
||||
require.NoError(t, err)
|
||||
slotOrderObserved := make([]types.Slot, 0)
|
||||
derp := errors.New("HighestSlotBlocksBelow don't work")
|
||||
derp := errors.New("HighestRootsBelowSlot don't work")
|
||||
// since only the end block and genesis are canonical, once the slot drops below
|
||||
// end, we should always get genesis
|
||||
cases := []struct {
|
||||
name string
|
||||
slot types.Slot
|
||||
canon CanonicalChecker
|
||||
overrideHighest func(context.Context, types.Slot) ([]interfaces.SignedBeaconBlock, error)
|
||||
overrideHighest func(context.Context, types.Slot) (types.Slot, [][32]byte, error)
|
||||
slotOrderExpected []types.Slot
|
||||
err error
|
||||
root [32]byte
|
||||
}{
|
||||
{
|
||||
name: "HighestSlotBlocksBelow not called for genesis",
|
||||
overrideHighest: func(_ context.Context, _ types.Slot) ([]interfaces.SignedBeaconBlock, error) {
|
||||
return nil, derp
|
||||
name: "HighestRootsBelowSlot not called for genesis",
|
||||
overrideHighest: func(_ context.Context, _ types.Slot) (types.Slot, [][32]byte, error) {
|
||||
return 0, [][32]byte{}, derp
|
||||
},
|
||||
root: hist.slotMap[0],
|
||||
},
|
||||
{
|
||||
name: "wrapped error from HighestSlotBlocksBelow returned",
|
||||
name: "wrapped error from HighestRootsBelowSlot returned",
|
||||
err: derp,
|
||||
overrideHighest: func(_ context.Context, _ types.Slot) ([]interfaces.SignedBeaconBlock, error) {
|
||||
return nil, derp
|
||||
overrideHighest: func(_ context.Context, _ types.Slot) (types.Slot, [][32]byte, error) {
|
||||
return 0, [][32]byte{}, derp
|
||||
},
|
||||
slot: end,
|
||||
},
|
||||
{
|
||||
name: "HighestSlotBlocksBelow empty list",
|
||||
name: "HighestRootsBelowSlot empty list",
|
||||
err: ErrNoBlocksBelowSlot,
|
||||
overrideHighest: func(_ context.Context, _ types.Slot) ([]interfaces.SignedBeaconBlock, error) {
|
||||
return []interfaces.SignedBeaconBlock{}, nil
|
||||
overrideHighest: func(_ context.Context, _ types.Slot) (types.Slot, [][32]byte, error) {
|
||||
return 0, [][32]byte{}, nil
|
||||
},
|
||||
slot: end,
|
||||
},
|
||||
{
|
||||
name: "HighestSlotBlocksBelow no canonical",
|
||||
err: ErrNoCanonicalBlockForSlot,
|
||||
name: "HighestRootsBelowSlot no canonical",
|
||||
canon: &mockCanonicalChecker{is: false},
|
||||
slot: end,
|
||||
root: genesis,
|
||||
},
|
||||
{
|
||||
name: "slot ordering correct - only genesis canonical",
|
||||
@@ -237,11 +204,11 @@ func TestCanonicalBlockForSlotNonHappy(t *testing.T) {
|
||||
}
|
||||
return false, nil
|
||||
}},
|
||||
overrideHighest: func(_ context.Context, s types.Slot) ([]interfaces.SignedBeaconBlock, error) {
|
||||
overrideHighest: func(_ context.Context, s types.Slot) (types.Slot, [][32]byte, error) {
|
||||
slotOrderObserved = append(slotOrderObserved, s)
|
||||
// this allows the mock HighestSlotBlocksBelow to continue to execute now that we've recorded
|
||||
// this allows the mock HighestRootsBelowSlot to continue to execute now that we've recorded
|
||||
// the slot in our channel
|
||||
return nil, errFallThroughOverride
|
||||
return 0, nil, errFallThroughOverride
|
||||
},
|
||||
slotOrderExpected: []types.Slot{156, 155, 150, 100},
|
||||
slot: end,
|
||||
@@ -255,11 +222,11 @@ func TestCanonicalBlockForSlotNonHappy(t *testing.T) {
|
||||
}
|
||||
return false, nil
|
||||
}},
|
||||
overrideHighest: func(_ context.Context, s types.Slot) ([]interfaces.SignedBeaconBlock, error) {
|
||||
overrideHighest: func(_ context.Context, s types.Slot) (types.Slot, [][32]byte, error) {
|
||||
slotOrderObserved = append(slotOrderObserved, s)
|
||||
// this allows the mock HighestSlotBlocksBelow to continue to execute now that we've recorded
|
||||
// this allows the mock HighestRootsBelowSlot to continue to execute now that we've recorded
|
||||
// the slot in our channel
|
||||
return nil, errFallThroughOverride
|
||||
return 0, nil, errFallThroughOverride
|
||||
},
|
||||
slotOrderExpected: []types.Slot{156, 155, 150},
|
||||
slot: end,
|
||||
@@ -274,14 +241,14 @@ func TestCanonicalBlockForSlotNonHappy(t *testing.T) {
|
||||
}
|
||||
ch := &CanonicalHistory{h: hist, cc: canon, cs: hist}
|
||||
hist.overrideHighestSlotBlocksBelow = c.overrideHighest
|
||||
r, _, err := ch.BlockForSlot(ctx, c.slot)
|
||||
r, err := ch.BlockRootForSlot(ctx, c.slot)
|
||||
if c.err == nil {
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
require.ErrorIs(t, err, c.err)
|
||||
}
|
||||
if len(c.slotOrderExpected) > 0 {
|
||||
require.Equal(t, len(c.slotOrderExpected), len(slotOrderObserved), "HighestSlotBlocksBelow not called the expected number of times")
|
||||
require.Equal(t, len(c.slotOrderExpected), len(slotOrderObserved), "HighestRootsBelowSlot not called the expected number of times")
|
||||
for i := range c.slotOrderExpected {
|
||||
require.Equal(t, c.slotOrderExpected[i], slotOrderObserved[i])
|
||||
}
|
||||
|
||||
@@ -55,24 +55,20 @@ func (s *State) MigrateToCold(ctx context.Context, fRoot [32]byte) error {
|
||||
aRoot = cached.root
|
||||
aState = cached.state
|
||||
} else {
|
||||
blks, err := s.beaconDB.HighestSlotBlocksBelow(ctx, slot)
|
||||
_, roots, err := s.beaconDB.HighestRootsBelowSlot(ctx, slot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Given the block has been finalized, the db should not have more than one block in a given slot.
|
||||
// We should error out when this happens.
|
||||
if len(blks) != 1 {
|
||||
if len(roots) != 1 {
|
||||
return errUnknownBlock
|
||||
}
|
||||
missingRoot, err := blks[0].Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
aRoot = missingRoot
|
||||
aRoot = roots[0]
|
||||
// There's no need to generate the state if the state already exists in the DB.
|
||||
// We can skip saving the state.
|
||||
if !s.beaconDB.HasState(ctx, aRoot) {
|
||||
aState, err = s.StateByRoot(ctx, missingRoot)
|
||||
aState, err = s.StateByRoot(ctx, aRoot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ type mockHistory struct {
|
||||
states map[[32]byte]state.BeaconState
|
||||
hiddenStates map[[32]byte]state.BeaconState
|
||||
current types.Slot
|
||||
overrideHighestSlotBlocksBelow func(context.Context, types.Slot) ([]interfaces.SignedBeaconBlock, error)
|
||||
overrideHighestSlotBlocksBelow func(context.Context, types.Slot) (types.Slot, [][32]byte, error)
|
||||
}
|
||||
|
||||
type slotList []types.Slot
|
||||
@@ -98,13 +98,13 @@ func (m slotList) Swap(i, j int) {
|
||||
m[i], m[j] = m[j], m[i]
|
||||
}
|
||||
|
||||
var errFallThroughOverride = errors.New("override yielding control back to real HighestSlotBlocksBelow")
|
||||
var errFallThroughOverride = errors.New("override yielding control back to real HighestRootsBelowSlot")
|
||||
|
||||
func (m *mockHistory) HighestSlotBlocksBelow(_ context.Context, slot types.Slot) ([]interfaces.SignedBeaconBlock, error) {
|
||||
func (m *mockHistory) HighestRootsBelowSlot(_ context.Context, slot types.Slot) (types.Slot, [][32]byte, error) {
|
||||
if m.overrideHighestSlotBlocksBelow != nil {
|
||||
s, err := m.overrideHighestSlotBlocksBelow(context.Background(), slot)
|
||||
s, r, err := m.overrideHighestSlotBlocksBelow(context.Background(), slot)
|
||||
if !errors.Is(err, errFallThroughOverride) {
|
||||
return s, err
|
||||
return s, r, err
|
||||
}
|
||||
}
|
||||
if len(m.slotIndex) == 0 && len(m.slotMap) > 0 {
|
||||
@@ -115,20 +115,20 @@ func (m *mockHistory) HighestSlotBlocksBelow(_ context.Context, slot types.Slot)
|
||||
}
|
||||
for _, s := range m.slotIndex {
|
||||
if s < slot {
|
||||
return []interfaces.SignedBeaconBlock{m.blocks[m.slotMap[s]]}, nil
|
||||
return s, [][32]byte{m.slotMap[s]}, nil
|
||||
}
|
||||
}
|
||||
return []interfaces.SignedBeaconBlock{}, nil
|
||||
return 0, [][32]byte{}, nil
|
||||
}
|
||||
|
||||
var errGenesisBlockNotFound = errors.New("canonical genesis block not found in db")
|
||||
|
||||
func (m *mockHistory) GenesisBlock(_ context.Context) (interfaces.SignedBeaconBlock, error) {
|
||||
func (m *mockHistory) GenesisBlockRoot(_ context.Context) ([32]byte, error) {
|
||||
genesisRoot, ok := m.slotMap[0]
|
||||
if !ok {
|
||||
return nil, errGenesisBlockNotFound
|
||||
return [32]byte{}, errGenesisBlockNotFound
|
||||
}
|
||||
return m.blocks[genesisRoot], nil
|
||||
return genesisRoot, nil
|
||||
}
|
||||
|
||||
func (m *mockHistory) Block(_ context.Context, blockRoot [32]byte) (interfaces.SignedBeaconBlock, error) {
|
||||
|
||||
@@ -27,8 +27,8 @@ const (
|
||||
|
||||
// HistoryAccessor describes the minimum set of database methods needed to support the ReplayerBuilder.
|
||||
type HistoryAccessor interface {
|
||||
HighestSlotBlocksBelow(ctx context.Context, slot types.Slot) ([]interfaces.SignedBeaconBlock, error)
|
||||
GenesisBlock(ctx context.Context) (interfaces.SignedBeaconBlock, error)
|
||||
HighestRootsBelowSlot(ctx context.Context, slot types.Slot) (types.Slot, [][32]byte, error)
|
||||
GenesisBlockRoot(ctx context.Context) ([32]byte, error)
|
||||
Block(ctx context.Context, blockRoot [32]byte) (interfaces.SignedBeaconBlock, error)
|
||||
StateOrError(ctx context.Context, blockRoot [32]byte) (state.BeaconState, error)
|
||||
}
|
||||
|
||||
@@ -64,13 +64,7 @@ func ValidatorFieldRoots(hasher ssz.HashFn, validator *ethpb.Validator) ([][32]b
|
||||
// a list of uint64 and mixed with registry limit.
|
||||
func Uint64ListRootWithRegistryLimit(balances []uint64) ([32]byte, error) {
|
||||
hasher := hash.CustomSHA256Hasher()
|
||||
balancesMarshaling := make([][]byte, 0, len(balances))
|
||||
for i := 0; i < len(balances); i++ {
|
||||
balanceBuf := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(balanceBuf, balances[i])
|
||||
balancesMarshaling = append(balancesMarshaling, balanceBuf)
|
||||
}
|
||||
balancesChunks, err := ssz.PackByChunk(balancesMarshaling)
|
||||
balancesChunks, err := PackUint64IntoChunks(balances)
|
||||
if err != nil {
|
||||
return [32]byte{}, errors.Wrap(err, "could not pack balances into chunks")
|
||||
}
|
||||
@@ -87,3 +81,37 @@ func Uint64ListRootWithRegistryLimit(balances []uint64) ([32]byte, error) {
|
||||
binary.LittleEndian.PutUint64(balancesLengthRoot, uint64(len(balances)))
|
||||
return ssz.MixInLength(balancesRootsRoot, balancesLengthRoot), nil
|
||||
}
|
||||
|
||||
// PackUint64IntoChunks packs a list of uint64 values into 32 byte roots.
|
||||
func PackUint64IntoChunks(vals []uint64) ([][32]byte, error) {
|
||||
// Initialize how many uint64 values we can pack
|
||||
// into a single chunk(32 bytes). Each uint64 value
|
||||
// would take up 8 bytes.
|
||||
numOfElems := 4
|
||||
sizeOfElem := 32 / numOfElems
|
||||
// Determine total number of chunks to be
|
||||
// allocated to provided list of unsigned
|
||||
// 64-bit integers.
|
||||
numOfChunks := len(vals) / numOfElems
|
||||
// Add an extra chunk if the list size
|
||||
// is not a perfect multiple of the number
|
||||
// of elements.
|
||||
if len(vals)%numOfElems != 0 {
|
||||
numOfChunks++
|
||||
}
|
||||
chunkList := make([][32]byte, numOfChunks)
|
||||
for idx, b := range vals {
|
||||
// In order to determine how to pack in the uint64 value by index into
|
||||
// our chunk list we need to determine a few things.
|
||||
// 1) The chunk which the particular uint64 value corresponds to.
|
||||
// 2) The position of the value in the chunk itself.
|
||||
//
|
||||
// Once we have determined these 2 values we can simply find the correct
|
||||
// section of contiguous bytes to insert the value in the chunk.
|
||||
chunkIdx := idx / numOfElems
|
||||
idxInChunk := idx % numOfElems
|
||||
chunkPos := idxInChunk * sizeOfElem
|
||||
binary.LittleEndian.PutUint64(chunkList[chunkIdx][chunkPos:chunkPos+sizeOfElem], b)
|
||||
}
|
||||
return chunkList, nil
|
||||
}
|
||||
|
||||
@@ -77,6 +77,8 @@ func InitializeFromProtoUnsafe(st *ethpb.BeaconState) (state.BeaconState, error)
|
||||
b.sharedFieldReferences[historicalRoots] = stateutil.NewRef(1)
|
||||
|
||||
state.StateCount.Inc()
|
||||
// Finalizer runs when dst is being destroyed in garbage collection.
|
||||
runtime.SetFinalizer(b, finalizerCleanup)
|
||||
return b, nil
|
||||
}
|
||||
|
||||
@@ -174,24 +176,7 @@ func (b *BeaconState) Copy() state.BeaconState {
|
||||
|
||||
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)
|
||||
})
|
||||
runtime.SetFinalizer(dst, finalizerCleanup)
|
||||
return dst
|
||||
}
|
||||
|
||||
@@ -439,3 +424,22 @@ func (b *BeaconState) resetFieldTrie(index types.FieldIndex, elements interface{
|
||||
b.dirtyIndices[index] = []uint64{}
|
||||
return nil
|
||||
}
|
||||
|
||||
func finalizerCleanup(b *BeaconState) {
|
||||
fieldCount := params.BeaconConfig().BeaconStateFieldCount
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -78,6 +78,8 @@ func InitializeFromProtoUnsafe(st *ethpb.BeaconStateAltair) (state.BeaconState,
|
||||
b.sharedFieldReferences[historicalRoots] = stateutil.NewRef(1)
|
||||
|
||||
state.StateCount.Inc()
|
||||
// Finalizer runs when dst is being destroyed in garbage collection.
|
||||
runtime.SetFinalizer(b, finalizerCleanup)
|
||||
return b, nil
|
||||
}
|
||||
|
||||
@@ -179,23 +181,7 @@ func (b *BeaconState) Copy() state.BeaconState {
|
||||
|
||||
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)
|
||||
})
|
||||
runtime.SetFinalizer(dst, finalizerCleanup)
|
||||
|
||||
return dst
|
||||
}
|
||||
@@ -426,3 +412,22 @@ func (b *BeaconState) resetFieldTrie(index types.FieldIndex, elements interface{
|
||||
b.dirtyIndices[index] = []uint64{}
|
||||
return nil
|
||||
}
|
||||
|
||||
func finalizerCleanup(b *BeaconState) {
|
||||
fieldCount := params.BeaconConfig().BeaconStateAltairFieldCount
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -78,6 +78,8 @@ func InitializeFromProtoUnsafe(st *ethpb.BeaconStateBellatrix) (state.BeaconStat
|
||||
b.sharedFieldReferences[historicalRoots] = stateutil.NewRef(1)
|
||||
b.sharedFieldReferences[latestExecutionPayloadHeader] = stateutil.NewRef(1) // New in Bellatrix.
|
||||
state.StateCount.Inc()
|
||||
// Finalizer runs when dst is being destroyed in garbage collection.
|
||||
runtime.SetFinalizer(b, finalizerCleanup)
|
||||
return b, nil
|
||||
}
|
||||
|
||||
@@ -179,23 +181,7 @@ func (b *BeaconState) Copy() state.BeaconState {
|
||||
}
|
||||
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)
|
||||
})
|
||||
runtime.SetFinalizer(dst, finalizerCleanup)
|
||||
|
||||
return dst
|
||||
}
|
||||
@@ -421,3 +407,22 @@ func (b *BeaconState) resetFieldTrie(index types.FieldIndex, elements interface{
|
||||
b.dirtyIndices[index] = []uint64{}
|
||||
return nil
|
||||
}
|
||||
|
||||
func finalizerCleanup(b *BeaconState) {
|
||||
fieldCount := params.BeaconConfig().BeaconStateBellatrixFieldCount
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ go_library(
|
||||
],
|
||||
deps = [
|
||||
"//cmd:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@com_github_urfave_cli_v2//:go_default_library",
|
||||
|
||||
@@ -5,7 +5,6 @@ package flags
|
||||
import (
|
||||
"strings"
|
||||
|
||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/config/params"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
@@ -215,7 +214,7 @@ var (
|
||||
SuggestedFeeRecipient = &cli.StringFlag{
|
||||
Name: "suggested-fee-recipient",
|
||||
Usage: "Post bellatrix, this address will receive the transaction fees produced by any blocks from this node. Default to junk whilst bellatrix is in development state. Validator client can override this value through the preparebeaconproposer api.",
|
||||
Value: fieldparams.EthBurnAddressHex,
|
||||
Value: params.BeaconConfig().EthBurnAddressHex,
|
||||
}
|
||||
// TerminalTotalDifficultyOverride specifies the total difficulty to manual overrides the `TERMINAL_TOTAL_DIFFICULTY` parameter.
|
||||
TerminalTotalDifficultyOverride = &cli.StringFlag{
|
||||
|
||||
29
cmd/beacon-chain/jwt/BUILD.bazel
Normal file
29
cmd/beacon-chain/jwt/BUILD.bazel
Normal file
@@ -0,0 +1,29 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["jwt.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/cmd/beacon-chain/jwt",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//cmd:go_default_library",
|
||||
"//crypto/rand:go_default_library",
|
||||
"//io/file:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_sirupsen_logrus//:go_default_library",
|
||||
"@com_github_urfave_cli_v2//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["jwt_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//cmd:go_default_library",
|
||||
"//io/file:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_urfave_cli_v2//:go_default_library",
|
||||
],
|
||||
)
|
||||
71
cmd/beacon-chain/jwt/jwt.go
Normal file
71
cmd/beacon-chain/jwt/jwt.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package jwt
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/prysmaticlabs/prysm/cmd"
|
||||
"github.com/prysmaticlabs/prysm/crypto/rand"
|
||||
"github.com/prysmaticlabs/prysm/io/file"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
const (
|
||||
secretFileName = "jwt.hex"
|
||||
)
|
||||
|
||||
var Commands = &cli.Command{
|
||||
Name: "generate-auth-secret",
|
||||
Usage: "creates a random, 32 byte hex string in a plaintext file to be used for authenticating JSON-RPC requests. If no --output-file flag is defined, the file will be created in the current working directory",
|
||||
Description: `creates a random, 32 byte hex string in a plaintext file to be used for authenticating JSON-RPC requests. If no --output-file flag is defined, the file will be created in the current working directory`,
|
||||
Flags: cmd.WrapFlags([]cli.Flag{
|
||||
cmd.JwtOutputFileFlag,
|
||||
}),
|
||||
Action: generateAuthSecretInFile,
|
||||
}
|
||||
|
||||
func generateAuthSecretInFile(c *cli.Context) error {
|
||||
fileName := secretFileName
|
||||
specifiedFilePath := c.String(cmd.JwtOutputFileFlag.Name)
|
||||
if len(specifiedFilePath) > 0 {
|
||||
fileName = specifiedFilePath
|
||||
}
|
||||
var err error
|
||||
fileName, err = file.ExpandPath(fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fileDir := filepath.Dir(fileName)
|
||||
exists, err := file.HasDir(fileDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !exists {
|
||||
if err := file.MkdirAll(fileDir); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
secret, err := generateRandomHexString()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := file.WriteFile(fileName, []byte(secret)); err != nil {
|
||||
return err
|
||||
}
|
||||
logrus.Infof("Successfully wrote JSON-RPC authentication secret to file %s", fileName)
|
||||
return nil
|
||||
}
|
||||
|
||||
func generateRandomHexString() (string, error) {
|
||||
secret := make([]byte, 32)
|
||||
randGen := rand.NewGenerator()
|
||||
n, err := randGen.Read(secret)
|
||||
if err != nil {
|
||||
return "", err
|
||||
} else if n <= 0 {
|
||||
return "", errors.New("rand: unexpected length")
|
||||
}
|
||||
return hexutil.Encode(secret), nil
|
||||
}
|
||||
86
cmd/beacon-chain/jwt/jwt_test.go
Normal file
86
cmd/beacon-chain/jwt/jwt_test.go
Normal file
@@ -0,0 +1,86 @@
|
||||
package jwt
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/prysmaticlabs/prysm/cmd"
|
||||
"github.com/prysmaticlabs/prysm/io/file"
|
||||
"github.com/prysmaticlabs/prysm/testing/require"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
func Test_generateJWTSecret(t *testing.T) {
|
||||
t.Run("command should be available", func(t *testing.T) {
|
||||
generateJwtCommand := Commands
|
||||
require.Equal(t, true, generateJwtCommand.Name == "generate-auth-secret")
|
||||
})
|
||||
t.Run("should create proper file in current directory", func(t *testing.T) {
|
||||
require.NoError(t, os.RemoveAll(secretFileName))
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, os.RemoveAll(secretFileName))
|
||||
})
|
||||
app := cli.App{}
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
cliCtx := cli.NewContext(&app, set, nil)
|
||||
err := generateAuthSecretInFile(cliCtx)
|
||||
require.NoError(t, err)
|
||||
|
||||
// We check the file has the contents we expect.
|
||||
checkAuthFileIntegrity(t, secretFileName)
|
||||
})
|
||||
t.Run("should create proper file in specified folder", func(t *testing.T) {
|
||||
customOutput := filepath.Join("data", "item.txt")
|
||||
require.NoError(t, os.RemoveAll(filepath.Dir(customOutput)))
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, os.RemoveAll(filepath.Dir(customOutput)))
|
||||
})
|
||||
app := cli.App{}
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.String(cmd.JwtOutputFileFlag.Name, customOutput, "")
|
||||
require.NoError(t, set.Set(cmd.JwtOutputFileFlag.Name, customOutput))
|
||||
|
||||
cliCtx := cli.NewContext(&app, set, nil)
|
||||
err := generateAuthSecretInFile(cliCtx)
|
||||
require.NoError(t, err)
|
||||
|
||||
// We check the file has the contents we expect.
|
||||
checkAuthFileIntegrity(t, customOutput)
|
||||
})
|
||||
t.Run("creates proper file in nested specified folder", func(t *testing.T) {
|
||||
rootDirectory := "data"
|
||||
customOutputPath := filepath.Join(rootDirectory, "nest", "nested", "item.txt")
|
||||
require.NoError(t, os.RemoveAll(filepath.Dir(customOutputPath)))
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, os.RemoveAll(rootDirectory))
|
||||
_, err := os.Stat(customOutputPath)
|
||||
require.Equal(t, true, err != nil)
|
||||
})
|
||||
app := cli.App{}
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.String(cmd.JwtOutputFileFlag.Name, customOutputPath, "")
|
||||
require.NoError(t, set.Set(cmd.JwtOutputFileFlag.Name, customOutputPath))
|
||||
|
||||
cliCtx := cli.NewContext(&app, set, nil)
|
||||
err := generateAuthSecretInFile(cliCtx)
|
||||
require.NoError(t, err)
|
||||
|
||||
// We check the file has the contents we expect.
|
||||
checkAuthFileIntegrity(t, customOutputPath)
|
||||
})
|
||||
}
|
||||
|
||||
func checkAuthFileIntegrity(t testing.TB, fPath string) {
|
||||
fileInfo, err := os.Stat(fPath)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, true, fileInfo != nil)
|
||||
|
||||
enc, err := file.ReadFileAsBytes(fPath)
|
||||
require.NoError(t, err)
|
||||
decoded, err := hexutil.Decode(string(enc))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 32, len(decoded))
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Package cmd defines the command line flags for the shared utlities.
|
||||
// Package cmd defines the command line flags for the shared utilities.
|
||||
package cmd
|
||||
|
||||
import (
|
||||
@@ -255,6 +255,12 @@ var (
|
||||
Usage: "Specifies the timeout value for API requests in seconds",
|
||||
Value: 120,
|
||||
}
|
||||
// JwtOutputFileFlag specifies the JWT file path that gets generated into when invoked by generate-jwt-secret.
|
||||
JwtOutputFileFlag = &cli.StringFlag{
|
||||
Name: "output-file",
|
||||
Usage: "Target file path for outputting a generated JWT secret to be used for JSON-RPC authentication",
|
||||
Aliases: []string{"o"},
|
||||
}
|
||||
)
|
||||
|
||||
// LoadFlagsFromConfig sets flags values from config file if ConfigFileFlag is set.
|
||||
|
||||
31
cmd/ssz/BUILD.bazel
Normal file
31
cmd/ssz/BUILD.bazel
Normal file
@@ -0,0 +1,31 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_binary")
|
||||
load("@prysm//tools/go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"benchmark.go",
|
||||
"generate.go",
|
||||
"ir.go",
|
||||
"main.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/cmd/ssz",
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
"//proto/beacon/p2p/v1:go_default_library",
|
||||
"//proto/eth/v1:go_default_library",
|
||||
"//proto/eth/v1alpha1:go_default_library",
|
||||
"//sszgen:go_default_library",
|
||||
"//sszgen/backend:go_default_library",
|
||||
"//sszgen/testutil:go_default_library",
|
||||
"@com_github_ferranbt_fastssz//:go_default_library",
|
||||
"@com_github_golang_snappy//:go_default_library",
|
||||
"@com_github_urfave_cli_v2//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_binary(
|
||||
name = "ssz",
|
||||
embed = [":go_default_library"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
315
cmd/ssz/benchmark.go
Normal file
315
cmd/ssz/benchmark.go
Normal file
@@ -0,0 +1,315 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
fssz "github.com/ferranbt/fastssz"
|
||||
"github.com/golang/snappy"
|
||||
"github.com/urfave/cli/v2"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime/pprof"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
pbbeacon "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
|
||||
pbethv1 "github.com/prysmaticlabs/prysm/proto/eth/v1"
|
||||
pbethv1alpha1 "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
)
|
||||
|
||||
const methodsetMethodical = "methodical"
|
||||
const methodsetFast = "fastssz"
|
||||
|
||||
var methodset string
|
||||
var benchmarkRepeat int
|
||||
var skipList string
|
||||
var benchmark = &cli.Command{
|
||||
Name: "benchmark",
|
||||
ArgsUsage: "<path to spectest repository>",
|
||||
Aliases: []string{"bench"},
|
||||
Usage: "Benchmark for comparing fastssz with methodical to generate profiling data",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "methodset",
|
||||
Value: "",
|
||||
Usage: "which methodset to evaluate, \"fastssz\" or \"methodical\"",
|
||||
Destination: &methodset,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "skip-list",
|
||||
Value: "",
|
||||
Usage: "comma-separated list of types to skip (useful for excluding that big ole BeaconState).",
|
||||
Destination: &skipList,
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "repeat",
|
||||
Usage: "how many times to repeat each unmarshal/marshal operation (increase for more stability)",
|
||||
Destination: &benchmarkRepeat,
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
// validate args
|
||||
spectestPath := c.Args().Get(0)
|
||||
if spectestPath == "" {
|
||||
cli.ShowCommandHelp(c, "benchmark")
|
||||
return fmt.Errorf("error: missing required <path to spectest repository> argument")
|
||||
}
|
||||
if methodset != methodsetMethodical && methodset != methodsetFast {
|
||||
cli.ShowCommandHelp(c, "benchmark")
|
||||
return fmt.Errorf("error: --methodset must be equal to \"fastssz\" or \"methodical\"")
|
||||
}
|
||||
|
||||
// initialize profiling, profilePath will fail if spectest path is weird
|
||||
ppath, err := profilePath(spectestPath, methodset)
|
||||
f, err := os.Create(ppath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pprof.StartCPUProfile(f)
|
||||
defer pprof.StopCPUProfile()
|
||||
|
||||
skip := make(map[string]struct{})
|
||||
if skipList != "" {
|
||||
skipNames := strings.Split(skipList, ",")
|
||||
for _, s := range skipNames {
|
||||
skip[s] = struct{}{}
|
||||
}
|
||||
}
|
||||
// use regex to parse test cases out of a dirwalk
|
||||
tcs, err := findTestCases(spectestPath, skip)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("Found %d test cases", len(tcs))
|
||||
for _, tc := range tcs {
|
||||
err := executeTestCase(tc, methodset, benchmarkRepeat)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func profilePath(path string, methodset string) (string, error) {
|
||||
pre := regexp.MustCompile(`.*\/tests\/(mainnet|minimal)\/(altair|merge|phase0)\/ssz_static`)
|
||||
parts := pre.FindStringSubmatch(path)
|
||||
if len(parts) != 3 {
|
||||
return "", fmt.Errorf("unfamiliar spectest path, can't determine test configuration and phase")
|
||||
}
|
||||
return fmt.Sprintf("cpu-%s-%s-%s.%s.pprof", methodset, parts[1], parts[2], time.Now().Format("20060102-150405")), nil
|
||||
}
|
||||
|
||||
func executeTestCase(tc *TestCase, methodset string, repeat int) error {
|
||||
b, err := tc.MarshaledBytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tys := make([]pbinit, 0)
|
||||
for _, c := range []map[string]pbinit{casesBeaconP2pV1,casesV1,casesV1Alpha1} {
|
||||
pi, ok := c[tc.typeName]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
tys = append(tys, pi)
|
||||
}
|
||||
for i := 0; i <= repeat; i++ {
|
||||
for _, fn := range tys {
|
||||
essz := fn()
|
||||
if methodset == methodsetFast {
|
||||
err := essz.UnmarshalSSZ(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = essz.MarshalSSZ()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = essz.HashTreeRoot()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if methodset == methodsetMethodical {
|
||||
err := essz.XXUnmarshalSSZ(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = essz.XXMarshalSSZ()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = essz.XXHashTreeRoot()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func findTestCases(path string, skip map[string]struct{}) ([]*TestCase, error) {
|
||||
var re = regexp.MustCompile(`.*\/tests\/(mainnet|minimal)\/(altair|merge|phase0)\/ssz_static\/(.*)\/ssz_random\/(case_\d+)`)
|
||||
tcs := make([]*TestCase, 0)
|
||||
testCaseFromPath := func (path string, d fs.DirEntry, err error) error {
|
||||
if !d.IsDir() {
|
||||
return nil
|
||||
}
|
||||
parts := re.FindStringSubmatch(path)
|
||||
if len(parts) != 5 {
|
||||
return nil
|
||||
}
|
||||
tc := &TestCase{
|
||||
path: path,
|
||||
config: parts[1],
|
||||
phase: parts[2],
|
||||
typeName: parts[3],
|
||||
caseId: parts[4],
|
||||
}
|
||||
if tc.config == "" || tc.phase == "" || tc.typeName == "" || tc.caseId == "" {
|
||||
return nil
|
||||
}
|
||||
if _, ok := skip[tc.typeName]; ok {
|
||||
return nil
|
||||
}
|
||||
tcs = append(tcs, tc)
|
||||
return nil
|
||||
}
|
||||
err := filepath.WalkDir(path, testCaseFromPath)
|
||||
|
||||
return tcs, err
|
||||
}
|
||||
|
||||
type SSZRoots struct {
|
||||
Root string `json:"root"`
|
||||
SigningRoot string `json:"signing_root"`
|
||||
}
|
||||
|
||||
type SSZValue struct {
|
||||
Message json.RawMessage `json:"message"`
|
||||
Signature string `json:"signature"`// hex encoded '0x...'
|
||||
}
|
||||
|
||||
type TestCase struct {
|
||||
path string
|
||||
config string
|
||||
phase string
|
||||
typeName string
|
||||
caseId string
|
||||
}
|
||||
|
||||
func (tc *TestCase) MarshaledBytes() ([]byte, error) {
|
||||
fh, err := os.Open(path.Join(tc.path, "serialized.ssz_snappy"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer fh.Close()
|
||||
buf := bytes.NewBuffer(nil)
|
||||
_, err = buf.ReadFrom(fh)
|
||||
return snappy.Decode(nil, buf.Bytes())
|
||||
}
|
||||
|
||||
func (tc *TestCase) Value() (*SSZValue, error) {
|
||||
fh, err := os.Open(path.Join(tc.path, "value.yaml"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer fh.Close()
|
||||
d := json.NewDecoder(fh)
|
||||
v := &SSZValue{}
|
||||
err = d.Decode(v)
|
||||
return v, err
|
||||
}
|
||||
|
||||
func (tc *TestCase) Roots() (*SSZRoots, error) {
|
||||
fh, err := os.Open(path.Join(tc.path, "roots.yaml"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer fh.Close()
|
||||
d := json.NewDecoder(fh)
|
||||
r := &SSZRoots{}
|
||||
err = d.Decode(r)
|
||||
return r, err
|
||||
}
|
||||
|
||||
//rootBytes, err := hex.DecodeString(rootsYaml.Root[2:])
|
||||
//require.NoError(t, err)
|
||||
//require.DeepEqual(t, rootBytes, root[:], "Did not receive expected hash tree root")
|
||||
|
||||
type ExperimentalSSZ interface {
|
||||
XXUnmarshalSSZ(buf []byte) error
|
||||
XXMarshalSSZ() ([]byte, error)
|
||||
XXHashTreeRoot() ([32]byte, error)
|
||||
fssz.Unmarshaler
|
||||
fssz.Marshaler
|
||||
fssz.HashRoot
|
||||
}
|
||||
|
||||
type pbinit func() ExperimentalSSZ
|
||||
|
||||
var casesBeaconP2pV1 = map[string]pbinit{
|
||||
"BeaconState": func() ExperimentalSSZ { return &pbbeacon.BeaconState{} },
|
||||
"DepositMessage": func() ExperimentalSSZ { return &pbbeacon.DepositMessage{} },
|
||||
"Fork": func() ExperimentalSSZ { return &pbbeacon.Fork{} },
|
||||
"ForkData": func() ExperimentalSSZ { return &pbbeacon.ForkData{} },
|
||||
"HistoricalBatch": func() ExperimentalSSZ { return &pbbeacon.HistoricalBatch{} },
|
||||
"PendingAttestation": func() ExperimentalSSZ { return &pbbeacon.PendingAttestation{} },
|
||||
"SigningData": func() ExperimentalSSZ { return &pbbeacon.SigningData{} },
|
||||
}
|
||||
|
||||
var casesV1 map[string]pbinit = map[string]pbinit{
|
||||
"AggregateAndProof": func() ExperimentalSSZ { return &pbethv1.AggregateAttestationAndProof{} },
|
||||
"Attestation": func() ExperimentalSSZ { return &pbethv1.Attestation{} },
|
||||
"AttestationData": func() ExperimentalSSZ { return &pbethv1.AttestationData{} },
|
||||
"AttesterSlashing": func() ExperimentalSSZ { return &pbethv1.AttesterSlashing{} },
|
||||
"BeaconBlock": func() ExperimentalSSZ { return &pbethv1.BeaconBlock{} },
|
||||
"BeaconBlockBody": func() ExperimentalSSZ { return &pbethv1.BeaconBlockBody{} },
|
||||
"BeaconBlockHeader": func() ExperimentalSSZ { return &pbethv1.BeaconBlockHeader{} },
|
||||
// exists in proto/eth/v1, but fastssz methods are not genrated for it
|
||||
//"BeaconState": func() ExperimentalSSZ { return &pbethv1.BeaconState{} },
|
||||
"Checkpoint": func() ExperimentalSSZ { return &pbethv1.Checkpoint{} },
|
||||
"Deposit": func() ExperimentalSSZ { return &pbethv1.Deposit{} },
|
||||
"DepositData": func() ExperimentalSSZ { return &pbethv1.Deposit_Data{} },
|
||||
"Eth1Data": func() ExperimentalSSZ { return &pbethv1.Eth1Data{} },
|
||||
// Fork is defined in proto/eth/v1 package, but fastssz methods are not generated
|
||||
//"Fork": func() ExperimentalSSZ { return &pbethv1.Fork{} },
|
||||
"IndexedAttestation": func() ExperimentalSSZ { return &pbethv1.IndexedAttestation{} },
|
||||
// PendingAttestation is defined in proto/eth/v1 package, but fastssz methods are not generated
|
||||
//"PendingAttestation": func() ExperimentalSSZ { return &pbethv1.PendingAttestation{} },
|
||||
"ProposerSlashing": func() ExperimentalSSZ { return &pbethv1.ProposerSlashing{} },
|
||||
"SignedAggregateAndProof": func() ExperimentalSSZ { return &pbethv1.SignedAggregateAttestationAndProof{} },
|
||||
"SignedBeaconBlock": func() ExperimentalSSZ { return &pbethv1.SignedBeaconBlock{} },
|
||||
"SignedBeaconBlockHeader": func() ExperimentalSSZ { return &pbethv1.SignedBeaconBlockHeader{} },
|
||||
"SignedVoluntaryExit": func() ExperimentalSSZ { return &pbethv1.SignedVoluntaryExit{} },
|
||||
"Validator": func() ExperimentalSSZ { return &pbethv1.Validator{} },
|
||||
"VoluntaryExit": func() ExperimentalSSZ { return &pbethv1.VoluntaryExit{} },
|
||||
}
|
||||
|
||||
var casesV1Alpha1 map[string]pbinit = map[string]pbinit{
|
||||
"AggregateAndProof": func() ExperimentalSSZ { return &pbethv1alpha1.AggregateAttestationAndProof{} },
|
||||
"Attestation": func() ExperimentalSSZ { return &pbethv1alpha1.Attestation{} },
|
||||
"AttestationData": func() ExperimentalSSZ { return &pbethv1alpha1.AttestationData{} },
|
||||
"AttesterSlashing": func() ExperimentalSSZ { return &pbethv1alpha1.AttesterSlashing{} },
|
||||
"BeaconBlock": func() ExperimentalSSZ { return &pbethv1alpha1.BeaconBlock{} },
|
||||
"BeaconBlockBody": func() ExperimentalSSZ { return &pbethv1alpha1.BeaconBlockBody{} },
|
||||
"BeaconBlockHeader": func() ExperimentalSSZ { return &pbethv1alpha1.BeaconBlockHeader{} },
|
||||
"Checkpoint": func() ExperimentalSSZ { return &pbethv1alpha1.Checkpoint{} },
|
||||
"Deposit": func() ExperimentalSSZ { return &pbethv1alpha1.Deposit{} },
|
||||
"DepositData": func() ExperimentalSSZ { return &pbethv1alpha1.Deposit_Data{} },
|
||||
"Eth1Data": func() ExperimentalSSZ { return &pbethv1alpha1.Eth1Data{} },
|
||||
"IndexedAttestation": func() ExperimentalSSZ { return &pbethv1alpha1.IndexedAttestation{} },
|
||||
"ProposerSlashing": func() ExperimentalSSZ { return &pbethv1alpha1.ProposerSlashing{} },
|
||||
"SignedAggregateAndProof": func() ExperimentalSSZ { return &pbethv1alpha1.SignedAggregateAttestationAndProof{} },
|
||||
"SignedBeaconBlock": func() ExperimentalSSZ { return &pbethv1alpha1.SignedBeaconBlock{} },
|
||||
"SignedBeaconBlockHeader": func() ExperimentalSSZ { return &pbethv1alpha1.SignedBeaconBlockHeader{} },
|
||||
"SignedVoluntaryExit": func() ExperimentalSSZ { return &pbethv1alpha1.SignedVoluntaryExit{} },
|
||||
"Validator": func() ExperimentalSSZ { return &pbethv1alpha1.Validator{} },
|
||||
"VoluntaryExit": func() ExperimentalSSZ { return &pbethv1alpha1.VoluntaryExit{} },
|
||||
}
|
||||
89
cmd/ssz/generate.go
Normal file
89
cmd/ssz/generate.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/sszgen"
|
||||
"github.com/prysmaticlabs/prysm/sszgen/backend"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var sourcePackage, output, typeNames string
|
||||
var generate = &cli.Command{
|
||||
Name: "generate",
|
||||
ArgsUsage: "<input package, eg github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1>",
|
||||
Aliases: []string{"gen"},
|
||||
Usage: "generate methodsets for a go struct type to support ssz ser/des",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "output",
|
||||
Value: "",
|
||||
Usage: "directory to write generated code (same as input by default)",
|
||||
Destination: &output,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "type-names",
|
||||
Value: "",
|
||||
Usage: "if specified, only generate methods for types specified in this comma-separated list",
|
||||
Destination: &typeNames,
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
sourcePackage = c.Args().Get(0)
|
||||
if sourcePackage == "" {
|
||||
cli.ShowCommandHelp(c, "generate")
|
||||
return fmt.Errorf("error: mising required <input package> argument")
|
||||
}
|
||||
var err error
|
||||
index := sszgen.NewPackageIndex()
|
||||
packageName, err := index.GetPackageName(sourcePackage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rep := sszgen.NewRepresenter(index)
|
||||
|
||||
var specs []*sszgen.DeclarationRef
|
||||
if len(typeNames) > 0 {
|
||||
for _, n := range strings.Split(strings.TrimSpace(typeNames), ",") {
|
||||
specs = append(specs, &sszgen.DeclarationRef{Package: sourcePackage, Name: n})
|
||||
}
|
||||
} else {
|
||||
specs, err = index.DeclarationRefs(sourcePackage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(specs) == 0 {
|
||||
return fmt.Errorf("Could not find any codegen targets in source package %s", sourcePackage)
|
||||
}
|
||||
|
||||
if output == "" {
|
||||
output = "methodical.ssz.go"
|
||||
}
|
||||
outFh, err := os.Create(output)
|
||||
defer outFh.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
g := backend.NewGenerator(packageName, sourcePackage)
|
||||
for _, s := range specs {
|
||||
fmt.Printf("Generating methods for %s/%s\n", s.Package, s.Name)
|
||||
typeRep, err := rep.GetDeclaration(s.Package, s.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
g.Generate(typeRep)
|
||||
}
|
||||
rbytes, err := g.Render()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = io.Copy(outFh, bytes.NewReader(rbytes))
|
||||
return err
|
||||
},
|
||||
}
|
||||
82
cmd/ssz/ir.go
Normal file
82
cmd/ssz/ir.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/sszgen"
|
||||
"github.com/prysmaticlabs/prysm/sszgen/testutil"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var ir = &cli.Command{
|
||||
Name: "ir",
|
||||
ArgsUsage: "<input package, eg github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1>",
|
||||
Aliases: []string{"gen"},
|
||||
Usage: "generate intermediate representation for a go struct type. This data structure is used by the backend code generator. Outputting it to a source file an be useful for generating test cases and debugging.",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "output",
|
||||
Value: "",
|
||||
Usage: "file path to write generated code",
|
||||
Destination: &output,
|
||||
Required: true,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "type-names",
|
||||
Value: "",
|
||||
Usage: "if specified, only generate types specified in this comma-separated list",
|
||||
Destination: &typeNames,
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
if c.NArg() > 0 {
|
||||
sourcePackage = c.Args().Get(0)
|
||||
}
|
||||
index := sszgen.NewPackageIndex()
|
||||
rep := sszgen.NewRepresenter(index)
|
||||
|
||||
var err error
|
||||
var specs []*sszgen.DeclarationRef
|
||||
if len(typeNames) > 0 {
|
||||
for _, n := range strings.Split(strings.TrimSpace(typeNames), ",") {
|
||||
specs = append(specs, &sszgen.DeclarationRef{Package: sourcePackage, Name: n})
|
||||
}
|
||||
} else {
|
||||
specs, err = index.DeclarationRefs(sourcePackage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(specs) == 0 {
|
||||
return fmt.Errorf("Could not find any codegen targets in source package %s", sourcePackage)
|
||||
}
|
||||
|
||||
outFh, err := os.Create(output)
|
||||
defer outFh.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
renderedTypes := make([]string, 0)
|
||||
for _, s := range specs {
|
||||
typeRep, err := rep.GetDeclaration(s.Package, s.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rendered, err := testutil.RenderIntermediate(typeRep)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
renderedTypes = append(renderedTypes, rendered)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = io.Copy(outFh, strings.NewReader(strings.Join(renderedTypes, "\n")))
|
||||
return err
|
||||
},
|
||||
}
|
||||
20
cmd/ssz/main.go
Normal file
20
cmd/ssz/main.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := &cli.App{
|
||||
Usage: "ssz support for prysm",
|
||||
Commands: []*cli.Command{benchmark, generate, ir},
|
||||
}
|
||||
|
||||
err := app.Run(os.Args)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"accounts.go",
|
||||
"backup.go",
|
||||
"delete.go",
|
||||
"list.go",
|
||||
"wallet_utils.go",
|
||||
@@ -14,6 +15,7 @@ go_library(
|
||||
"//cmd:go_default_library",
|
||||
"//cmd/validator/flags:go_default_library",
|
||||
"//config/features:go_default_library",
|
||||
"//io/prompt:go_default_library",
|
||||
"//runtime/tos:go_default_library",
|
||||
"//validator/accounts:go_default_library",
|
||||
"//validator/accounts/iface:go_default_library",
|
||||
@@ -29,20 +31,27 @@ go_library(
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["delete_test.go"],
|
||||
srcs = [
|
||||
"backup_test.go",
|
||||
"delete_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//cmd/validator/flags:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//crypto/bls:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//io/file:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"//time:go_default_library",
|
||||
"//validator/accounts:go_default_library",
|
||||
"//validator/accounts/iface:go_default_library",
|
||||
"//validator/accounts/wallet:go_default_library",
|
||||
"//validator/keymanager:go_default_library",
|
||||
"//validator/keymanager/derived:go_default_library",
|
||||
"//validator/keymanager/local:go_default_library",
|
||||
"//validator/testing:go_default_library",
|
||||
"@com_github_google_uuid//:go_default_library",
|
||||
"@com_github_urfave_cli_v2//:go_default_library",
|
||||
"@com_github_wealdtech_go_eth2_wallet_encryptor_keystorev4//:go_default_library",
|
||||
|
||||
@@ -111,13 +111,16 @@ var Commands = &cli.Command{
|
||||
if err := cmd.LoadFlagsFromConfig(cliCtx, cliCtx.Command.Flags); err != nil {
|
||||
return err
|
||||
}
|
||||
return tos.VerifyTosAcceptedOrPrompt(cliCtx)
|
||||
},
|
||||
Action: func(cliCtx *cli.Context) error {
|
||||
if err := tos.VerifyTosAcceptedOrPrompt(cliCtx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := features.ConfigureValidator(cliCtx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := accounts.BackupAccountsCli(cliCtx); err != nil {
|
||||
return nil
|
||||
},
|
||||
Action: func(cliCtx *cli.Context) error {
|
||||
if err := accountsBackup(cliCtx); err != nil {
|
||||
log.Fatalf("Could not backup accounts: %v", err)
|
||||
}
|
||||
return nil
|
||||
|
||||
82
cmd/validator/accounts/backup.go
Normal file
82
cmd/validator/accounts/backup.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package accounts
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/cmd"
|
||||
"github.com/prysmaticlabs/prysm/cmd/validator/flags"
|
||||
"github.com/prysmaticlabs/prysm/io/prompt"
|
||||
"github.com/prysmaticlabs/prysm/validator/accounts"
|
||||
"github.com/prysmaticlabs/prysm/validator/accounts/userprompt"
|
||||
"github.com/prysmaticlabs/prysm/validator/client"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
const backupPromptText = "Enter the directory where your backup.zip file will be written to"
|
||||
|
||||
func accountsBackup(c *cli.Context) error {
|
||||
w, km, err := walletWithKeymanager(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dialOpts := client.ConstructDialOptions(
|
||||
c.Int(cmd.GrpcMaxCallRecvMsgSizeFlag.Name),
|
||||
c.String(flags.CertFlag.Name),
|
||||
c.Uint(flags.GrpcRetriesFlag.Name),
|
||||
c.Duration(flags.GrpcRetryDelayFlag.Name),
|
||||
)
|
||||
grpcHeaders := strings.Split(c.String(flags.GrpcHeadersFlag.Name), ",")
|
||||
|
||||
opts := []accounts.Option{
|
||||
accounts.WithWallet(w),
|
||||
accounts.WithKeymanager(km),
|
||||
accounts.WithGRPCDialOpts(dialOpts),
|
||||
accounts.WithBeaconRPCProvider(c.String(flags.BeaconRPCProviderFlag.Name)),
|
||||
accounts.WithGRPCHeaders(grpcHeaders),
|
||||
}
|
||||
|
||||
// Get full set of public keys from the keymanager.
|
||||
publicKeys, err := km.FetchValidatingPublicKeys(c.Context)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not fetch validating public keys")
|
||||
}
|
||||
// Filter keys either from CLI flag or from interactive session.
|
||||
filteredPubKeys, err := accounts.FilterPublicKeysFromUserInput(
|
||||
c,
|
||||
flags.BackupPublicKeysFlag,
|
||||
publicKeys,
|
||||
userprompt.SelectAccountsBackupPromptText,
|
||||
)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not filter public keys for backup")
|
||||
}
|
||||
opts = append(opts, accounts.WithFilteredPubKeys(filteredPubKeys))
|
||||
|
||||
// Input the directory where they wish to backup their accounts.
|
||||
backupsDir, err := userprompt.InputDirectory(c, backupPromptText, flags.BackupDirFlag)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not parse keys directory")
|
||||
}
|
||||
// Ask the user for their desired password for their backed up accounts.
|
||||
backupsPassword, err := prompt.InputPassword(
|
||||
c,
|
||||
flags.BackupPasswordFile,
|
||||
"Enter a new password for your backed up accounts",
|
||||
"Confirm new password",
|
||||
true,
|
||||
prompt.ValidatePasswordInput,
|
||||
)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not determine password for backed up accounts")
|
||||
}
|
||||
|
||||
opts = append(opts, accounts.WithBackupsDir(backupsDir))
|
||||
opts = append(opts, accounts.WithBackupsPassword(backupsPassword))
|
||||
|
||||
acc, err := accounts.NewCLIManager(opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return acc.Backup(c.Context)
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/io/file"
|
||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/validator/accounts"
|
||||
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
|
||||
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
|
||||
"github.com/prysmaticlabs/prysm/validator/keymanager"
|
||||
@@ -52,7 +53,7 @@ func TestBackupAccounts_Noninteractive_Derived(t *testing.T) {
|
||||
backupPasswordFile: backupPasswordFile,
|
||||
backupDir: backupDir,
|
||||
})
|
||||
w, err := CreateWalletWithKeymanager(cliCtx.Context, &CreateWalletConfig{
|
||||
w, err := accounts.CreateWalletWithKeymanager(cliCtx.Context, &accounts.CreateWalletConfig{
|
||||
WalletCfg: &wallet.Config{
|
||||
WalletDir: walletDir,
|
||||
KeymanagerKind: keymanager.Derived,
|
||||
@@ -93,10 +94,10 @@ func TestBackupAccounts_Noninteractive_Derived(t *testing.T) {
|
||||
})
|
||||
|
||||
// Next, we attempt to backup the accounts.
|
||||
require.NoError(t, BackupAccountsCli(cliCtx))
|
||||
require.NoError(t, accountsBackup(cliCtx))
|
||||
|
||||
// We check a backup.zip file was created at the output path.
|
||||
zipFilePath := filepath.Join(backupDir, archiveFilename)
|
||||
zipFilePath := filepath.Join(backupDir, accounts.ArchiveFilename)
|
||||
assert.DeepEqual(t, true, file.FileExists(zipFilePath))
|
||||
|
||||
// We attempt to unzip the file and verify the keystores do match our accounts.
|
||||
@@ -169,7 +170,7 @@ func TestBackupAccounts_Noninteractive_Imported(t *testing.T) {
|
||||
backupPasswordFile: backupPasswordFile,
|
||||
backupDir: backupDir,
|
||||
})
|
||||
_, err = CreateWalletWithKeymanager(cliCtx.Context, &CreateWalletConfig{
|
||||
_, err = accounts.CreateWalletWithKeymanager(cliCtx.Context, &accounts.CreateWalletConfig{
|
||||
WalletCfg: &wallet.Config{
|
||||
WalletDir: walletDir,
|
||||
KeymanagerKind: keymanager.Local,
|
||||
@@ -180,13 +181,13 @@ func TestBackupAccounts_Noninteractive_Imported(t *testing.T) {
|
||||
|
||||
// We attempt to import accounts we wrote to the keys directory
|
||||
// into our newly created wallet.
|
||||
require.NoError(t, ImportAccountsCli(cliCtx))
|
||||
require.NoError(t, accounts.ImportAccountsCli(cliCtx))
|
||||
|
||||
// Next, we attempt to backup the accounts.
|
||||
require.NoError(t, BackupAccountsCli(cliCtx))
|
||||
require.NoError(t, accountsBackup(cliCtx))
|
||||
|
||||
// We check a backup.zip file was created at the output path.
|
||||
zipFilePath := filepath.Join(backupDir, archiveFilename)
|
||||
zipFilePath := filepath.Join(backupDir, accounts.ArchiveFilename)
|
||||
assert.DeepEqual(t, true, file.FileExists(zipFilePath))
|
||||
|
||||
// We attempt to unzip the file and verify the keystores do match our accounts.
|
||||
@@ -13,7 +13,7 @@ go_library(
|
||||
"//validator:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//io/file:go_default_library",
|
||||
"@com_github_urfave_cli_v2//:go_default_library",
|
||||
],
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
field_params "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/config/params"
|
||||
"github.com/prysmaticlabs/prysm/io/file"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
@@ -327,21 +327,36 @@ var (
|
||||
// FeeRecipientConfigFileFlag defines the path or URL to a file with proposer config.
|
||||
FeeRecipientConfigFileFlag = &cli.StringFlag{
|
||||
Name: "fee-recipient-config-file",
|
||||
Usage: "Set path to a JSON file containing validator mappings to ETH addresses for receiving transaction fees when proposing blocks (i.e. --fee-recipient-config-file=/path/to/proposer.json). File format found in docs",
|
||||
Usage: "DEPRECATED, please use proposer-settings-file",
|
||||
Value: "",
|
||||
}
|
||||
// FeeRecipientConfigURLFlag defines the path or URL to a file with proposer config.
|
||||
FeeRecipientConfigURLFlag = &cli.StringFlag{
|
||||
Name: "fee-recipient-config-url",
|
||||
Usage: "Set URL to a REST endpoint containing validator mappings to ETH addresses for receiving transaction fees when proposing blocks (i.e. --fee-recipient-config-url=https://example.com/api/getConfig). File format found in docs",
|
||||
Usage: "DEPRECATED, please use proposer-settings-url",
|
||||
Value: "",
|
||||
}
|
||||
|
||||
// ProposerSettingsFlag defines the path or URL to a file with proposer config.
|
||||
ProposerSettingsFlag = &cli.StringFlag{
|
||||
Name: "proposer-settings-file",
|
||||
Usage: "Set path to a YAML or JSON file containing validator settings used when proposing blocks such as (fee recipient and gas limit) (i.e. --proposer-settings-file=/path/to/proposer.json). File format found in docs",
|
||||
Value: "",
|
||||
}
|
||||
// ProposerSettingsURLFlag defines the path or URL to a file with proposer config.
|
||||
ProposerSettingsURLFlag = &cli.StringFlag{
|
||||
Name: "proposer-settings-url",
|
||||
Usage: "Set URL to a REST endpoint containing validator settings used when proposing blocks such as (fee recipient) (i.e. --proposer-settings-url=https://example.com/api/getConfig). File format found in docs",
|
||||
Value: "",
|
||||
}
|
||||
|
||||
// SuggestedFeeRecipientFlag defines the address of the fee recipient.
|
||||
SuggestedFeeRecipientFlag = &cli.StringFlag{
|
||||
Name: "suggested-fee-recipient",
|
||||
Usage: "Sets ALL validators' mapping to a suggested an eth address to receive gas fees when proposing a block. Overrides the --fee-recipient-config-file flag if set",
|
||||
Value: field_params.EthBurnAddressHex,
|
||||
Name: "suggested-fee-recipient",
|
||||
Usage: "Sets ALL validators' mapping to a suggested an eth address to receive gas fees when proposing a block." +
|
||||
" note that this is only a suggestion when integrating with a Builder API, which may choose to specify a different fee recipient as payment for the blocks it builds." +
|
||||
" For additional setting overrides use the --" + ProposerSettingsFlag.Name + " or --" + ProposerSettingsURLFlag.Name + " Flags. ",
|
||||
Value: params.BeaconConfig().EthBurnAddressHex,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -78,6 +78,8 @@ var appFlags = []cli.Flag{
|
||||
flags.FeeRecipientConfigFileFlag,
|
||||
flags.FeeRecipientConfigURLFlag,
|
||||
flags.SuggestedFeeRecipientFlag,
|
||||
flags.ProposerSettingsURLFlag,
|
||||
flags.ProposerSettingsFlag,
|
||||
////////////////////
|
||||
cmd.DisableMonitoringFlag,
|
||||
cmd.MonitoringHostFlag,
|
||||
|
||||
@@ -111,6 +111,8 @@ var appHelpFlagGroups = []flagGroup{
|
||||
flags.Web3SignerPublicValidatorKeysFlag,
|
||||
flags.FeeRecipientConfigFileFlag,
|
||||
flags.FeeRecipientConfigURLFlag,
|
||||
flags.ProposerSettingsFlag,
|
||||
flags.ProposerSettingsURLFlag,
|
||||
flags.SuggestedFeeRecipientFlag,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -122,6 +122,12 @@ func configureTestnet(ctx *cli.Context) error {
|
||||
if err := params.SetActive(params.RopstenConfig().Copy()); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ctx.Set(enableVecHTR.Names()[0], "true"); err != nil {
|
||||
log.WithError(err).Debug("error enabling vectorized HTR flag")
|
||||
}
|
||||
if err := ctx.Set(enableForkChoiceDoublyLinkedTree.Names()[0], "true"); err != nil {
|
||||
log.WithError(err).Debug("error enabling doubly linked tree forkchoice flag")
|
||||
}
|
||||
params.UseRopstenNetworkConfig()
|
||||
} else {
|
||||
log.Warn("Running on Ethereum Consensus Mainnet")
|
||||
|
||||
@@ -5,23 +5,22 @@ package field_params
|
||||
|
||||
const (
|
||||
Preset = "mainnet"
|
||||
BlockRootsLength = 8192 // SLOTS_PER_HISTORICAL_ROOT
|
||||
StateRootsLength = 8192 // SLOTS_PER_HISTORICAL_ROOT
|
||||
RandaoMixesLength = 65536 // EPOCHS_PER_HISTORICAL_VECTOR
|
||||
HistoricalRootsLength = 16777216 // HISTORICAL_ROOTS_LIMIT
|
||||
ValidatorRegistryLimit = 1099511627776 // VALIDATOR_REGISTRY_LIMIT
|
||||
Eth1DataVotesLength = 2048 // SLOTS_PER_ETH1_VOTING_PERIOD
|
||||
PreviousEpochAttestationsLength = 4096 // MAX_ATTESTATIONS * SLOTS_PER_EPOCH
|
||||
CurrentEpochAttestationsLength = 4096 // MAX_ATTESTATIONS * SLOTS_PER_EPOCH
|
||||
SlashingsLength = 8192 // EPOCHS_PER_SLASHINGS_VECTOR
|
||||
SyncCommitteeLength = 512 // SYNC_COMMITTEE_SIZE
|
||||
RootLength = 32 // RootLength defines the byte length of a Merkle root.
|
||||
BLSSignatureLength = 96 // BLSSignatureLength defines the byte length of a BLSSignature.
|
||||
BLSPubkeyLength = 48 // BLSPubkeyLength defines the byte length of a BLSSignature.
|
||||
MaxTxsPerPayloadLength = 1048576 // MaxTxsPerPayloadLength defines the maximum number of transactions that can be included in a payload.
|
||||
MaxBytesPerTxLength = 1073741824 // MaxBytesPerTxLength defines the maximum number of bytes that can be included in a transaction.
|
||||
FeeRecipientLength = 20 // FeeRecipientLength defines the byte length of a fee recipient.
|
||||
LogsBloomLength = 256 // LogsBloomLength defines the byte length of a logs bloom.
|
||||
VersionLength = 4 // VersionLength defines the byte length of a fork version number.
|
||||
EthBurnAddressHex = "0x0000000000000000000000000000000000000000" // EthBurnAddressHex defines the hex encoded address of the eth1.0 burn contract.
|
||||
BlockRootsLength = 8192 // SLOTS_PER_HISTORICAL_ROOT
|
||||
StateRootsLength = 8192 // SLOTS_PER_HISTORICAL_ROOT
|
||||
RandaoMixesLength = 65536 // EPOCHS_PER_HISTORICAL_VECTOR
|
||||
HistoricalRootsLength = 16777216 // HISTORICAL_ROOTS_LIMIT
|
||||
ValidatorRegistryLimit = 1099511627776 // VALIDATOR_REGISTRY_LIMIT
|
||||
Eth1DataVotesLength = 2048 // SLOTS_PER_ETH1_VOTING_PERIOD
|
||||
PreviousEpochAttestationsLength = 4096 // MAX_ATTESTATIONS * SLOTS_PER_EPOCH
|
||||
CurrentEpochAttestationsLength = 4096 // MAX_ATTESTATIONS * SLOTS_PER_EPOCH
|
||||
SlashingsLength = 8192 // EPOCHS_PER_SLASHINGS_VECTOR
|
||||
SyncCommitteeLength = 512 // SYNC_COMMITTEE_SIZE
|
||||
RootLength = 32 // RootLength defines the byte length of a Merkle root.
|
||||
BLSSignatureLength = 96 // BLSSignatureLength defines the byte length of a BLSSignature.
|
||||
BLSPubkeyLength = 48 // BLSPubkeyLength defines the byte length of a BLSSignature.
|
||||
MaxTxsPerPayloadLength = 1048576 // MaxTxsPerPayloadLength defines the maximum number of transactions that can be included in a payload.
|
||||
MaxBytesPerTxLength = 1073741824 // MaxBytesPerTxLength defines the maximum number of bytes that can be included in a transaction.
|
||||
FeeRecipientLength = 20 // FeeRecipientLength defines the byte length of a fee recipient.
|
||||
LogsBloomLength = 256 // LogsBloomLength defines the byte length of a logs bloom.
|
||||
VersionLength = 4 // VersionLength defines the byte length of a fork version number.
|
||||
)
|
||||
|
||||
@@ -5,23 +5,22 @@ package field_params
|
||||
|
||||
const (
|
||||
Preset = "minimal"
|
||||
BlockRootsLength = 64 // SLOTS_PER_HISTORICAL_ROOT
|
||||
StateRootsLength = 64 // SLOTS_PER_HISTORICAL_ROOT
|
||||
RandaoMixesLength = 64 // EPOCHS_PER_HISTORICAL_VECTOR
|
||||
HistoricalRootsLength = 16777216 // HISTORICAL_ROOTS_LIMIT
|
||||
ValidatorRegistryLimit = 1099511627776 // VALIDATOR_REGISTRY_LIMIT
|
||||
Eth1DataVotesLength = 32 // SLOTS_PER_ETH1_VOTING_PERIOD
|
||||
PreviousEpochAttestationsLength = 1024 // MAX_ATTESTATIONS * SLOTS_PER_EPOCH
|
||||
CurrentEpochAttestationsLength = 1024 // MAX_ATTESTATIONS * SLOTS_PER_EPOCH
|
||||
SlashingsLength = 64 // EPOCHS_PER_SLASHINGS_VECTOR
|
||||
SyncCommitteeLength = 32 // SYNC_COMMITTEE_SIZE
|
||||
RootLength = 32 // RootLength defines the byte length of a Merkle root.
|
||||
BLSSignatureLength = 96 // BLSSignatureLength defines the byte length of a BLSSignature.
|
||||
BLSPubkeyLength = 48 // BLSPubkeyLength defines the byte length of a BLSSignature.
|
||||
MaxTxsPerPayloadLength = 1048576 // MaxTxsPerPayloadLength defines the maximum number of transactions that can be included in a payload.
|
||||
MaxBytesPerTxLength = 1073741824 // MaxBytesPerTxLength defines the maximum number of bytes that can be included in a transaction.
|
||||
FeeRecipientLength = 20 // FeeRecipientLength defines the byte length of a fee recipient.
|
||||
LogsBloomLength = 256 // LogsBloomLength defines the byte length of a logs bloom.
|
||||
VersionLength = 4 // VersionLength defines the byte length of a fork version number.
|
||||
EthBurnAddressHex = "0x0000000000000000000000000000000000000000" // EthBurnAddressHex defines the hex encoded address of the eth1.0 burn contract.
|
||||
BlockRootsLength = 64 // SLOTS_PER_HISTORICAL_ROOT
|
||||
StateRootsLength = 64 // SLOTS_PER_HISTORICAL_ROOT
|
||||
RandaoMixesLength = 64 // EPOCHS_PER_HISTORICAL_VECTOR
|
||||
HistoricalRootsLength = 16777216 // HISTORICAL_ROOTS_LIMIT
|
||||
ValidatorRegistryLimit = 1099511627776 // VALIDATOR_REGISTRY_LIMIT
|
||||
Eth1DataVotesLength = 32 // SLOTS_PER_ETH1_VOTING_PERIOD
|
||||
PreviousEpochAttestationsLength = 1024 // MAX_ATTESTATIONS * SLOTS_PER_EPOCH
|
||||
CurrentEpochAttestationsLength = 1024 // MAX_ATTESTATIONS * SLOTS_PER_EPOCH
|
||||
SlashingsLength = 64 // EPOCHS_PER_SLASHINGS_VECTOR
|
||||
SyncCommitteeLength = 32 // SYNC_COMMITTEE_SIZE
|
||||
RootLength = 32 // RootLength defines the byte length of a Merkle root.
|
||||
BLSSignatureLength = 96 // BLSSignatureLength defines the byte length of a BLSSignature.
|
||||
BLSPubkeyLength = 48 // BLSPubkeyLength defines the byte length of a BLSSignature.
|
||||
MaxTxsPerPayloadLength = 1048576 // MaxTxsPerPayloadLength defines the maximum number of transactions that can be included in a payload.
|
||||
MaxBytesPerTxLength = 1073741824 // MaxBytesPerTxLength defines the maximum number of bytes that can be included in a transaction.
|
||||
FeeRecipientLength = 20 // FeeRecipientLength defines the byte length of a fee recipient.
|
||||
LogsBloomLength = 256 // LogsBloomLength defines the byte length of a logs bloom.
|
||||
VersionLength = 4 // VersionLength defines the byte length of a fork version number.
|
||||
)
|
||||
|
||||
@@ -192,6 +192,8 @@ type BeaconChainConfig struct {
|
||||
TerminalBlockHashActivationEpoch types.Epoch `yaml:"TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH" spec:"true"` // TerminalBlockHashActivationEpoch of beacon chain.
|
||||
TerminalTotalDifficulty string `yaml:"TERMINAL_TOTAL_DIFFICULTY" spec:"true"` // TerminalTotalDifficulty is part of the experimental Bellatrix spec. This value is type is currently TBD.
|
||||
DefaultFeeRecipient common.Address // DefaultFeeRecipient where the transaction fee goes to.
|
||||
EthBurnAddressHex string // EthBurnAddressHex is the constant eth address written in hex format to burn fees in that network. the default is 0x0
|
||||
DefaultBuilderGasLimit uint64 // DefaultBuilderGasLimit is the default used to set the gaslimit for the Builder APIs, typically at around 30M wei.
|
||||
}
|
||||
|
||||
// InitializeForkSchedule initializes the schedules forks baked into the config.
|
||||
|
||||
@@ -244,6 +244,8 @@ var mainnetBeaconConfig = &BeaconChainConfig{
|
||||
TerminalBlockHashActivationEpoch: 18446744073709551615,
|
||||
TerminalBlockHash: [32]byte{},
|
||||
TerminalTotalDifficulty: "115792089237316195423570985008687907853269984665640564039457584007913129638912",
|
||||
EthBurnAddressHex: "0x0000000000000000000000000000000000000000",
|
||||
DefaultBuilderGasLimit: uint64(30000000),
|
||||
}
|
||||
|
||||
// MainnetTestConfig provides a version of the mainnet config that has a different name
|
||||
|
||||
@@ -2,7 +2,7 @@ load("@prysm//tools/go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["fee-recipient-config.go"],
|
||||
srcs = ["proposer-settings.go"],
|
||||
importpath = "github.com/prysmaticlabs/prysm/config/validator/service",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
package validator_service_config
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
field_params "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||
)
|
||||
|
||||
// FeeRecipientFileConfig is the struct representation of the JSON config file set in the validator through the CLI.
|
||||
// ProposeConfig is the map of validator address to fee recipient options all in hex format.
|
||||
// DefaultConfig is the default fee recipient address for all validators unless otherwise specified in the propose config.required.
|
||||
type FeeRecipientFileConfig struct {
|
||||
ProposeConfig map[string]*FeeRecipientFileOptions `json:"proposer_config"`
|
||||
DefaultConfig *FeeRecipientFileOptions `json:"default_config"`
|
||||
}
|
||||
|
||||
// FeeRecipientFileOptions is the struct representation of the JSON config file set in the validator through the CLI.
|
||||
// FeeRecipient is set to an eth address in hex string format with 0x prefix.
|
||||
type FeeRecipientFileOptions struct {
|
||||
FeeRecipient string `json:"fee_recipient"`
|
||||
}
|
||||
|
||||
// FeeRecipientConfig is a Prysm internal representation of the fee recipient config on the validator client.
|
||||
// FeeRecipientFileConfig maps to FeeRecipientConfig on import through the CLI.
|
||||
type FeeRecipientConfig struct {
|
||||
ProposeConfig map[[field_params.BLSPubkeyLength]byte]*FeeRecipientOptions
|
||||
DefaultConfig *FeeRecipientOptions
|
||||
}
|
||||
|
||||
// FeeRecipientOptions is a Prysm internal representation of the FeeRecipientFileOptions on the validator client in bytes format instead of hex.
|
||||
type FeeRecipientOptions struct {
|
||||
FeeRecipient common.Address
|
||||
}
|
||||
35
config/validator/service/proposer-settings.go
Normal file
35
config/validator/service/proposer-settings.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package validator_service_config
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
field_params "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||
)
|
||||
|
||||
// ProposerSettingsPayload is the struct representation of the JSON or YAML payload set in the validator through the CLI.
|
||||
// ProposeConfig is the map of validator address to fee recipient options all in hex format.
|
||||
// DefaultConfig is the default fee recipient address for all validators unless otherwise specified in the propose config.required.
|
||||
type ProposerSettingsPayload struct {
|
||||
ProposeConfig map[string]*ProposerOptionPayload `json:"proposer_config" yaml:"proposer_config"`
|
||||
DefaultConfig *ProposerOptionPayload `json:"default_config" yaml:"default_config"`
|
||||
}
|
||||
|
||||
// ProposerOptionPayload is the struct representation of the JSON config file set in the validator through the CLI.
|
||||
// FeeRecipient is set to an eth address in hex string format with 0x prefix.
|
||||
// GasLimit is a number set to help the network decide on the maximum gas in each block.
|
||||
type ProposerOptionPayload struct {
|
||||
FeeRecipient string `json:"fee_recipient" yaml:"fee_recipient"`
|
||||
GasLimit uint64 `json:"gas_limit,omitempty" yaml:"gas_limit,omitempty"`
|
||||
}
|
||||
|
||||
// ProposerSettings is a Prysm internal representation of the fee recipient config on the validator client.
|
||||
// ProposerSettingsPayload maps to ProposerSettings on import through the CLI.
|
||||
type ProposerSettings struct {
|
||||
ProposeConfig map[[field_params.BLSPubkeyLength]byte]*ProposerOption
|
||||
DefaultConfig *ProposerOption
|
||||
}
|
||||
|
||||
// ProposerOption is a Prysm internal representation of the ProposerOptionPayload on the validator client in bytes format instead of hex.
|
||||
type ProposerOption struct {
|
||||
FeeRecipient common.Address
|
||||
GasLimit uint64
|
||||
}
|
||||
46
consensus-types/blocks/BUILD.bazel
Normal file
46
consensus-types/blocks/BUILD.bazel
Normal file
@@ -0,0 +1,46 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"factory.go",
|
||||
"getters.go",
|
||||
"proto.go",
|
||||
"types.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/consensus-types/blocks",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//proto/prysm/v1alpha1/validator-client:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"@com_github_ferranbt_fastssz//:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@org_golang_google_protobuf//proto:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"factory_test.go",
|
||||
"getters_test.go",
|
||||
"proto_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//proto/prysm/v1alpha1/validator-client:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"//testing/util:go_default_library",
|
||||
"@com_github_ferranbt_fastssz//:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
||||
],
|
||||
)
|
||||
130
consensus-types/blocks/factory.go
Normal file
130
consensus-types/blocks/factory.go
Normal file
@@ -0,0 +1,130 @@
|
||||
package blocks
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrUnsupportedSignedBeaconBlock is returned when the struct type is not a supported signed
|
||||
// beacon block type.
|
||||
ErrUnsupportedSignedBeaconBlock = errors.New("unsupported signed beacon block")
|
||||
// errUnsupportedBeaconBlock is returned when the struct type is not a supported beacon block
|
||||
// type.
|
||||
errUnsupportedBeaconBlock = errors.New("unsupported beacon block")
|
||||
// errUnsupportedBeaconBlockBody is returned when the struct type is not a supported beacon block body
|
||||
// type.
|
||||
errUnsupportedBeaconBlockBody = errors.New("unsupported beacon block body")
|
||||
// ErrNilObjectWrapped is returned in a constructor when the underlying object is nil.
|
||||
ErrNilObjectWrapped = errors.New("attempted to wrap nil object")
|
||||
errNilSignedBeaconBlock = errors.New("signed beacon block can't be nil")
|
||||
errNilBeaconBlock = errors.New("beacon block can't be nil")
|
||||
errNilBeaconBlockBody = errors.New("beacon block body can't be nil")
|
||||
)
|
||||
|
||||
// NewSignedBeaconBlock creates a signed beacon block from a protobuf signed beacon block.
|
||||
func NewSignedBeaconBlock(i interface{}) (*SignedBeaconBlock, error) {
|
||||
switch b := i.(type) {
|
||||
case *eth.GenericSignedBeaconBlock_Phase0:
|
||||
return initSignedBlockFromProtoPhase0(b.Phase0)
|
||||
case *eth.SignedBeaconBlock:
|
||||
return initSignedBlockFromProtoPhase0(b)
|
||||
case *eth.GenericSignedBeaconBlock_Altair:
|
||||
return initSignedBlockFromProtoAltair(b.Altair)
|
||||
case *eth.SignedBeaconBlockAltair:
|
||||
return initSignedBlockFromProtoAltair(b)
|
||||
case *eth.GenericSignedBeaconBlock_Bellatrix:
|
||||
return initSignedBlockFromProtoBellatrix(b.Bellatrix)
|
||||
case *eth.SignedBeaconBlockBellatrix:
|
||||
return initSignedBlockFromProtoBellatrix(b)
|
||||
case *eth.GenericSignedBeaconBlock_BlindedBellatrix:
|
||||
return initBlindedSignedBlockFromProtoBellatrix(b.BlindedBellatrix)
|
||||
case *eth.SignedBlindedBeaconBlockBellatrix:
|
||||
return initBlindedSignedBlockFromProtoBellatrix(b)
|
||||
case nil:
|
||||
return nil, ErrNilObjectWrapped
|
||||
default:
|
||||
return nil, errors.Wrapf(ErrUnsupportedSignedBeaconBlock, "unable to create block from type %T", i)
|
||||
}
|
||||
}
|
||||
|
||||
// NewBeaconBlock creates a beacon block from a protobuf beacon block.
|
||||
func NewBeaconBlock(i interface{}) (*BeaconBlock, error) {
|
||||
switch b := i.(type) {
|
||||
case *eth.GenericBeaconBlock_Phase0:
|
||||
return initBlockFromProtoPhase0(b.Phase0)
|
||||
case *eth.BeaconBlock:
|
||||
return initBlockFromProtoPhase0(b)
|
||||
case *eth.GenericBeaconBlock_Altair:
|
||||
return initBlockFromProtoAltair(b.Altair)
|
||||
case *eth.BeaconBlockAltair:
|
||||
return initBlockFromProtoAltair(b)
|
||||
case *eth.GenericBeaconBlock_Bellatrix:
|
||||
return initBlockFromProtoBellatrix(b.Bellatrix)
|
||||
case *eth.BeaconBlockBellatrix:
|
||||
return initBlockFromProtoBellatrix(b)
|
||||
case *eth.GenericBeaconBlock_BlindedBellatrix:
|
||||
return initBlindedBlockFromProtoBellatrix(b.BlindedBellatrix)
|
||||
case *eth.BlindedBeaconBlockBellatrix:
|
||||
return initBlindedBlockFromProtoBellatrix(b)
|
||||
case nil:
|
||||
return nil, ErrNilObjectWrapped
|
||||
default:
|
||||
return nil, errors.Wrapf(errUnsupportedBeaconBlock, "unable to create block from type %T", i)
|
||||
}
|
||||
}
|
||||
|
||||
// NewBeaconBlockBody creates a beacon block body from a protobuf beacon block body.
|
||||
func NewBeaconBlockBody(i interface{}) (*BeaconBlockBody, error) {
|
||||
switch b := i.(type) {
|
||||
case *eth.BeaconBlockBody:
|
||||
return initBlockBodyFromProtoPhase0(b)
|
||||
case *eth.BeaconBlockBodyAltair:
|
||||
return initBlockBodyFromProtoAltair(b)
|
||||
case *eth.BeaconBlockBodyBellatrix:
|
||||
return initBlockBodyFromProtoBellatrix(b)
|
||||
case *eth.BlindedBeaconBlockBodyBellatrix:
|
||||
return initBlindedBlockBodyFromProtoBellatrix(b)
|
||||
case nil:
|
||||
return nil, ErrNilObjectWrapped
|
||||
default:
|
||||
return nil, errors.Wrapf(errUnsupportedBeaconBlockBody, "unable to create block body from type %T", i)
|
||||
}
|
||||
}
|
||||
|
||||
// BuildSignedBeaconBlock assembles a block.SignedBeaconBlock interface compatible struct from a
|
||||
// given beacon block and the appropriate signature. This method may be used to easily create a
|
||||
// signed beacon block.
|
||||
func BuildSignedBeaconBlock(blk interfaces.BeaconBlock, signature []byte) (*SignedBeaconBlock, error) {
|
||||
pb := blk.Proto()
|
||||
switch blk.Version() {
|
||||
case version.Phase0:
|
||||
pb, ok := pb.(*eth.BeaconBlock)
|
||||
if !ok {
|
||||
return nil, errIncorrectBlockVersion
|
||||
}
|
||||
return NewSignedBeaconBlock(ð.SignedBeaconBlock{Block: pb, Signature: signature})
|
||||
case version.Altair:
|
||||
pb, ok := pb.(*eth.BeaconBlockAltair)
|
||||
if !ok {
|
||||
return nil, errIncorrectBlockVersion
|
||||
}
|
||||
return NewSignedBeaconBlock(ð.SignedBeaconBlockAltair{Block: pb, Signature: signature})
|
||||
case version.Bellatrix:
|
||||
pb, ok := pb.(*eth.BeaconBlockBellatrix)
|
||||
if !ok {
|
||||
return nil, errIncorrectBlockVersion
|
||||
}
|
||||
return NewSignedBeaconBlock(ð.SignedBeaconBlockBellatrix{Block: pb, Signature: signature})
|
||||
case version.BellatrixBlind:
|
||||
pb, ok := pb.(*eth.BlindedBeaconBlockBellatrix)
|
||||
if !ok {
|
||||
return nil, errIncorrectBlockVersion
|
||||
}
|
||||
return NewSignedBeaconBlock(ð.SignedBlindedBeaconBlockBellatrix{Block: pb, Signature: signature})
|
||||
default:
|
||||
return nil, errUnsupportedBeaconBlock
|
||||
}
|
||||
}
|
||||
184
consensus-types/blocks/factory_test.go
Normal file
184
consensus-types/blocks/factory_test.go
Normal file
@@ -0,0 +1,184 @@
|
||||
package blocks
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/testing/require"
|
||||
)
|
||||
|
||||
func Test_NewSignedBeaconBlock(t *testing.T) {
|
||||
t.Run("GenericSignedBeaconBlock_Phase0", func(t *testing.T) {
|
||||
pb := ð.GenericSignedBeaconBlock_Phase0{
|
||||
Phase0: ð.SignedBeaconBlock{
|
||||
Block: ð.BeaconBlock{
|
||||
Body: ð.BeaconBlockBody{}}}}
|
||||
b, err := NewSignedBeaconBlock(pb)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version.Phase0, b.version)
|
||||
})
|
||||
t.Run("SignedBeaconBlock", func(t *testing.T) {
|
||||
pb := ð.SignedBeaconBlock{
|
||||
Block: ð.BeaconBlock{
|
||||
Body: ð.BeaconBlockBody{}}}
|
||||
b, err := NewSignedBeaconBlock(pb)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version.Phase0, b.version)
|
||||
})
|
||||
t.Run("GenericSignedBeaconBlock_Altair", func(t *testing.T) {
|
||||
pb := ð.GenericSignedBeaconBlock_Altair{
|
||||
Altair: ð.SignedBeaconBlockAltair{
|
||||
Block: ð.BeaconBlockAltair{
|
||||
Body: ð.BeaconBlockBodyAltair{}}}}
|
||||
b, err := NewSignedBeaconBlock(pb)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version.Altair, b.version)
|
||||
})
|
||||
t.Run("SignedBeaconBlockAltair", func(t *testing.T) {
|
||||
pb := ð.SignedBeaconBlockAltair{
|
||||
Block: ð.BeaconBlockAltair{
|
||||
Body: ð.BeaconBlockBodyAltair{}}}
|
||||
b, err := NewSignedBeaconBlock(pb)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version.Altair, b.version)
|
||||
})
|
||||
t.Run("GenericSignedBeaconBlock_Bellatrix", func(t *testing.T) {
|
||||
pb := ð.GenericSignedBeaconBlock_Bellatrix{
|
||||
Bellatrix: ð.SignedBeaconBlockBellatrix{
|
||||
Block: ð.BeaconBlockBellatrix{
|
||||
Body: ð.BeaconBlockBodyBellatrix{}}}}
|
||||
b, err := NewSignedBeaconBlock(pb)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version.Bellatrix, b.version)
|
||||
})
|
||||
t.Run("SignedBeaconBlockBellatrix", func(t *testing.T) {
|
||||
pb := ð.SignedBeaconBlockBellatrix{
|
||||
Block: ð.BeaconBlockBellatrix{
|
||||
Body: ð.BeaconBlockBodyBellatrix{}}}
|
||||
b, err := NewSignedBeaconBlock(pb)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version.Bellatrix, b.version)
|
||||
})
|
||||
t.Run("GenericSignedBeaconBlock_BlindedBellatrix", func(t *testing.T) {
|
||||
pb := ð.GenericSignedBeaconBlock_BlindedBellatrix{
|
||||
BlindedBellatrix: ð.SignedBlindedBeaconBlockBellatrix{
|
||||
Block: ð.BlindedBeaconBlockBellatrix{
|
||||
Body: ð.BlindedBeaconBlockBodyBellatrix{}}}}
|
||||
b, err := NewSignedBeaconBlock(pb)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version.BellatrixBlind, b.version)
|
||||
})
|
||||
t.Run("SignedBlindedBeaconBlockBellatrix", func(t *testing.T) {
|
||||
pb := ð.SignedBlindedBeaconBlockBellatrix{
|
||||
Block: ð.BlindedBeaconBlockBellatrix{
|
||||
Body: ð.BlindedBeaconBlockBodyBellatrix{}}}
|
||||
b, err := NewSignedBeaconBlock(pb)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version.BellatrixBlind, b.version)
|
||||
})
|
||||
t.Run("nil", func(t *testing.T) {
|
||||
_, err := NewSignedBeaconBlock(nil)
|
||||
assert.ErrorContains(t, "attempted to wrap nil object", err)
|
||||
})
|
||||
t.Run("unsupported type", func(t *testing.T) {
|
||||
_, err := NewSignedBeaconBlock(&bytes.Reader{})
|
||||
assert.ErrorContains(t, "unable to create block from type *bytes.Reader", err)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_NewBeaconBlock(t *testing.T) {
|
||||
t.Run("GenericBeaconBlock_Phase0", func(t *testing.T) {
|
||||
pb := ð.GenericBeaconBlock_Phase0{Phase0: ð.BeaconBlock{Body: ð.BeaconBlockBody{}}}
|
||||
b, err := NewBeaconBlock(pb)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version.Phase0, b.version)
|
||||
})
|
||||
t.Run("BeaconBlock", func(t *testing.T) {
|
||||
pb := ð.BeaconBlock{Body: ð.BeaconBlockBody{}}
|
||||
b, err := NewBeaconBlock(pb)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version.Phase0, b.version)
|
||||
})
|
||||
t.Run("GenericBeaconBlock_Altair", func(t *testing.T) {
|
||||
pb := ð.GenericBeaconBlock_Altair{Altair: ð.BeaconBlockAltair{Body: ð.BeaconBlockBodyAltair{}}}
|
||||
b, err := NewBeaconBlock(pb)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version.Altair, b.version)
|
||||
})
|
||||
t.Run("BeaconBlockAltair", func(t *testing.T) {
|
||||
pb := ð.BeaconBlockAltair{Body: ð.BeaconBlockBodyAltair{}}
|
||||
b, err := NewBeaconBlock(pb)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version.Altair, b.version)
|
||||
})
|
||||
t.Run("GenericBeaconBlock_Bellatrix", func(t *testing.T) {
|
||||
pb := ð.GenericBeaconBlock_Bellatrix{Bellatrix: ð.BeaconBlockBellatrix{Body: ð.BeaconBlockBodyBellatrix{}}}
|
||||
b, err := NewBeaconBlock(pb)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version.Bellatrix, b.version)
|
||||
})
|
||||
t.Run("BeaconBlockBellatrix", func(t *testing.T) {
|
||||
pb := ð.BeaconBlockBellatrix{Body: ð.BeaconBlockBodyBellatrix{}}
|
||||
b, err := NewBeaconBlock(pb)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version.Bellatrix, b.version)
|
||||
})
|
||||
t.Run("GenericBeaconBlock_BlindedBellatrix", func(t *testing.T) {
|
||||
pb := ð.GenericBeaconBlock_BlindedBellatrix{BlindedBellatrix: ð.BlindedBeaconBlockBellatrix{Body: ð.BlindedBeaconBlockBodyBellatrix{}}}
|
||||
b, err := NewBeaconBlock(pb)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version.BellatrixBlind, b.version)
|
||||
})
|
||||
t.Run("BlindedBeaconBlockBellatrix", func(t *testing.T) {
|
||||
pb := ð.BlindedBeaconBlockBellatrix{Body: ð.BlindedBeaconBlockBodyBellatrix{}}
|
||||
b, err := NewBeaconBlock(pb)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version.BellatrixBlind, b.version)
|
||||
})
|
||||
t.Run("nil", func(t *testing.T) {
|
||||
_, err := NewBeaconBlock(nil)
|
||||
assert.ErrorContains(t, "attempted to wrap nil object", err)
|
||||
})
|
||||
t.Run("unsupported type", func(t *testing.T) {
|
||||
_, err := NewBeaconBlock(&bytes.Reader{})
|
||||
assert.ErrorContains(t, "unable to create block from type *bytes.Reader", err)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_NewBeaconBlockBody(t *testing.T) {
|
||||
t.Run("BeaconBlockBody", func(t *testing.T) {
|
||||
pb := ð.BeaconBlockBody{}
|
||||
b, err := NewBeaconBlockBody(pb)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version.Phase0, b.version)
|
||||
})
|
||||
t.Run("BeaconBlockBodyAltair", func(t *testing.T) {
|
||||
pb := ð.BeaconBlockBodyAltair{}
|
||||
b, err := NewBeaconBlockBody(pb)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version.Altair, b.version)
|
||||
})
|
||||
t.Run("BeaconBlockBodyBellatrix", func(t *testing.T) {
|
||||
pb := ð.BeaconBlockBodyBellatrix{}
|
||||
b, err := NewBeaconBlockBody(pb)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version.Bellatrix, b.version)
|
||||
})
|
||||
t.Run("BlindedBeaconBlockBodyBellatrix", func(t *testing.T) {
|
||||
pb := ð.BlindedBeaconBlockBodyBellatrix{}
|
||||
b, err := NewBeaconBlockBody(pb)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version.BellatrixBlind, b.version)
|
||||
})
|
||||
t.Run("nil", func(t *testing.T) {
|
||||
_, err := NewBeaconBlockBody(nil)
|
||||
assert.ErrorContains(t, "attempted to wrap nil object", err)
|
||||
})
|
||||
t.Run("unsupported type", func(t *testing.T) {
|
||||
_, err := NewBeaconBlockBody(&bytes.Reader{})
|
||||
assert.ErrorContains(t, "unable to create block body from type *bytes.Reader", err)
|
||||
})
|
||||
}
|
||||
592
consensus-types/blocks/getters.go
Normal file
592
consensus-types/blocks/getters.go
Normal file
@@ -0,0 +1,592 @@
|
||||
package blocks
|
||||
|
||||
import (
|
||||
ssz "github.com/ferranbt/fastssz"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
||||
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
validatorpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/validator-client"
|
||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||
)
|
||||
|
||||
// BeaconBlockIsNil checks if any composite field of input signed beacon block is nil.
|
||||
// Access to these nil fields will result in run time panic,
|
||||
// it is recommended to run these checks as first line of defense.
|
||||
func BeaconBlockIsNil(b interfaces.SignedBeaconBlock) error {
|
||||
if b == nil || b.IsNil() {
|
||||
return errNilSignedBeaconBlock
|
||||
}
|
||||
if b.Block().IsNil() {
|
||||
return errNilBeaconBlock
|
||||
}
|
||||
if b.Block().Body().IsNil() {
|
||||
return errNilBeaconBlockBody
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Signature returns the respective block signature.
|
||||
func (b *SignedBeaconBlock) Signature() []byte {
|
||||
return b.signature
|
||||
}
|
||||
|
||||
// Block returns the underlying beacon block object.
|
||||
func (b *SignedBeaconBlock) Block() *BeaconBlock {
|
||||
return b.block
|
||||
}
|
||||
|
||||
// IsNil checks if the underlying beacon block is nil.
|
||||
func (b *SignedBeaconBlock) IsNil() bool {
|
||||
return b == nil || b.block.IsNil()
|
||||
}
|
||||
|
||||
// Copy performs a deep copy of the signed beacon block object.
|
||||
func (b *SignedBeaconBlock) Copy() (*SignedBeaconBlock, error) {
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
cp := eth.CopySignedBeaconBlock(pb.(*eth.SignedBeaconBlock))
|
||||
return initSignedBlockFromProtoPhase0(cp)
|
||||
case version.Altair:
|
||||
cp := eth.CopySignedBeaconBlockAltair(pb.(*eth.SignedBeaconBlockAltair))
|
||||
return initSignedBlockFromProtoAltair(cp)
|
||||
case version.Bellatrix:
|
||||
cp := eth.CopySignedBeaconBlockBellatrix(pb.(*eth.SignedBeaconBlockBellatrix))
|
||||
return initSignedBlockFromProtoBellatrix(cp)
|
||||
case version.BellatrixBlind:
|
||||
cp := eth.CopySignedBlindedBeaconBlockBellatrix(pb.(*eth.SignedBlindedBeaconBlockBellatrix))
|
||||
return initBlindedSignedBlockFromProtoBellatrix(cp)
|
||||
default:
|
||||
return nil, errIncorrectBlockVersion
|
||||
}
|
||||
}
|
||||
|
||||
// PbGenericBlock returns a generic signed beacon block.
|
||||
func (b *SignedBeaconBlock) PbGenericBlock() (*eth.GenericSignedBeaconBlock, error) {
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
return ð.GenericSignedBeaconBlock{
|
||||
Block: ð.GenericSignedBeaconBlock_Phase0{Phase0: pb.(*eth.SignedBeaconBlock)},
|
||||
}, nil
|
||||
case version.Altair:
|
||||
return ð.GenericSignedBeaconBlock{
|
||||
Block: ð.GenericSignedBeaconBlock_Altair{Altair: pb.(*eth.SignedBeaconBlockAltair)},
|
||||
}, nil
|
||||
case version.Bellatrix:
|
||||
return ð.GenericSignedBeaconBlock{
|
||||
Block: ð.GenericSignedBeaconBlock_Bellatrix{Bellatrix: pb.(*eth.SignedBeaconBlockBellatrix)},
|
||||
}, nil
|
||||
case version.BellatrixBlind:
|
||||
return ð.GenericSignedBeaconBlock{
|
||||
Block: ð.GenericSignedBeaconBlock_BlindedBellatrix{BlindedBellatrix: pb.(*eth.SignedBlindedBeaconBlockBellatrix)},
|
||||
}, nil
|
||||
default:
|
||||
return nil, errIncorrectBlockVersion
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// PbPhase0Block returns the underlying protobuf object.
|
||||
func (b *SignedBeaconBlock) PbPhase0Block() (*eth.SignedBeaconBlock, error) {
|
||||
if b.version != version.Phase0 {
|
||||
return nil, errNotSupported("PbPhase0Block", b.version)
|
||||
}
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pb.(*eth.SignedBeaconBlock), nil
|
||||
}
|
||||
|
||||
// PbAltairBlock returns the underlying protobuf object.
|
||||
func (b *SignedBeaconBlock) PbAltairBlock() (*eth.SignedBeaconBlockAltair, error) {
|
||||
if b.version != version.Altair {
|
||||
return nil, errNotSupported("PbAltairBlock", b.version)
|
||||
}
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pb.(*eth.SignedBeaconBlockAltair), nil
|
||||
}
|
||||
|
||||
// PbBellatrixBlock returns the underlying protobuf object.
|
||||
func (b *SignedBeaconBlock) PbBellatrixBlock() (*eth.SignedBeaconBlockBellatrix, error) {
|
||||
if b.version != version.Bellatrix {
|
||||
return nil, errNotSupported("PbBellatrixBlock", b.version)
|
||||
}
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pb.(*eth.SignedBeaconBlockBellatrix), nil
|
||||
}
|
||||
|
||||
// PbBlindedBellatrixBlock returns the underlying protobuf object.
|
||||
func (b *SignedBeaconBlock) PbBlindedBellatrixBlock() (*eth.SignedBlindedBeaconBlockBellatrix, error) {
|
||||
if b.version != version.BellatrixBlind {
|
||||
return nil, errNotSupported("PbBlindedBellatrixBlock", b.version)
|
||||
}
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pb.(*eth.SignedBlindedBeaconBlockBellatrix), nil
|
||||
}
|
||||
|
||||
// Version of the underlying protobuf object.
|
||||
func (b *SignedBeaconBlock) Version() int {
|
||||
return b.version
|
||||
}
|
||||
|
||||
// Header converts the underlying protobuf object from blinded block to header format.
|
||||
func (b *SignedBeaconBlock) Header() (*eth.SignedBeaconBlockHeader, error) {
|
||||
if b.IsNil() {
|
||||
return nil, errNilBlock
|
||||
}
|
||||
root, err := b.block.body.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not hash block body")
|
||||
}
|
||||
|
||||
return ð.SignedBeaconBlockHeader{
|
||||
Header: ð.BeaconBlockHeader{
|
||||
Slot: b.block.slot,
|
||||
ProposerIndex: b.block.proposerIndex,
|
||||
ParentRoot: b.block.parentRoot,
|
||||
StateRoot: b.block.stateRoot,
|
||||
BodyRoot: root[:],
|
||||
},
|
||||
Signature: b.signature,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// MarshalSSZ marshals the signed beacon block to its relevant ssz form.
|
||||
func (b *SignedBeaconBlock) MarshalSSZ() ([]byte, error) {
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
return pb.(*eth.SignedBeaconBlock).MarshalSSZ()
|
||||
case version.Altair:
|
||||
return pb.(*eth.SignedBeaconBlockAltair).MarshalSSZ()
|
||||
case version.Bellatrix:
|
||||
return pb.(*eth.SignedBeaconBlockBellatrix).MarshalSSZ()
|
||||
case version.BellatrixBlind:
|
||||
return pb.(*eth.SignedBlindedBeaconBlockBellatrix).MarshalSSZ()
|
||||
default:
|
||||
return []byte{}, errIncorrectBlockVersion
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalSSZTo marshals the signed beacon block's ssz
|
||||
// form to the provided byte buffer.
|
||||
func (b *SignedBeaconBlock) MarshalSSZTo(dst []byte) ([]byte, error) {
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
return pb.(*eth.SignedBeaconBlock).MarshalSSZTo(dst)
|
||||
case version.Altair:
|
||||
return pb.(*eth.SignedBeaconBlockAltair).MarshalSSZTo(dst)
|
||||
case version.Bellatrix:
|
||||
return pb.(*eth.SignedBeaconBlockBellatrix).MarshalSSZTo(dst)
|
||||
case version.BellatrixBlind:
|
||||
return pb.(*eth.SignedBlindedBeaconBlockBellatrix).MarshalSSZTo(dst)
|
||||
default:
|
||||
return []byte{}, errIncorrectBlockVersion
|
||||
}
|
||||
}
|
||||
|
||||
// SizeSSZ returns the size of the serialized signed block
|
||||
func (b *SignedBeaconBlock) SizeSSZ() (int, error) {
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
return pb.(*eth.SignedBeaconBlock).SizeSSZ(), nil
|
||||
case version.Altair:
|
||||
return pb.(*eth.SignedBeaconBlockAltair).SizeSSZ(), nil
|
||||
case version.Bellatrix:
|
||||
return pb.(*eth.SignedBeaconBlockBellatrix).SizeSSZ(), nil
|
||||
case version.BellatrixBlind:
|
||||
return pb.(*eth.SignedBlindedBeaconBlockBellatrix).SizeSSZ(), nil
|
||||
default:
|
||||
return 0, errIncorrectBlockVersion
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalSSZ unmarshals the signed beacon block from its relevant ssz form.
|
||||
func (b *SignedBeaconBlock) UnmarshalSSZ(buf []byte) error {
|
||||
var newBlock *SignedBeaconBlock
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
pb := ð.SignedBeaconBlock{}
|
||||
if err := pb.UnmarshalSSZ(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
var err error
|
||||
newBlock, err = initSignedBlockFromProtoPhase0(pb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case version.Altair:
|
||||
pb := ð.SignedBeaconBlockAltair{}
|
||||
if err := pb.UnmarshalSSZ(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
var err error
|
||||
newBlock, err = initSignedBlockFromProtoAltair(pb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case version.Bellatrix:
|
||||
pb := ð.SignedBeaconBlockBellatrix{}
|
||||
if err := pb.UnmarshalSSZ(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
var err error
|
||||
newBlock, err = initSignedBlockFromProtoBellatrix(pb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case version.BellatrixBlind:
|
||||
pb := ð.SignedBlindedBeaconBlockBellatrix{}
|
||||
if err := pb.UnmarshalSSZ(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
var err error
|
||||
newBlock, err = initBlindedSignedBlockFromProtoBellatrix(pb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return errIncorrectBlockVersion
|
||||
}
|
||||
*b = *newBlock
|
||||
return nil
|
||||
}
|
||||
|
||||
// Slot returns the respective slot of the block.
|
||||
func (b *BeaconBlock) Slot() types.Slot {
|
||||
return b.slot
|
||||
}
|
||||
|
||||
// ProposerIndex returns the proposer index of the beacon block.
|
||||
func (b *BeaconBlock) ProposerIndex() types.ValidatorIndex {
|
||||
return b.proposerIndex
|
||||
}
|
||||
|
||||
// ParentRoot returns the parent root of beacon block.
|
||||
func (b *BeaconBlock) ParentRoot() []byte {
|
||||
return b.parentRoot
|
||||
}
|
||||
|
||||
// StateRoot returns the state root of the beacon block.
|
||||
func (b *BeaconBlock) StateRoot() []byte {
|
||||
return b.stateRoot
|
||||
}
|
||||
|
||||
// Body returns the underlying block body.
|
||||
func (b *BeaconBlock) Body() *BeaconBlockBody {
|
||||
return b.body
|
||||
}
|
||||
|
||||
// IsNil checks if the beacon block is nil.
|
||||
func (b *BeaconBlock) IsNil() bool {
|
||||
return b == nil || b.Body().IsNil()
|
||||
}
|
||||
|
||||
// IsBlinded checks if the beacon block is a blinded block.
|
||||
func (b *BeaconBlock) IsBlinded() bool {
|
||||
switch b.version {
|
||||
case version.Phase0, version.Altair, version.Bellatrix:
|
||||
return false
|
||||
case version.BellatrixBlind:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Version of the underlying protobuf object.
|
||||
func (b *BeaconBlock) Version() int {
|
||||
return b.version
|
||||
}
|
||||
|
||||
// HashTreeRoot returns the ssz root of the block.
|
||||
func (b *BeaconBlock) HashTreeRoot() ([32]byte, error) {
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
return [32]byte{}, err
|
||||
}
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
return pb.(*eth.BeaconBlock).HashTreeRoot()
|
||||
case version.Altair:
|
||||
return pb.(*eth.BeaconBlockAltair).HashTreeRoot()
|
||||
case version.Bellatrix:
|
||||
return pb.(*eth.BeaconBlockBellatrix).HashTreeRoot()
|
||||
case version.BellatrixBlind:
|
||||
return pb.(*eth.BlindedBeaconBlockBellatrix).HashTreeRoot()
|
||||
default:
|
||||
return [32]byte{}, errIncorrectBlockVersion
|
||||
}
|
||||
}
|
||||
|
||||
// HashTreeRootWith ssz hashes the BeaconBlock object with a hasher.
|
||||
func (b *BeaconBlock) HashTreeRootWith(h *ssz.Hasher) error {
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
return pb.(*eth.BeaconBlock).HashTreeRootWith(h)
|
||||
case version.Altair:
|
||||
return pb.(*eth.BeaconBlockAltair).HashTreeRootWith(h)
|
||||
case version.Bellatrix:
|
||||
return pb.(*eth.BeaconBlockBellatrix).HashTreeRootWith(h)
|
||||
case version.BellatrixBlind:
|
||||
return pb.(*eth.BlindedBeaconBlockBellatrix).HashTreeRootWith(h)
|
||||
default:
|
||||
return errIncorrectBlockVersion
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalSSZ marshals the block into its respective
|
||||
// ssz form.
|
||||
func (b *BeaconBlock) MarshalSSZ() ([]byte, error) {
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
return pb.(*eth.BeaconBlock).MarshalSSZ()
|
||||
case version.Altair:
|
||||
return pb.(*eth.BeaconBlockAltair).MarshalSSZ()
|
||||
case version.Bellatrix:
|
||||
return pb.(*eth.BeaconBlockBellatrix).MarshalSSZ()
|
||||
case version.BellatrixBlind:
|
||||
return pb.(*eth.BlindedBeaconBlockBellatrix).MarshalSSZ()
|
||||
default:
|
||||
return []byte{}, errIncorrectBlockVersion
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalSSZTo marshals the beacon block's ssz
|
||||
// form to the provided byte buffer.
|
||||
func (b *BeaconBlock) MarshalSSZTo(dst []byte) ([]byte, error) {
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
return pb.(*eth.BeaconBlock).MarshalSSZTo(dst)
|
||||
case version.Altair:
|
||||
return pb.(*eth.BeaconBlockAltair).MarshalSSZTo(dst)
|
||||
case version.Bellatrix:
|
||||
return pb.(*eth.BeaconBlockBellatrix).MarshalSSZTo(dst)
|
||||
case version.BellatrixBlind:
|
||||
return pb.(*eth.BlindedBeaconBlockBellatrix).MarshalSSZTo(dst)
|
||||
default:
|
||||
return []byte{}, errIncorrectBlockVersion
|
||||
}
|
||||
}
|
||||
|
||||
// SizeSSZ returns the size of the serialized block.
|
||||
func (b *BeaconBlock) SizeSSZ() (int, error) {
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
return pb.(*eth.BeaconBlock).SizeSSZ(), nil
|
||||
case version.Altair:
|
||||
return pb.(*eth.BeaconBlockAltair).SizeSSZ(), nil
|
||||
case version.Bellatrix:
|
||||
return pb.(*eth.BeaconBlockBellatrix).SizeSSZ(), nil
|
||||
case version.BellatrixBlind:
|
||||
return pb.(*eth.BlindedBeaconBlockBellatrix).SizeSSZ(), nil
|
||||
default:
|
||||
return 0, errIncorrectBlockVersion
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalSSZ unmarshals the beacon block from its relevant ssz form.
|
||||
func (b *BeaconBlock) UnmarshalSSZ(buf []byte) error {
|
||||
var newBlock *BeaconBlock
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
pb := ð.BeaconBlock{}
|
||||
if err := pb.UnmarshalSSZ(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
var err error
|
||||
newBlock, err = initBlockFromProtoPhase0(pb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case version.Altair:
|
||||
pb := ð.BeaconBlockAltair{}
|
||||
if err := pb.UnmarshalSSZ(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
var err error
|
||||
newBlock, err = initBlockFromProtoAltair(pb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case version.Bellatrix:
|
||||
pb := ð.BeaconBlockBellatrix{}
|
||||
if err := pb.UnmarshalSSZ(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
var err error
|
||||
newBlock, err = initBlockFromProtoBellatrix(pb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case version.BellatrixBlind:
|
||||
pb := ð.BlindedBeaconBlockBellatrix{}
|
||||
if err := pb.UnmarshalSSZ(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
var err error
|
||||
newBlock, err = initBlindedBlockFromProtoBellatrix(pb)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return errIncorrectBlockVersion
|
||||
}
|
||||
*b = *newBlock
|
||||
return nil
|
||||
}
|
||||
|
||||
// AsSignRequestObject returns the underlying sign request object.
|
||||
func (b *BeaconBlock) AsSignRequestObject() (validatorpb.SignRequestObject, error) {
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
return &validatorpb.SignRequest_Block{Block: pb.(*eth.BeaconBlock)}, nil
|
||||
case version.Altair:
|
||||
return &validatorpb.SignRequest_BlockV2{BlockV2: pb.(*eth.BeaconBlockAltair)}, nil
|
||||
case version.Bellatrix:
|
||||
return &validatorpb.SignRequest_BlockV3{BlockV3: pb.(*eth.BeaconBlockBellatrix)}, nil
|
||||
case version.BellatrixBlind:
|
||||
return &validatorpb.SignRequest_BlindedBlockV3{BlindedBlockV3: pb.(*eth.BlindedBeaconBlockBellatrix)}, nil
|
||||
default:
|
||||
return nil, errIncorrectBlockVersion
|
||||
}
|
||||
}
|
||||
|
||||
// IsNil checks if the block body is nil.
|
||||
func (b *BeaconBlockBody) IsNil() bool {
|
||||
return b == nil
|
||||
}
|
||||
|
||||
// RandaoReveal returns the randao reveal from the block body.
|
||||
func (b *BeaconBlockBody) RandaoReveal() []byte {
|
||||
return b.randaoReveal
|
||||
}
|
||||
|
||||
// Eth1Data returns the eth1 data in the block.
|
||||
func (b *BeaconBlockBody) Eth1Data() *eth.Eth1Data {
|
||||
return b.eth1Data
|
||||
}
|
||||
|
||||
// Graffiti returns the graffiti in the block.
|
||||
func (b *BeaconBlockBody) Graffiti() []byte {
|
||||
return b.graffiti
|
||||
}
|
||||
|
||||
// ProposerSlashings returns the proposer slashings in the block.
|
||||
func (b *BeaconBlockBody) ProposerSlashings() []*eth.ProposerSlashing {
|
||||
return b.proposerSlashings
|
||||
}
|
||||
|
||||
// AttesterSlashings returns the attester slashings in the block.
|
||||
func (b *BeaconBlockBody) AttesterSlashings() []*eth.AttesterSlashing {
|
||||
return b.attesterSlashings
|
||||
}
|
||||
|
||||
// Attestations returns the stored attestations in the block.
|
||||
func (b *BeaconBlockBody) Attestations() []*eth.Attestation {
|
||||
return b.attestations
|
||||
}
|
||||
|
||||
// Deposits returns the stored deposits in the block.
|
||||
func (b *BeaconBlockBody) Deposits() []*eth.Deposit {
|
||||
return b.deposits
|
||||
}
|
||||
|
||||
// VoluntaryExits returns the voluntary exits in the block.
|
||||
func (b *BeaconBlockBody) VoluntaryExits() []*eth.SignedVoluntaryExit {
|
||||
return b.voluntaryExits
|
||||
}
|
||||
|
||||
// SyncAggregate returns the sync aggregate in the block.
|
||||
func (b *BeaconBlockBody) SyncAggregate() (*eth.SyncAggregate, error) {
|
||||
if b.version == version.Phase0 {
|
||||
return nil, errNotSupported("SyncAggregate", b.version)
|
||||
}
|
||||
return b.syncAggregate, nil
|
||||
}
|
||||
|
||||
// ExecutionPayload returns the execution payload of the block body.
|
||||
func (b *BeaconBlockBody) ExecutionPayload() (*enginev1.ExecutionPayload, error) {
|
||||
if b.version != version.Bellatrix {
|
||||
return nil, errNotSupported("ExecutionPayload", b.version)
|
||||
}
|
||||
return b.executionPayload, nil
|
||||
}
|
||||
|
||||
// ExecutionPayloadHeader returns the execution payload header of the block body.
|
||||
func (b *BeaconBlockBody) ExecutionPayloadHeader() (*eth.ExecutionPayloadHeader, error) {
|
||||
if b.version != version.BellatrixBlind {
|
||||
return nil, errNotSupported("ExecutionPayloadHeader", b.version)
|
||||
}
|
||||
return b.executionPayloadHeader, nil
|
||||
}
|
||||
|
||||
// HashTreeRoot returns the ssz root of the block body.
|
||||
func (b *BeaconBlockBody) HashTreeRoot() ([32]byte, error) {
|
||||
pb, err := b.Proto()
|
||||
if err != nil {
|
||||
return [32]byte{}, err
|
||||
}
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
return pb.(*eth.BeaconBlockBody).HashTreeRoot()
|
||||
case version.Altair:
|
||||
return pb.(*eth.BeaconBlockBodyAltair).HashTreeRoot()
|
||||
case version.Bellatrix:
|
||||
return pb.(*eth.BeaconBlockBodyBellatrix).HashTreeRoot()
|
||||
case version.BellatrixBlind:
|
||||
return pb.(*eth.BlindedBeaconBlockBodyBellatrix).HashTreeRoot()
|
||||
default:
|
||||
return [32]byte{}, errIncorrectBodyVersion
|
||||
}
|
||||
}
|
||||
314
consensus-types/blocks/getters_test.go
Normal file
314
consensus-types/blocks/getters_test.go
Normal file
@@ -0,0 +1,314 @@
|
||||
package blocks
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
ssz "github.com/ferranbt/fastssz"
|
||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
||||
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
validatorpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/validator-client"
|
||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/testing/util"
|
||||
)
|
||||
|
||||
func Test_SignedBeaconBlock_Signature(t *testing.T) {
|
||||
sb := &SignedBeaconBlock{signature: []byte("signature")}
|
||||
assert.DeepEqual(t, []byte("signature"), sb.Signature())
|
||||
}
|
||||
|
||||
func Test_SignedBeaconBlock_Block(t *testing.T) {
|
||||
b := &BeaconBlock{}
|
||||
sb := &SignedBeaconBlock{block: b}
|
||||
assert.Equal(t, b, sb.Block())
|
||||
}
|
||||
|
||||
func Test_SignedBeaconBlock_IsNil(t *testing.T) {
|
||||
t.Run("nil signed block", func(t *testing.T) {
|
||||
var sb *SignedBeaconBlock
|
||||
assert.Equal(t, true, sb.IsNil())
|
||||
})
|
||||
t.Run("nil block", func(t *testing.T) {
|
||||
sb := &SignedBeaconBlock{}
|
||||
assert.Equal(t, true, sb.IsNil())
|
||||
})
|
||||
t.Run("nil body", func(t *testing.T) {
|
||||
sb := &SignedBeaconBlock{block: &BeaconBlock{}}
|
||||
assert.Equal(t, true, sb.IsNil())
|
||||
})
|
||||
t.Run("not nil", func(t *testing.T) {
|
||||
sb := &SignedBeaconBlock{block: &BeaconBlock{body: &BeaconBlockBody{}}}
|
||||
assert.Equal(t, false, sb.IsNil())
|
||||
})
|
||||
}
|
||||
|
||||
func Test_SignedBeaconBlock_Copy(t *testing.T) {
|
||||
bb := &BeaconBlockBody{}
|
||||
b := &BeaconBlock{body: bb}
|
||||
sb := &SignedBeaconBlock{block: b}
|
||||
cp, err := sb.Copy()
|
||||
require.NoError(t, err)
|
||||
assert.NotEqual(t, cp, sb)
|
||||
assert.NotEqual(t, cp.block, sb.block)
|
||||
assert.NotEqual(t, cp.block.body, sb.block.body)
|
||||
}
|
||||
|
||||
func Test_SignedBeaconBlock_Version(t *testing.T) {
|
||||
sb := &SignedBeaconBlock{version: 128}
|
||||
assert.Equal(t, 128, sb.Version())
|
||||
}
|
||||
|
||||
func Test_SignedBeaconBlock_Header(t *testing.T) {
|
||||
bb := &BeaconBlockBody{
|
||||
version: version.Phase0,
|
||||
randaoReveal: make([]byte, 96),
|
||||
eth1Data: ð.Eth1Data{
|
||||
DepositRoot: make([]byte, 32),
|
||||
BlockHash: make([]byte, 32),
|
||||
},
|
||||
graffiti: make([]byte, 32),
|
||||
}
|
||||
sb := &SignedBeaconBlock{
|
||||
version: version.Phase0,
|
||||
block: &BeaconBlock{
|
||||
version: version.Phase0,
|
||||
slot: 128,
|
||||
proposerIndex: 128,
|
||||
parentRoot: []byte("parentroot"),
|
||||
stateRoot: []byte("stateroot"),
|
||||
body: bb,
|
||||
},
|
||||
signature: []byte("signature"),
|
||||
}
|
||||
h, err := sb.Header()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, sb.signature, h.Signature)
|
||||
assert.Equal(t, sb.block.slot, h.Header.Slot)
|
||||
assert.Equal(t, sb.block.proposerIndex, h.Header.ProposerIndex)
|
||||
assert.DeepEqual(t, sb.block.parentRoot, h.Header.ParentRoot)
|
||||
assert.DeepEqual(t, sb.block.stateRoot, h.Header.StateRoot)
|
||||
expectedHTR, err := bb.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR[:], h.Header.BodyRoot)
|
||||
}
|
||||
|
||||
func Test_SignedBeaconBlock_UnmarshalSSZ(t *testing.T) {
|
||||
pb := util.HydrateSignedBeaconBlock(ð.SignedBeaconBlock{})
|
||||
buf, err := pb.MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := pb.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
sb := &SignedBeaconBlock{}
|
||||
require.NoError(t, sb.UnmarshalSSZ(buf))
|
||||
msg, err := sb.Proto()
|
||||
require.NoError(t, err)
|
||||
actualPb, ok := msg.(*eth.SignedBeaconBlock)
|
||||
require.Equal(t, true, ok)
|
||||
actualHTR, err := actualPb.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, actualHTR)
|
||||
}
|
||||
|
||||
func Test_BeaconBlock_Slot(t *testing.T) {
|
||||
b := &BeaconBlock{slot: 128}
|
||||
assert.Equal(t, types.Slot(128), b.Slot())
|
||||
}
|
||||
|
||||
func Test_BeaconBlock_ProposerIndex(t *testing.T) {
|
||||
b := &BeaconBlock{proposerIndex: 128}
|
||||
assert.Equal(t, types.ValidatorIndex(128), b.ProposerIndex())
|
||||
}
|
||||
|
||||
func Test_BeaconBlock_ParentRoot(t *testing.T) {
|
||||
b := &BeaconBlock{parentRoot: []byte("parentroot")}
|
||||
assert.DeepEqual(t, []byte("parentroot"), b.ParentRoot())
|
||||
}
|
||||
|
||||
func Test_BeaconBlock_StateRoot(t *testing.T) {
|
||||
b := &BeaconBlock{stateRoot: []byte("stateroot")}
|
||||
assert.DeepEqual(t, []byte("stateroot"), b.StateRoot())
|
||||
}
|
||||
|
||||
func Test_BeaconBlock_Body(t *testing.T) {
|
||||
bb := &BeaconBlockBody{}
|
||||
b := &BeaconBlock{body: bb}
|
||||
assert.Equal(t, bb, b.Body())
|
||||
}
|
||||
|
||||
func Test_BeaconBlock_IsNil(t *testing.T) {
|
||||
t.Run("nil block", func(t *testing.T) {
|
||||
var b *BeaconBlock
|
||||
assert.Equal(t, true, b.IsNil())
|
||||
})
|
||||
t.Run("nil block body", func(t *testing.T) {
|
||||
b := &BeaconBlock{}
|
||||
assert.Equal(t, true, b.IsNil())
|
||||
})
|
||||
t.Run("not nil", func(t *testing.T) {
|
||||
b := &BeaconBlock{body: &BeaconBlockBody{}}
|
||||
assert.Equal(t, false, b.IsNil())
|
||||
})
|
||||
}
|
||||
|
||||
func Test_BeaconBlock_IsBlinded(t *testing.T) {
|
||||
assert.Equal(t, false, (&BeaconBlock{version: version.Phase0}).IsBlinded())
|
||||
assert.Equal(t, false, (&BeaconBlock{version: version.Altair}).IsBlinded())
|
||||
assert.Equal(t, false, (&BeaconBlock{version: version.Bellatrix}).IsBlinded())
|
||||
assert.Equal(t, true, (&BeaconBlock{version: version.BellatrixBlind}).IsBlinded())
|
||||
assert.Equal(t, false, (&BeaconBlock{version: 128}).IsBlinded())
|
||||
}
|
||||
|
||||
func Test_BeaconBlock_Version(t *testing.T) {
|
||||
b := &BeaconBlock{version: 128}
|
||||
assert.Equal(t, 128, b.Version())
|
||||
}
|
||||
|
||||
func Test_BeaconBlock_HashTreeRoot(t *testing.T) {
|
||||
pb := util.HydrateBeaconBlock(ð.BeaconBlock{})
|
||||
expectedHTR, err := pb.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
b, err := initBlockFromProtoPhase0(pb)
|
||||
require.NoError(t, err)
|
||||
actualHTR, err := b.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, actualHTR)
|
||||
}
|
||||
|
||||
func Test_BeaconBlock_HashTreeRootWith(t *testing.T) {
|
||||
pb := util.HydrateBeaconBlock(ð.BeaconBlock{})
|
||||
expectedHTR, err := pb.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
b, err := initBlockFromProtoPhase0(pb)
|
||||
require.NoError(t, err)
|
||||
h := ssz.DefaultHasherPool.Get()
|
||||
require.NoError(t, b.HashTreeRootWith(h))
|
||||
actualHTR, err := h.HashRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, actualHTR)
|
||||
}
|
||||
|
||||
func Test_BeaconBlock_UnmarshalSSZ(t *testing.T) {
|
||||
pb := util.HydrateBeaconBlock(ð.BeaconBlock{})
|
||||
buf, err := pb.MarshalSSZ()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := pb.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
b := &BeaconBlock{}
|
||||
require.NoError(t, b.UnmarshalSSZ(buf))
|
||||
msg, err := b.Proto()
|
||||
require.NoError(t, err)
|
||||
actualPb, ok := msg.(*eth.BeaconBlock)
|
||||
require.Equal(t, true, ok)
|
||||
actualHTR, err := actualPb.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, actualHTR)
|
||||
}
|
||||
|
||||
func Test_BeaconBlock_AsSignRequestObject(t *testing.T) {
|
||||
pb := util.HydrateBeaconBlock(ð.BeaconBlock{})
|
||||
expectedHTR, err := pb.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
b, err := initBlockFromProtoPhase0(pb)
|
||||
require.NoError(t, err)
|
||||
signRequestObj, err := b.AsSignRequestObject()
|
||||
require.NoError(t, err)
|
||||
actualSignRequestObj, ok := signRequestObj.(*validatorpb.SignRequest_Block)
|
||||
require.Equal(t, true, ok)
|
||||
actualHTR, err := actualSignRequestObj.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, actualHTR)
|
||||
}
|
||||
|
||||
func Test_BeaconBlockBody_IsNil(t *testing.T) {
|
||||
t.Run("nil block body", func(t *testing.T) {
|
||||
var bb *BeaconBlockBody
|
||||
assert.Equal(t, true, bb.IsNil())
|
||||
})
|
||||
t.Run("not nil", func(t *testing.T) {
|
||||
bb := &BeaconBlockBody{}
|
||||
assert.Equal(t, false, bb.IsNil())
|
||||
})
|
||||
}
|
||||
|
||||
func Test_BeaconBlockBody_RandaoReveal(t *testing.T) {
|
||||
bb := &BeaconBlockBody{randaoReveal: []byte("randaoreveal")}
|
||||
assert.DeepEqual(t, []byte("randaoreveal"), bb.RandaoReveal())
|
||||
}
|
||||
|
||||
func Test_BeaconBlockBody_Eth1Data(t *testing.T) {
|
||||
e := ð.Eth1Data{}
|
||||
bb := &BeaconBlockBody{eth1Data: e}
|
||||
assert.Equal(t, e, bb.Eth1Data())
|
||||
}
|
||||
|
||||
func Test_BeaconBlockBody_Graffiti(t *testing.T) {
|
||||
bb := &BeaconBlockBody{graffiti: []byte("graffiti")}
|
||||
assert.DeepEqual(t, []byte("graffiti"), bb.Graffiti())
|
||||
}
|
||||
|
||||
func Test_BeaconBlockBody_ProposerSlashings(t *testing.T) {
|
||||
ps := make([]*eth.ProposerSlashing, 0)
|
||||
bb := &BeaconBlockBody{proposerSlashings: ps}
|
||||
assert.DeepSSZEqual(t, ps, bb.ProposerSlashings())
|
||||
}
|
||||
|
||||
func Test_BeaconBlockBody_AttesterSlashings(t *testing.T) {
|
||||
as := make([]*eth.AttesterSlashing, 0)
|
||||
bb := &BeaconBlockBody{attesterSlashings: as}
|
||||
assert.DeepSSZEqual(t, as, bb.AttesterSlashings())
|
||||
}
|
||||
|
||||
func Test_BeaconBlockBody_Attestations(t *testing.T) {
|
||||
a := make([]*eth.Attestation, 0)
|
||||
bb := &BeaconBlockBody{attestations: a}
|
||||
assert.DeepSSZEqual(t, a, bb.Attestations())
|
||||
}
|
||||
|
||||
func Test_BeaconBlockBody_Deposits(t *testing.T) {
|
||||
d := make([]*eth.Deposit, 0)
|
||||
bb := &BeaconBlockBody{deposits: d}
|
||||
assert.DeepSSZEqual(t, d, bb.Deposits())
|
||||
}
|
||||
|
||||
func Test_BeaconBlockBody_VoluntaryExits(t *testing.T) {
|
||||
ve := make([]*eth.SignedVoluntaryExit, 0)
|
||||
bb := &BeaconBlockBody{voluntaryExits: ve}
|
||||
assert.DeepSSZEqual(t, ve, bb.VoluntaryExits())
|
||||
}
|
||||
|
||||
func Test_BeaconBlockBody_SyncAggregate(t *testing.T) {
|
||||
sa := ð.SyncAggregate{}
|
||||
bb := &BeaconBlockBody{version: version.Altair, syncAggregate: sa}
|
||||
result, err := bb.SyncAggregate()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, result, sa)
|
||||
}
|
||||
|
||||
func Test_BeaconBlockBody_ExecutionPayload(t *testing.T) {
|
||||
ep := &enginev1.ExecutionPayload{}
|
||||
bb := &BeaconBlockBody{version: version.Bellatrix, executionPayload: ep}
|
||||
result, err := bb.ExecutionPayload()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, result, ep)
|
||||
}
|
||||
|
||||
func Test_BeaconBlockBody_ExecutionPayloadHeader(t *testing.T) {
|
||||
eph := ð.ExecutionPayloadHeader{}
|
||||
bb := &BeaconBlockBody{version: version.BellatrixBlind, executionPayloadHeader: eph}
|
||||
result, err := bb.ExecutionPayloadHeader()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, result, eph)
|
||||
}
|
||||
|
||||
func Test_BeaconBlockBody_HashTreeRoot(t *testing.T) {
|
||||
pb := util.HydrateBeaconBlockBody(ð.BeaconBlockBody{})
|
||||
expectedHTR, err := pb.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
b, err := initBlockBodyFromProtoPhase0(pb)
|
||||
require.NoError(t, err)
|
||||
actualHTR, err := b.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, actualHTR)
|
||||
}
|
||||
416
consensus-types/blocks/proto.go
Normal file
416
consensus-types/blocks/proto.go
Normal file
@@ -0,0 +1,416 @@
|
||||
package blocks
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
// Proto returns the underlying protobuf signed beacon block.
|
||||
func (b *SignedBeaconBlock) Proto() (proto.Message, error) {
|
||||
if b == nil {
|
||||
return nil, errNilBlock
|
||||
}
|
||||
|
||||
blockMessage, err := b.block.Proto()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
block, ok := blockMessage.(*eth.BeaconBlock)
|
||||
if !ok {
|
||||
return nil, errors.Wrap(err, incorrectBlockVersion)
|
||||
}
|
||||
return ð.SignedBeaconBlock{
|
||||
Block: block,
|
||||
Signature: b.signature,
|
||||
}, nil
|
||||
case version.Altair:
|
||||
block, ok := blockMessage.(*eth.BeaconBlockAltair)
|
||||
if !ok {
|
||||
return nil, errors.Wrap(err, incorrectBlockVersion)
|
||||
}
|
||||
return ð.SignedBeaconBlockAltair{
|
||||
Block: block,
|
||||
Signature: b.signature,
|
||||
}, nil
|
||||
case version.Bellatrix:
|
||||
block, ok := blockMessage.(*eth.BeaconBlockBellatrix)
|
||||
if !ok {
|
||||
return nil, errors.Wrap(err, incorrectBlockVersion)
|
||||
}
|
||||
return ð.SignedBeaconBlockBellatrix{
|
||||
Block: block,
|
||||
Signature: b.signature,
|
||||
}, nil
|
||||
case version.BellatrixBlind:
|
||||
block, ok := blockMessage.(*eth.BlindedBeaconBlockBellatrix)
|
||||
if !ok {
|
||||
return nil, errors.Wrap(err, incorrectBlockVersion)
|
||||
}
|
||||
return ð.SignedBlindedBeaconBlockBellatrix{
|
||||
Block: block,
|
||||
Signature: b.signature,
|
||||
}, nil
|
||||
default:
|
||||
return nil, errors.New("unsupported signed beacon block version")
|
||||
}
|
||||
}
|
||||
|
||||
// Proto returns the underlying protobuf beacon block.
|
||||
func (b *BeaconBlock) Proto() (proto.Message, error) {
|
||||
if b == nil {
|
||||
return nil, errNilBlock
|
||||
}
|
||||
|
||||
bodyMessage, err := b.body.Proto()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
body, ok := bodyMessage.(*eth.BeaconBlockBody)
|
||||
if !ok {
|
||||
return nil, errors.Wrap(err, incorrectBodyVersion)
|
||||
}
|
||||
return ð.BeaconBlock{
|
||||
Slot: b.slot,
|
||||
ProposerIndex: b.proposerIndex,
|
||||
ParentRoot: b.parentRoot,
|
||||
StateRoot: b.stateRoot,
|
||||
Body: body,
|
||||
}, nil
|
||||
case version.Altair:
|
||||
body, ok := bodyMessage.(*eth.BeaconBlockBodyAltair)
|
||||
if !ok {
|
||||
return nil, errors.Wrap(err, incorrectBodyVersion)
|
||||
}
|
||||
return ð.BeaconBlockAltair{
|
||||
Slot: b.slot,
|
||||
ProposerIndex: b.proposerIndex,
|
||||
ParentRoot: b.parentRoot,
|
||||
StateRoot: b.stateRoot,
|
||||
Body: body,
|
||||
}, nil
|
||||
case version.Bellatrix:
|
||||
body, ok := bodyMessage.(*eth.BeaconBlockBodyBellatrix)
|
||||
if !ok {
|
||||
return nil, errors.Wrap(err, incorrectBodyVersion)
|
||||
}
|
||||
return ð.BeaconBlockBellatrix{
|
||||
Slot: b.slot,
|
||||
ProposerIndex: b.proposerIndex,
|
||||
ParentRoot: b.parentRoot,
|
||||
StateRoot: b.stateRoot,
|
||||
Body: body,
|
||||
}, nil
|
||||
case version.BellatrixBlind:
|
||||
body, ok := bodyMessage.(*eth.BlindedBeaconBlockBodyBellatrix)
|
||||
if !ok {
|
||||
return nil, errors.Wrap(err, incorrectBodyVersion)
|
||||
}
|
||||
return ð.BlindedBeaconBlockBellatrix{
|
||||
Slot: b.slot,
|
||||
ProposerIndex: b.proposerIndex,
|
||||
ParentRoot: b.parentRoot,
|
||||
StateRoot: b.stateRoot,
|
||||
Body: body,
|
||||
}, nil
|
||||
default:
|
||||
return nil, errors.New("unsupported beacon block version")
|
||||
}
|
||||
}
|
||||
|
||||
// Proto returns the underlying protobuf beacon block body.
|
||||
func (b *BeaconBlockBody) Proto() (proto.Message, error) {
|
||||
if b == nil {
|
||||
return nil, errNilBody
|
||||
}
|
||||
|
||||
switch b.version {
|
||||
case version.Phase0:
|
||||
return ð.BeaconBlockBody{
|
||||
RandaoReveal: b.randaoReveal,
|
||||
Eth1Data: b.eth1Data,
|
||||
Graffiti: b.graffiti,
|
||||
ProposerSlashings: b.proposerSlashings,
|
||||
AttesterSlashings: b.attesterSlashings,
|
||||
Attestations: b.attestations,
|
||||
Deposits: b.deposits,
|
||||
VoluntaryExits: b.voluntaryExits,
|
||||
}, nil
|
||||
case version.Altair:
|
||||
return ð.BeaconBlockBodyAltair{
|
||||
RandaoReveal: b.randaoReveal,
|
||||
Eth1Data: b.eth1Data,
|
||||
Graffiti: b.graffiti,
|
||||
ProposerSlashings: b.proposerSlashings,
|
||||
AttesterSlashings: b.attesterSlashings,
|
||||
Attestations: b.attestations,
|
||||
Deposits: b.deposits,
|
||||
VoluntaryExits: b.voluntaryExits,
|
||||
SyncAggregate: b.syncAggregate,
|
||||
}, nil
|
||||
case version.Bellatrix:
|
||||
return ð.BeaconBlockBodyBellatrix{
|
||||
RandaoReveal: b.randaoReveal,
|
||||
Eth1Data: b.eth1Data,
|
||||
Graffiti: b.graffiti,
|
||||
ProposerSlashings: b.proposerSlashings,
|
||||
AttesterSlashings: b.attesterSlashings,
|
||||
Attestations: b.attestations,
|
||||
Deposits: b.deposits,
|
||||
VoluntaryExits: b.voluntaryExits,
|
||||
SyncAggregate: b.syncAggregate,
|
||||
ExecutionPayload: b.executionPayload,
|
||||
}, nil
|
||||
case version.BellatrixBlind:
|
||||
return ð.BlindedBeaconBlockBodyBellatrix{
|
||||
RandaoReveal: b.randaoReveal,
|
||||
Eth1Data: b.eth1Data,
|
||||
Graffiti: b.graffiti,
|
||||
ProposerSlashings: b.proposerSlashings,
|
||||
AttesterSlashings: b.attesterSlashings,
|
||||
Attestations: b.attestations,
|
||||
Deposits: b.deposits,
|
||||
VoluntaryExits: b.voluntaryExits,
|
||||
SyncAggregate: b.syncAggregate,
|
||||
ExecutionPayloadHeader: b.executionPayloadHeader,
|
||||
}, nil
|
||||
default:
|
||||
return nil, errors.New("unsupported beacon block body version")
|
||||
}
|
||||
}
|
||||
|
||||
func initSignedBlockFromProtoPhase0(pb *eth.SignedBeaconBlock) (*SignedBeaconBlock, error) {
|
||||
if pb == nil {
|
||||
return nil, errNilBlock
|
||||
}
|
||||
|
||||
block, err := initBlockFromProtoPhase0(pb.Block)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b := &SignedBeaconBlock{
|
||||
version: version.Phase0,
|
||||
block: block,
|
||||
signature: pb.Signature,
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func initSignedBlockFromProtoAltair(pb *eth.SignedBeaconBlockAltair) (*SignedBeaconBlock, error) {
|
||||
if pb == nil {
|
||||
return nil, errNilBlock
|
||||
}
|
||||
|
||||
block, err := initBlockFromProtoAltair(pb.Block)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b := &SignedBeaconBlock{
|
||||
version: version.Altair,
|
||||
block: block,
|
||||
signature: pb.Signature,
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func initSignedBlockFromProtoBellatrix(pb *eth.SignedBeaconBlockBellatrix) (*SignedBeaconBlock, error) {
|
||||
if pb == nil {
|
||||
return nil, errNilBlock
|
||||
}
|
||||
|
||||
block, err := initBlockFromProtoBellatrix(pb.Block)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b := &SignedBeaconBlock{
|
||||
version: version.Bellatrix,
|
||||
block: block,
|
||||
signature: pb.Signature,
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func initBlindedSignedBlockFromProtoBellatrix(pb *eth.SignedBlindedBeaconBlockBellatrix) (*SignedBeaconBlock, error) {
|
||||
if pb == nil {
|
||||
return nil, errNilBlock
|
||||
}
|
||||
|
||||
block, err := initBlindedBlockFromProtoBellatrix(pb.Block)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b := &SignedBeaconBlock{
|
||||
version: version.BellatrixBlind,
|
||||
block: block,
|
||||
signature: pb.Signature,
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func initBlockFromProtoPhase0(pb *eth.BeaconBlock) (*BeaconBlock, error) {
|
||||
if pb == nil {
|
||||
return nil, errNilBlock
|
||||
}
|
||||
|
||||
body, err := initBlockBodyFromProtoPhase0(pb.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b := &BeaconBlock{
|
||||
version: version.Phase0,
|
||||
slot: pb.Slot,
|
||||
proposerIndex: pb.ProposerIndex,
|
||||
parentRoot: pb.ParentRoot,
|
||||
stateRoot: pb.StateRoot,
|
||||
body: body,
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func initBlockFromProtoAltair(pb *eth.BeaconBlockAltair) (*BeaconBlock, error) {
|
||||
if pb == nil {
|
||||
return nil, errNilBlock
|
||||
}
|
||||
|
||||
body, err := initBlockBodyFromProtoAltair(pb.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b := &BeaconBlock{
|
||||
version: version.Altair,
|
||||
slot: pb.Slot,
|
||||
proposerIndex: pb.ProposerIndex,
|
||||
parentRoot: pb.ParentRoot,
|
||||
stateRoot: pb.StateRoot,
|
||||
body: body,
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func initBlockFromProtoBellatrix(pb *eth.BeaconBlockBellatrix) (*BeaconBlock, error) {
|
||||
if pb == nil {
|
||||
return nil, errNilBlock
|
||||
}
|
||||
|
||||
body, err := initBlockBodyFromProtoBellatrix(pb.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b := &BeaconBlock{
|
||||
version: version.Bellatrix,
|
||||
slot: pb.Slot,
|
||||
proposerIndex: pb.ProposerIndex,
|
||||
parentRoot: pb.ParentRoot,
|
||||
stateRoot: pb.StateRoot,
|
||||
body: body,
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func initBlindedBlockFromProtoBellatrix(pb *eth.BlindedBeaconBlockBellatrix) (*BeaconBlock, error) {
|
||||
if pb == nil {
|
||||
return nil, errNilBlock
|
||||
}
|
||||
|
||||
body, err := initBlindedBlockBodyFromProtoBellatrix(pb.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b := &BeaconBlock{
|
||||
version: version.BellatrixBlind,
|
||||
slot: pb.Slot,
|
||||
proposerIndex: pb.ProposerIndex,
|
||||
parentRoot: pb.ParentRoot,
|
||||
stateRoot: pb.StateRoot,
|
||||
body: body,
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func initBlockBodyFromProtoPhase0(pb *eth.BeaconBlockBody) (*BeaconBlockBody, error) {
|
||||
if pb == nil {
|
||||
return nil, errNilBody
|
||||
}
|
||||
|
||||
b := &BeaconBlockBody{
|
||||
version: version.Phase0,
|
||||
randaoReveal: pb.RandaoReveal,
|
||||
eth1Data: pb.Eth1Data,
|
||||
graffiti: pb.Graffiti,
|
||||
proposerSlashings: pb.ProposerSlashings,
|
||||
attesterSlashings: pb.AttesterSlashings,
|
||||
attestations: pb.Attestations,
|
||||
deposits: pb.Deposits,
|
||||
voluntaryExits: pb.VoluntaryExits,
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func initBlockBodyFromProtoAltair(pb *eth.BeaconBlockBodyAltair) (*BeaconBlockBody, error) {
|
||||
if pb == nil {
|
||||
return nil, errNilBody
|
||||
}
|
||||
|
||||
b := &BeaconBlockBody{
|
||||
version: version.Altair,
|
||||
randaoReveal: pb.RandaoReveal,
|
||||
eth1Data: pb.Eth1Data,
|
||||
graffiti: pb.Graffiti,
|
||||
proposerSlashings: pb.ProposerSlashings,
|
||||
attesterSlashings: pb.AttesterSlashings,
|
||||
attestations: pb.Attestations,
|
||||
deposits: pb.Deposits,
|
||||
voluntaryExits: pb.VoluntaryExits,
|
||||
syncAggregate: pb.SyncAggregate,
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func initBlockBodyFromProtoBellatrix(pb *eth.BeaconBlockBodyBellatrix) (*BeaconBlockBody, error) {
|
||||
if pb == nil {
|
||||
return nil, errNilBody
|
||||
}
|
||||
|
||||
b := &BeaconBlockBody{
|
||||
version: version.Bellatrix,
|
||||
randaoReveal: pb.RandaoReveal,
|
||||
eth1Data: pb.Eth1Data,
|
||||
graffiti: pb.Graffiti,
|
||||
proposerSlashings: pb.ProposerSlashings,
|
||||
attesterSlashings: pb.AttesterSlashings,
|
||||
attestations: pb.Attestations,
|
||||
deposits: pb.Deposits,
|
||||
voluntaryExits: pb.VoluntaryExits,
|
||||
syncAggregate: pb.SyncAggregate,
|
||||
executionPayload: pb.ExecutionPayload,
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func initBlindedBlockBodyFromProtoBellatrix(pb *eth.BlindedBeaconBlockBodyBellatrix) (*BeaconBlockBody, error) {
|
||||
if pb == nil {
|
||||
return nil, errNilBody
|
||||
}
|
||||
|
||||
b := &BeaconBlockBody{
|
||||
version: version.BellatrixBlind,
|
||||
randaoReveal: pb.RandaoReveal,
|
||||
eth1Data: pb.Eth1Data,
|
||||
graffiti: pb.Graffiti,
|
||||
proposerSlashings: pb.ProposerSlashings,
|
||||
attesterSlashings: pb.AttesterSlashings,
|
||||
attestations: pb.Attestations,
|
||||
deposits: pb.Deposits,
|
||||
voluntaryExits: pb.VoluntaryExits,
|
||||
syncAggregate: pb.SyncAggregate,
|
||||
executionPayloadHeader: pb.ExecutionPayloadHeader,
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
871
consensus-types/blocks/proto_test.go
Normal file
871
consensus-types/blocks/proto_test.go
Normal file
@@ -0,0 +1,871 @@
|
||||
package blocks
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
||||
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/testing/require"
|
||||
)
|
||||
|
||||
type fields struct {
|
||||
b20 []byte
|
||||
b32 []byte
|
||||
b48 []byte
|
||||
b96 []byte
|
||||
b256 []byte
|
||||
deposits []*eth.Deposit
|
||||
atts []*eth.Attestation
|
||||
proposerSlashings []*eth.ProposerSlashing
|
||||
attesterSlashings []*eth.AttesterSlashing
|
||||
voluntaryExits []*eth.SignedVoluntaryExit
|
||||
syncAggregate *eth.SyncAggregate
|
||||
execPayload *enginev1.ExecutionPayload
|
||||
execPayloadHeader *eth.ExecutionPayloadHeader
|
||||
}
|
||||
|
||||
func Test_SignedBeaconBlock_Proto(t *testing.T) {
|
||||
f := getFields()
|
||||
|
||||
t.Run("Phase0", func(t *testing.T) {
|
||||
expectedBlock := ð.SignedBeaconBlock{
|
||||
Block: ð.BeaconBlock{
|
||||
Slot: 128,
|
||||
ProposerIndex: 128,
|
||||
ParentRoot: f.b32,
|
||||
StateRoot: f.b32,
|
||||
Body: bodyPbPhase0(),
|
||||
},
|
||||
Signature: f.b96,
|
||||
}
|
||||
block := &SignedBeaconBlock{
|
||||
version: version.Phase0,
|
||||
block: &BeaconBlock{
|
||||
version: version.Phase0,
|
||||
slot: 128,
|
||||
proposerIndex: 128,
|
||||
parentRoot: f.b32,
|
||||
stateRoot: f.b32,
|
||||
body: bodyPhase0(),
|
||||
},
|
||||
signature: f.b96,
|
||||
}
|
||||
|
||||
result, err := block.Proto()
|
||||
require.NoError(t, err)
|
||||
resultBlock, ok := result.(*eth.SignedBeaconBlock)
|
||||
require.Equal(t, true, ok)
|
||||
resultHTR, err := resultBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
})
|
||||
t.Run("Altair", func(t *testing.T) {
|
||||
expectedBlock := ð.SignedBeaconBlockAltair{
|
||||
Block: ð.BeaconBlockAltair{
|
||||
Slot: 128,
|
||||
ProposerIndex: 128,
|
||||
ParentRoot: f.b32,
|
||||
StateRoot: f.b32,
|
||||
Body: bodyPbAltair(),
|
||||
},
|
||||
Signature: f.b96,
|
||||
}
|
||||
block := &SignedBeaconBlock{
|
||||
version: version.Altair,
|
||||
block: &BeaconBlock{
|
||||
version: version.Altair,
|
||||
slot: 128,
|
||||
proposerIndex: 128,
|
||||
parentRoot: f.b32,
|
||||
stateRoot: f.b32,
|
||||
body: bodyAltair(),
|
||||
},
|
||||
signature: f.b96,
|
||||
}
|
||||
|
||||
result, err := block.Proto()
|
||||
require.NoError(t, err)
|
||||
resultBlock, ok := result.(*eth.SignedBeaconBlockAltair)
|
||||
require.Equal(t, true, ok)
|
||||
resultHTR, err := resultBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
})
|
||||
t.Run("Bellatrix", func(t *testing.T) {
|
||||
expectedBlock := ð.SignedBeaconBlockBellatrix{
|
||||
Block: ð.BeaconBlockBellatrix{
|
||||
Slot: 128,
|
||||
ProposerIndex: 128,
|
||||
ParentRoot: f.b32,
|
||||
StateRoot: f.b32,
|
||||
Body: bodyPbBellatrix(),
|
||||
},
|
||||
Signature: f.b96,
|
||||
}
|
||||
block := &SignedBeaconBlock{
|
||||
version: version.Bellatrix,
|
||||
block: &BeaconBlock{
|
||||
version: version.Bellatrix,
|
||||
slot: 128,
|
||||
proposerIndex: 128,
|
||||
parentRoot: f.b32,
|
||||
stateRoot: f.b32,
|
||||
body: bodyBellatrix(),
|
||||
},
|
||||
signature: f.b96,
|
||||
}
|
||||
|
||||
result, err := block.Proto()
|
||||
require.NoError(t, err)
|
||||
resultBlock, ok := result.(*eth.SignedBeaconBlockBellatrix)
|
||||
require.Equal(t, true, ok)
|
||||
resultHTR, err := resultBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
})
|
||||
t.Run("BellatrixBlind", func(t *testing.T) {
|
||||
expectedBlock := ð.SignedBlindedBeaconBlockBellatrix{
|
||||
Block: ð.BlindedBeaconBlockBellatrix{
|
||||
Slot: 128,
|
||||
ProposerIndex: 128,
|
||||
ParentRoot: f.b32,
|
||||
StateRoot: f.b32,
|
||||
Body: bodyPbBlindedBellatrix(),
|
||||
},
|
||||
Signature: f.b96,
|
||||
}
|
||||
block := &SignedBeaconBlock{
|
||||
version: version.BellatrixBlind,
|
||||
block: &BeaconBlock{
|
||||
version: version.BellatrixBlind,
|
||||
slot: 128,
|
||||
proposerIndex: 128,
|
||||
parentRoot: f.b32,
|
||||
stateRoot: f.b32,
|
||||
body: bodyBlindedBellatrix(),
|
||||
},
|
||||
signature: f.b96,
|
||||
}
|
||||
|
||||
result, err := block.Proto()
|
||||
require.NoError(t, err)
|
||||
resultBlock, ok := result.(*eth.SignedBlindedBeaconBlockBellatrix)
|
||||
require.Equal(t, true, ok)
|
||||
resultHTR, err := resultBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_BeaconBlock_Proto(t *testing.T) {
|
||||
f := getFields()
|
||||
|
||||
t.Run("Phase0", func(t *testing.T) {
|
||||
expectedBlock := ð.BeaconBlock{
|
||||
Slot: 128,
|
||||
ProposerIndex: 128,
|
||||
ParentRoot: f.b32,
|
||||
StateRoot: f.b32,
|
||||
Body: bodyPbPhase0(),
|
||||
}
|
||||
block := &BeaconBlock{
|
||||
version: version.Phase0,
|
||||
slot: 128,
|
||||
proposerIndex: 128,
|
||||
parentRoot: f.b32,
|
||||
stateRoot: f.b32,
|
||||
body: bodyPhase0(),
|
||||
}
|
||||
|
||||
result, err := block.Proto()
|
||||
require.NoError(t, err)
|
||||
resultBlock, ok := result.(*eth.BeaconBlock)
|
||||
require.Equal(t, true, ok)
|
||||
resultHTR, err := resultBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
})
|
||||
t.Run("Altair", func(t *testing.T) {
|
||||
expectedBlock := ð.BeaconBlockAltair{
|
||||
Slot: 128,
|
||||
ProposerIndex: 128,
|
||||
ParentRoot: f.b32,
|
||||
StateRoot: f.b32,
|
||||
Body: bodyPbAltair(),
|
||||
}
|
||||
block := &BeaconBlock{
|
||||
version: version.Altair,
|
||||
slot: 128,
|
||||
proposerIndex: 128,
|
||||
parentRoot: f.b32,
|
||||
stateRoot: f.b32,
|
||||
body: bodyAltair(),
|
||||
}
|
||||
|
||||
result, err := block.Proto()
|
||||
require.NoError(t, err)
|
||||
resultBlock, ok := result.(*eth.BeaconBlockAltair)
|
||||
require.Equal(t, true, ok)
|
||||
resultHTR, err := resultBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
})
|
||||
t.Run("Bellatrix", func(t *testing.T) {
|
||||
expectedBlock := ð.BeaconBlockBellatrix{
|
||||
Slot: 128,
|
||||
ProposerIndex: 128,
|
||||
ParentRoot: f.b32,
|
||||
StateRoot: f.b32,
|
||||
Body: bodyPbBellatrix(),
|
||||
}
|
||||
block := &BeaconBlock{
|
||||
version: version.Bellatrix,
|
||||
slot: 128,
|
||||
proposerIndex: 128,
|
||||
parentRoot: f.b32,
|
||||
stateRoot: f.b32,
|
||||
body: bodyBellatrix(),
|
||||
}
|
||||
|
||||
result, err := block.Proto()
|
||||
require.NoError(t, err)
|
||||
resultBlock, ok := result.(*eth.BeaconBlockBellatrix)
|
||||
require.Equal(t, true, ok)
|
||||
resultHTR, err := resultBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
})
|
||||
t.Run("BellatrixBlind", func(t *testing.T) {
|
||||
expectedBlock := ð.BlindedBeaconBlockBellatrix{
|
||||
Slot: 128,
|
||||
ProposerIndex: 128,
|
||||
ParentRoot: f.b32,
|
||||
StateRoot: f.b32,
|
||||
Body: bodyPbBlindedBellatrix(),
|
||||
}
|
||||
block := &BeaconBlock{
|
||||
version: version.BellatrixBlind,
|
||||
slot: 128,
|
||||
proposerIndex: 128,
|
||||
parentRoot: f.b32,
|
||||
stateRoot: f.b32,
|
||||
body: bodyBlindedBellatrix(),
|
||||
}
|
||||
|
||||
result, err := block.Proto()
|
||||
require.NoError(t, err)
|
||||
resultBlock, ok := result.(*eth.BlindedBeaconBlockBellatrix)
|
||||
require.Equal(t, true, ok)
|
||||
resultHTR, err := resultBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_BeaconBlockBody_Proto(t *testing.T) {
|
||||
t.Run("Phase0", func(t *testing.T) {
|
||||
expectedBody := bodyPbPhase0()
|
||||
body := bodyPhase0()
|
||||
|
||||
result, err := body.Proto()
|
||||
require.NoError(t, err)
|
||||
resultBlock, ok := result.(*eth.BeaconBlockBody)
|
||||
require.Equal(t, true, ok)
|
||||
resultHTR, err := resultBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBody.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
})
|
||||
t.Run("Altair", func(t *testing.T) {
|
||||
expectedBody := bodyPbAltair()
|
||||
body := bodyAltair()
|
||||
result, err := body.Proto()
|
||||
require.NoError(t, err)
|
||||
resultBlock, ok := result.(*eth.BeaconBlockBodyAltair)
|
||||
require.Equal(t, true, ok)
|
||||
resultHTR, err := resultBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBody.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
})
|
||||
t.Run("Bellatrix", func(t *testing.T) {
|
||||
expectedBody := bodyPbBellatrix()
|
||||
body := bodyBellatrix()
|
||||
result, err := body.Proto()
|
||||
require.NoError(t, err)
|
||||
resultBlock, ok := result.(*eth.BeaconBlockBodyBellatrix)
|
||||
require.Equal(t, true, ok)
|
||||
resultHTR, err := resultBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBody.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
})
|
||||
t.Run("BellatrixBlind", func(t *testing.T) {
|
||||
expectedBody := bodyPbBlindedBellatrix()
|
||||
body := bodyBlindedBellatrix()
|
||||
result, err := body.Proto()
|
||||
require.NoError(t, err)
|
||||
resultBlock, ok := result.(*eth.BlindedBeaconBlockBodyBellatrix)
|
||||
require.Equal(t, true, ok)
|
||||
resultHTR, err := resultBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBody.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_initSignedBlockFromProtoPhase0(t *testing.T) {
|
||||
f := getFields()
|
||||
expectedBlock := ð.SignedBeaconBlock{
|
||||
Block: ð.BeaconBlock{
|
||||
Slot: 128,
|
||||
ProposerIndex: 128,
|
||||
ParentRoot: f.b32,
|
||||
StateRoot: f.b32,
|
||||
Body: bodyPbPhase0(),
|
||||
},
|
||||
Signature: f.b96,
|
||||
}
|
||||
resultBlock, err := initSignedBlockFromProtoPhase0(expectedBlock)
|
||||
require.NoError(t, err)
|
||||
resultHTR, err := resultBlock.block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBlock.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
assert.DeepEqual(t, expectedBlock.Signature, resultBlock.signature)
|
||||
}
|
||||
|
||||
func Test_initSignedBlockFromProtoAltair(t *testing.T) {
|
||||
f := getFields()
|
||||
expectedBlock := ð.SignedBeaconBlockAltair{
|
||||
Block: ð.BeaconBlockAltair{
|
||||
Slot: 128,
|
||||
ProposerIndex: 128,
|
||||
ParentRoot: f.b32,
|
||||
StateRoot: f.b32,
|
||||
Body: bodyPbAltair(),
|
||||
},
|
||||
Signature: f.b96,
|
||||
}
|
||||
resultBlock, err := initSignedBlockFromProtoAltair(expectedBlock)
|
||||
require.NoError(t, err)
|
||||
resultHTR, err := resultBlock.block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBlock.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
assert.DeepEqual(t, expectedBlock.Signature, resultBlock.signature)
|
||||
}
|
||||
|
||||
func Test_initSignedBlockFromProtoBellatrix(t *testing.T) {
|
||||
f := getFields()
|
||||
expectedBlock := ð.SignedBeaconBlockBellatrix{
|
||||
Block: ð.BeaconBlockBellatrix{
|
||||
Slot: 128,
|
||||
ProposerIndex: 128,
|
||||
ParentRoot: f.b32,
|
||||
StateRoot: f.b32,
|
||||
Body: bodyPbBellatrix(),
|
||||
},
|
||||
Signature: f.b96,
|
||||
}
|
||||
resultBlock, err := initSignedBlockFromProtoBellatrix(expectedBlock)
|
||||
require.NoError(t, err)
|
||||
resultHTR, err := resultBlock.block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBlock.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
assert.DeepEqual(t, expectedBlock.Signature, resultBlock.signature)
|
||||
}
|
||||
|
||||
func Test_initBlindedSignedBlockFromProtoBellatrix(t *testing.T) {
|
||||
f := getFields()
|
||||
expectedBlock := ð.SignedBlindedBeaconBlockBellatrix{
|
||||
Block: ð.BlindedBeaconBlockBellatrix{
|
||||
Slot: 128,
|
||||
ProposerIndex: 128,
|
||||
ParentRoot: f.b32,
|
||||
StateRoot: f.b32,
|
||||
Body: bodyPbBlindedBellatrix(),
|
||||
},
|
||||
Signature: f.b96,
|
||||
}
|
||||
resultBlock, err := initBlindedSignedBlockFromProtoBellatrix(expectedBlock)
|
||||
require.NoError(t, err)
|
||||
resultHTR, err := resultBlock.block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBlock.Block.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
assert.DeepEqual(t, expectedBlock.Signature, resultBlock.signature)
|
||||
}
|
||||
|
||||
func Test_initBlockFromProtoPhase0(t *testing.T) {
|
||||
f := getFields()
|
||||
expectedBlock := ð.BeaconBlock{
|
||||
Slot: 128,
|
||||
ProposerIndex: 128,
|
||||
ParentRoot: f.b32,
|
||||
StateRoot: f.b32,
|
||||
Body: bodyPbPhase0(),
|
||||
}
|
||||
resultBlock, err := initBlockFromProtoPhase0(expectedBlock)
|
||||
require.NoError(t, err)
|
||||
resultHTR, err := resultBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
}
|
||||
|
||||
func Test_initBlockFromProtoAltair(t *testing.T) {
|
||||
f := getFields()
|
||||
expectedBlock := ð.BeaconBlockAltair{
|
||||
Slot: 128,
|
||||
ProposerIndex: 128,
|
||||
ParentRoot: f.b32,
|
||||
StateRoot: f.b32,
|
||||
Body: bodyPbAltair(),
|
||||
}
|
||||
resultBlock, err := initBlockFromProtoAltair(expectedBlock)
|
||||
require.NoError(t, err)
|
||||
resultHTR, err := resultBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
}
|
||||
|
||||
func Test_initBlockFromProtoBellatrix(t *testing.T) {
|
||||
f := getFields()
|
||||
expectedBlock := ð.BeaconBlockBellatrix{
|
||||
Slot: 128,
|
||||
ProposerIndex: 128,
|
||||
ParentRoot: f.b32,
|
||||
StateRoot: f.b32,
|
||||
Body: bodyPbBellatrix(),
|
||||
}
|
||||
resultBlock, err := initBlockFromProtoBellatrix(expectedBlock)
|
||||
require.NoError(t, err)
|
||||
resultHTR, err := resultBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
}
|
||||
|
||||
func Test_initBlockFromProtoBlindedBellatrix(t *testing.T) {
|
||||
f := getFields()
|
||||
expectedBlock := ð.BlindedBeaconBlockBellatrix{
|
||||
Slot: 128,
|
||||
ProposerIndex: 128,
|
||||
ParentRoot: f.b32,
|
||||
StateRoot: f.b32,
|
||||
Body: bodyPbBlindedBellatrix(),
|
||||
}
|
||||
resultBlock, err := initBlindedBlockFromProtoBellatrix(expectedBlock)
|
||||
require.NoError(t, err)
|
||||
resultHTR, err := resultBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBlock.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
}
|
||||
|
||||
func Test_initBlockBodyFromProtoPhase0(t *testing.T) {
|
||||
expectedBody := bodyPbPhase0()
|
||||
resultBody, err := initBlockBodyFromProtoPhase0(expectedBody)
|
||||
require.NoError(t, err)
|
||||
resultHTR, err := resultBody.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBody.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
}
|
||||
|
||||
func Test_initBlockBodyFromProtoAltair(t *testing.T) {
|
||||
expectedBody := bodyPbAltair()
|
||||
resultBody, err := initBlockBodyFromProtoAltair(expectedBody)
|
||||
require.NoError(t, err)
|
||||
resultHTR, err := resultBody.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBody.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
}
|
||||
|
||||
func Test_initBlockBodyFromProtoBellatrix(t *testing.T) {
|
||||
expectedBody := bodyPbBellatrix()
|
||||
resultBody, err := initBlockBodyFromProtoBellatrix(expectedBody)
|
||||
require.NoError(t, err)
|
||||
resultHTR, err := resultBody.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBody.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
}
|
||||
|
||||
func Test_initBlockBodyFromProtoBlindedBellatrix(t *testing.T) {
|
||||
expectedBody := bodyPbBlindedBellatrix()
|
||||
resultBody, err := initBlindedBlockBodyFromProtoBellatrix(expectedBody)
|
||||
require.NoError(t, err)
|
||||
resultHTR, err := resultBody.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
expectedHTR, err := expectedBody.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, expectedHTR, resultHTR)
|
||||
}
|
||||
|
||||
func bodyPbPhase0() *eth.BeaconBlockBody {
|
||||
f := getFields()
|
||||
return ð.BeaconBlockBody{
|
||||
RandaoReveal: f.b96,
|
||||
Eth1Data: ð.Eth1Data{
|
||||
DepositRoot: f.b32,
|
||||
DepositCount: 128,
|
||||
BlockHash: f.b32,
|
||||
},
|
||||
Graffiti: f.b32,
|
||||
ProposerSlashings: f.proposerSlashings,
|
||||
AttesterSlashings: f.attesterSlashings,
|
||||
Attestations: f.atts,
|
||||
Deposits: f.deposits,
|
||||
VoluntaryExits: f.voluntaryExits,
|
||||
}
|
||||
}
|
||||
|
||||
func bodyPbAltair() *eth.BeaconBlockBodyAltair {
|
||||
f := getFields()
|
||||
return ð.BeaconBlockBodyAltair{
|
||||
RandaoReveal: f.b96,
|
||||
Eth1Data: ð.Eth1Data{
|
||||
DepositRoot: f.b32,
|
||||
DepositCount: 128,
|
||||
BlockHash: f.b32,
|
||||
},
|
||||
Graffiti: f.b32,
|
||||
ProposerSlashings: f.proposerSlashings,
|
||||
AttesterSlashings: f.attesterSlashings,
|
||||
Attestations: f.atts,
|
||||
Deposits: f.deposits,
|
||||
VoluntaryExits: f.voluntaryExits,
|
||||
SyncAggregate: f.syncAggregate,
|
||||
}
|
||||
}
|
||||
|
||||
func bodyPbBellatrix() *eth.BeaconBlockBodyBellatrix {
|
||||
f := getFields()
|
||||
return ð.BeaconBlockBodyBellatrix{
|
||||
RandaoReveal: f.b96,
|
||||
Eth1Data: ð.Eth1Data{
|
||||
DepositRoot: f.b32,
|
||||
DepositCount: 128,
|
||||
BlockHash: f.b32,
|
||||
},
|
||||
Graffiti: f.b32,
|
||||
ProposerSlashings: f.proposerSlashings,
|
||||
AttesterSlashings: f.attesterSlashings,
|
||||
Attestations: f.atts,
|
||||
Deposits: f.deposits,
|
||||
VoluntaryExits: f.voluntaryExits,
|
||||
SyncAggregate: f.syncAggregate,
|
||||
ExecutionPayload: f.execPayload,
|
||||
}
|
||||
}
|
||||
|
||||
func bodyPbBlindedBellatrix() *eth.BlindedBeaconBlockBodyBellatrix {
|
||||
f := getFields()
|
||||
return ð.BlindedBeaconBlockBodyBellatrix{
|
||||
RandaoReveal: f.b96,
|
||||
Eth1Data: ð.Eth1Data{
|
||||
DepositRoot: f.b32,
|
||||
DepositCount: 128,
|
||||
BlockHash: f.b32,
|
||||
},
|
||||
Graffiti: f.b32,
|
||||
ProposerSlashings: f.proposerSlashings,
|
||||
AttesterSlashings: f.attesterSlashings,
|
||||
Attestations: f.atts,
|
||||
Deposits: f.deposits,
|
||||
VoluntaryExits: f.voluntaryExits,
|
||||
SyncAggregate: f.syncAggregate,
|
||||
ExecutionPayloadHeader: f.execPayloadHeader,
|
||||
}
|
||||
}
|
||||
|
||||
func bodyPhase0() *BeaconBlockBody {
|
||||
f := getFields()
|
||||
return &BeaconBlockBody{
|
||||
version: version.Phase0,
|
||||
randaoReveal: f.b96,
|
||||
eth1Data: ð.Eth1Data{
|
||||
DepositRoot: f.b32,
|
||||
DepositCount: 128,
|
||||
BlockHash: f.b32,
|
||||
},
|
||||
graffiti: f.b32,
|
||||
proposerSlashings: f.proposerSlashings,
|
||||
attesterSlashings: f.attesterSlashings,
|
||||
attestations: f.atts,
|
||||
deposits: f.deposits,
|
||||
voluntaryExits: f.voluntaryExits,
|
||||
}
|
||||
}
|
||||
|
||||
func bodyAltair() *BeaconBlockBody {
|
||||
f := getFields()
|
||||
return &BeaconBlockBody{
|
||||
version: version.Altair,
|
||||
randaoReveal: f.b96,
|
||||
eth1Data: ð.Eth1Data{
|
||||
DepositRoot: f.b32,
|
||||
DepositCount: 128,
|
||||
BlockHash: f.b32,
|
||||
},
|
||||
graffiti: f.b32,
|
||||
proposerSlashings: f.proposerSlashings,
|
||||
attesterSlashings: f.attesterSlashings,
|
||||
attestations: f.atts,
|
||||
deposits: f.deposits,
|
||||
voluntaryExits: f.voluntaryExits,
|
||||
syncAggregate: f.syncAggregate,
|
||||
}
|
||||
}
|
||||
|
||||
func bodyBellatrix() *BeaconBlockBody {
|
||||
f := getFields()
|
||||
return &BeaconBlockBody{
|
||||
version: version.Bellatrix,
|
||||
randaoReveal: f.b96,
|
||||
eth1Data: ð.Eth1Data{
|
||||
DepositRoot: f.b32,
|
||||
DepositCount: 128,
|
||||
BlockHash: f.b32,
|
||||
},
|
||||
graffiti: f.b32,
|
||||
proposerSlashings: f.proposerSlashings,
|
||||
attesterSlashings: f.attesterSlashings,
|
||||
attestations: f.atts,
|
||||
deposits: f.deposits,
|
||||
voluntaryExits: f.voluntaryExits,
|
||||
syncAggregate: f.syncAggregate,
|
||||
executionPayload: f.execPayload,
|
||||
}
|
||||
}
|
||||
|
||||
func bodyBlindedBellatrix() *BeaconBlockBody {
|
||||
f := getFields()
|
||||
return &BeaconBlockBody{
|
||||
version: version.BellatrixBlind,
|
||||
randaoReveal: f.b96,
|
||||
eth1Data: ð.Eth1Data{
|
||||
DepositRoot: f.b32,
|
||||
DepositCount: 128,
|
||||
BlockHash: f.b32,
|
||||
},
|
||||
graffiti: f.b32,
|
||||
proposerSlashings: f.proposerSlashings,
|
||||
attesterSlashings: f.attesterSlashings,
|
||||
attestations: f.atts,
|
||||
deposits: f.deposits,
|
||||
voluntaryExits: f.voluntaryExits,
|
||||
syncAggregate: f.syncAggregate,
|
||||
executionPayloadHeader: f.execPayloadHeader,
|
||||
}
|
||||
}
|
||||
|
||||
func getFields() fields {
|
||||
b20 := make([]byte, 20)
|
||||
b32 := make([]byte, 32)
|
||||
b48 := make([]byte, 48)
|
||||
b96 := make([]byte, 96)
|
||||
b256 := make([]byte, 256)
|
||||
b20[0], b20[5], b20[10] = 'q', 'u', 'x'
|
||||
b32[0], b32[5], b32[10] = 'f', 'o', 'o'
|
||||
b48[0], b48[5], b48[10] = 'b', 'a', 'r'
|
||||
b96[0], b96[5], b96[10] = 'b', 'a', 'z'
|
||||
b256[0], b256[5], b256[10] = 'x', 'y', 'z'
|
||||
deposits := make([]*eth.Deposit, 16)
|
||||
for i := range deposits {
|
||||
deposits[i] = ð.Deposit{}
|
||||
deposits[i].Proof = make([][]byte, 33)
|
||||
for j := range deposits[i].Proof {
|
||||
deposits[i].Proof[j] = b32
|
||||
}
|
||||
deposits[i].Data = ð.Deposit_Data{
|
||||
PublicKey: b48,
|
||||
WithdrawalCredentials: b32,
|
||||
Amount: 128,
|
||||
Signature: b96,
|
||||
}
|
||||
}
|
||||
atts := make([]*eth.Attestation, 128)
|
||||
for i := range atts {
|
||||
atts[i] = ð.Attestation{}
|
||||
atts[i].Signature = b96
|
||||
atts[i].AggregationBits = bitfield.NewBitlist(1)
|
||||
atts[i].Data = ð.AttestationData{
|
||||
Slot: 128,
|
||||
CommitteeIndex: 128,
|
||||
BeaconBlockRoot: b32,
|
||||
Source: ð.Checkpoint{
|
||||
Epoch: 128,
|
||||
Root: b32,
|
||||
},
|
||||
Target: ð.Checkpoint{
|
||||
Epoch: 128,
|
||||
Root: b32,
|
||||
},
|
||||
}
|
||||
}
|
||||
proposerSlashing := ð.ProposerSlashing{
|
||||
Header_1: ð.SignedBeaconBlockHeader{
|
||||
Header: ð.BeaconBlockHeader{
|
||||
Slot: 128,
|
||||
ProposerIndex: 128,
|
||||
ParentRoot: b32,
|
||||
StateRoot: b32,
|
||||
BodyRoot: b32,
|
||||
},
|
||||
Signature: b96,
|
||||
},
|
||||
Header_2: ð.SignedBeaconBlockHeader{
|
||||
Header: ð.BeaconBlockHeader{
|
||||
Slot: 128,
|
||||
ProposerIndex: 128,
|
||||
ParentRoot: b32,
|
||||
StateRoot: b32,
|
||||
BodyRoot: b32,
|
||||
},
|
||||
Signature: b96,
|
||||
},
|
||||
}
|
||||
attesterSlashing := ð.AttesterSlashing{
|
||||
Attestation_1: ð.IndexedAttestation{
|
||||
AttestingIndices: []uint64{1, 2, 8},
|
||||
Data: ð.AttestationData{
|
||||
Slot: 128,
|
||||
CommitteeIndex: 128,
|
||||
BeaconBlockRoot: b32,
|
||||
Source: ð.Checkpoint{
|
||||
Epoch: 128,
|
||||
Root: b32,
|
||||
},
|
||||
Target: ð.Checkpoint{
|
||||
Epoch: 128,
|
||||
Root: b32,
|
||||
},
|
||||
},
|
||||
Signature: b96,
|
||||
},
|
||||
Attestation_2: ð.IndexedAttestation{
|
||||
AttestingIndices: []uint64{1, 2, 8},
|
||||
Data: ð.AttestationData{
|
||||
Slot: 128,
|
||||
CommitteeIndex: 128,
|
||||
BeaconBlockRoot: b32,
|
||||
Source: ð.Checkpoint{
|
||||
Epoch: 128,
|
||||
Root: b32,
|
||||
},
|
||||
Target: ð.Checkpoint{
|
||||
Epoch: 128,
|
||||
Root: b32,
|
||||
},
|
||||
},
|
||||
Signature: b96,
|
||||
},
|
||||
}
|
||||
voluntaryExit := ð.SignedVoluntaryExit{
|
||||
Exit: ð.VoluntaryExit{
|
||||
Epoch: 128,
|
||||
ValidatorIndex: 128,
|
||||
},
|
||||
Signature: b96,
|
||||
}
|
||||
syncCommitteeBits := bitfield.NewBitvector512()
|
||||
syncCommitteeBits.SetBitAt(1, true)
|
||||
syncCommitteeBits.SetBitAt(2, true)
|
||||
syncCommitteeBits.SetBitAt(8, true)
|
||||
syncAggregate := ð.SyncAggregate{
|
||||
SyncCommitteeBits: syncCommitteeBits,
|
||||
SyncCommitteeSignature: b96,
|
||||
}
|
||||
execPayload := &enginev1.ExecutionPayload{
|
||||
ParentHash: b32,
|
||||
FeeRecipient: b20,
|
||||
StateRoot: b32,
|
||||
ReceiptsRoot: b32,
|
||||
LogsBloom: b256,
|
||||
PrevRandao: b32,
|
||||
BlockNumber: 128,
|
||||
GasLimit: 128,
|
||||
GasUsed: 128,
|
||||
Timestamp: 128,
|
||||
ExtraData: b32,
|
||||
BaseFeePerGas: b32,
|
||||
BlockHash: b32,
|
||||
Transactions: [][]byte{
|
||||
[]byte("transaction1"),
|
||||
[]byte("transaction2"),
|
||||
[]byte("transaction8"),
|
||||
},
|
||||
}
|
||||
execPayloadHeader := ð.ExecutionPayloadHeader{
|
||||
ParentHash: b32,
|
||||
FeeRecipient: b20,
|
||||
StateRoot: b32,
|
||||
ReceiptsRoot: b32,
|
||||
LogsBloom: b256,
|
||||
PrevRandao: b32,
|
||||
BlockNumber: 128,
|
||||
GasLimit: 128,
|
||||
GasUsed: 128,
|
||||
Timestamp: 128,
|
||||
ExtraData: b32,
|
||||
BaseFeePerGas: b32,
|
||||
BlockHash: b32,
|
||||
TransactionsRoot: b32,
|
||||
}
|
||||
|
||||
return fields{
|
||||
b20: b20,
|
||||
b32: b32,
|
||||
b48: b48,
|
||||
b96: b96,
|
||||
b256: b256,
|
||||
deposits: deposits,
|
||||
atts: atts,
|
||||
proposerSlashings: []*eth.ProposerSlashing{proposerSlashing},
|
||||
attesterSlashings: []*eth.AttesterSlashing{attesterSlashing},
|
||||
voluntaryExits: []*eth.SignedVoluntaryExit{voluntaryExit},
|
||||
syncAggregate: syncAggregate,
|
||||
execPayload: execPayload,
|
||||
execPayloadHeader: execPayloadHeader,
|
||||
}
|
||||
}
|
||||
20
consensus-types/blocks/testing/BUILD.bazel
Normal file
20
consensus-types/blocks/testing/BUILD.bazel
Normal file
@@ -0,0 +1,20 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
testonly = True,
|
||||
srcs = [
|
||||
"factory.go",
|
||||
"mutator.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/consensus-types/blocks/testing",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
],
|
||||
)
|
||||
27
consensus-types/blocks/testing/factory.go
Normal file
27
consensus-types/blocks/testing/factory.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package testing
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/consensus-types/blocks"
|
||||
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
// NewSignedBeaconBlockFromGeneric creates a signed beacon block
|
||||
// from a protobuf generic signed beacon block.
|
||||
func NewSignedBeaconBlockFromGeneric(gb *eth.GenericSignedBeaconBlock) (*blocks.SignedBeaconBlock, error) {
|
||||
if gb == nil {
|
||||
return nil, blocks.ErrNilObjectWrapped
|
||||
}
|
||||
switch bb := gb.Block.(type) {
|
||||
case *eth.GenericSignedBeaconBlock_Phase0:
|
||||
return blocks.NewSignedBeaconBlock(bb.Phase0)
|
||||
case *eth.GenericSignedBeaconBlock_Altair:
|
||||
return blocks.NewSignedBeaconBlock(bb.Altair)
|
||||
case *eth.GenericSignedBeaconBlock_Bellatrix:
|
||||
return blocks.NewSignedBeaconBlock(bb.Bellatrix)
|
||||
case *eth.GenericSignedBeaconBlock_BlindedBellatrix:
|
||||
return blocks.NewSignedBeaconBlock(bb.BlindedBellatrix)
|
||||
default:
|
||||
return nil, errors.Wrapf(blocks.ErrUnsupportedSignedBeaconBlock, "unable to create block from type %T", gb)
|
||||
}
|
||||
}
|
||||
79
consensus-types/blocks/testing/mutator.go
Normal file
79
consensus-types/blocks/testing/mutator.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package testing
|
||||
|
||||
import (
|
||||
"github.com/prysmaticlabs/prysm/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/consensus-types/interfaces"
|
||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||
)
|
||||
|
||||
type blockMutator struct {
|
||||
Phase0 func(beaconBlock *eth.SignedBeaconBlock)
|
||||
Altair func(beaconBlock *eth.SignedBeaconBlockAltair)
|
||||
Bellatrix func(beaconBlock *eth.SignedBeaconBlockBellatrix)
|
||||
}
|
||||
|
||||
func (m blockMutator) apply(b interfaces.SignedBeaconBlock) error {
|
||||
switch b.Version() {
|
||||
case version.Phase0:
|
||||
bb, err := b.PbPhase0Block()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Phase0(bb)
|
||||
return nil
|
||||
case version.Altair:
|
||||
bb, err := b.PbAltairBlock()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Altair(bb)
|
||||
return nil
|
||||
case version.Bellatrix:
|
||||
bb, err := b.PbBellatrixBlock()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Bellatrix(bb)
|
||||
return nil
|
||||
default:
|
||||
return blocks.ErrUnsupportedSignedBeaconBlock
|
||||
}
|
||||
}
|
||||
|
||||
// SetBlockStateRoot modifies the block's state root.
|
||||
func SetBlockStateRoot(b interfaces.SignedBeaconBlock, sr [32]byte) error {
|
||||
return blockMutator{
|
||||
Phase0: func(bb *eth.SignedBeaconBlock) { bb.Block.StateRoot = sr[:] },
|
||||
Altair: func(bb *eth.SignedBeaconBlockAltair) { bb.Block.StateRoot = sr[:] },
|
||||
Bellatrix: func(bb *eth.SignedBeaconBlockBellatrix) { bb.Block.StateRoot = sr[:] },
|
||||
}.apply(b)
|
||||
}
|
||||
|
||||
// SetBlockParentRoot modifies the block's parent root.
|
||||
func SetBlockParentRoot(b interfaces.SignedBeaconBlock, pr [32]byte) error {
|
||||
return blockMutator{
|
||||
Phase0: func(bb *eth.SignedBeaconBlock) { bb.Block.ParentRoot = pr[:] },
|
||||
Altair: func(bb *eth.SignedBeaconBlockAltair) { bb.Block.ParentRoot = pr[:] },
|
||||
Bellatrix: func(bb *eth.SignedBeaconBlockBellatrix) { bb.Block.ParentRoot = pr[:] },
|
||||
}.apply(b)
|
||||
}
|
||||
|
||||
// SetBlockSlot modifies the block's slot.
|
||||
func SetBlockSlot(b interfaces.SignedBeaconBlock, s types.Slot) error {
|
||||
return blockMutator{
|
||||
Phase0: func(bb *eth.SignedBeaconBlock) { bb.Block.Slot = s },
|
||||
Altair: func(bb *eth.SignedBeaconBlockAltair) { bb.Block.Slot = s },
|
||||
Bellatrix: func(bb *eth.SignedBeaconBlockBellatrix) { bb.Block.Slot = s },
|
||||
}.apply(b)
|
||||
}
|
||||
|
||||
// SetProposerIndex modifies the block's proposer index.
|
||||
func SetProposerIndex(b interfaces.SignedBeaconBlock, idx types.ValidatorIndex) error {
|
||||
return blockMutator{
|
||||
Phase0: func(bb *eth.SignedBeaconBlock) { bb.Block.ProposerIndex = idx },
|
||||
Altair: func(bb *eth.SignedBeaconBlockAltair) { bb.Block.ProposerIndex = idx },
|
||||
Bellatrix: func(bb *eth.SignedBeaconBlockBellatrix) { bb.Block.ProposerIndex = idx },
|
||||
}.apply(b)
|
||||
}
|
||||
62
consensus-types/blocks/types.go
Normal file
62
consensus-types/blocks/types.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package blocks
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
types "github.com/prysmaticlabs/prysm/consensus-types/primitives"
|
||||
engine "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
||||
eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/runtime/version"
|
||||
)
|
||||
|
||||
const (
|
||||
incorrectBlockVersion = "incorrect beacon block version"
|
||||
incorrectBodyVersion = "incorrect beacon block body version"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrUnsupportedGetter is returned when a getter access is not supported for a specific beacon block version.
|
||||
ErrUnsupportedGetter = errors.New("unsupported getter")
|
||||
errNilBlock = errors.New("received nil beacon block")
|
||||
errNilBody = errors.New("received nil beacon block body")
|
||||
errIncorrectBlockVersion = errors.New(incorrectBlockVersion)
|
||||
errIncorrectBodyVersion = errors.New(incorrectBodyVersion)
|
||||
)
|
||||
|
||||
// BeaconBlockBody is the main beacon block body structure. It can represent any block type.
|
||||
type BeaconBlockBody struct {
|
||||
version int
|
||||
randaoReveal []byte
|
||||
eth1Data *eth.Eth1Data
|
||||
graffiti []byte
|
||||
proposerSlashings []*eth.ProposerSlashing
|
||||
attesterSlashings []*eth.AttesterSlashing
|
||||
attestations []*eth.Attestation
|
||||
deposits []*eth.Deposit
|
||||
voluntaryExits []*eth.SignedVoluntaryExit
|
||||
syncAggregate *eth.SyncAggregate
|
||||
executionPayload *engine.ExecutionPayload
|
||||
executionPayloadHeader *eth.ExecutionPayloadHeader
|
||||
}
|
||||
|
||||
// BeaconBlock is the main beacon block structure. It can represent any block type.
|
||||
type BeaconBlock struct {
|
||||
version int
|
||||
slot types.Slot
|
||||
proposerIndex types.ValidatorIndex
|
||||
parentRoot []byte
|
||||
stateRoot []byte
|
||||
body *BeaconBlockBody
|
||||
}
|
||||
|
||||
// SignedBeaconBlock is the main signed beacon block structure. It can represent any block type.
|
||||
type SignedBeaconBlock struct {
|
||||
version int
|
||||
block *BeaconBlock
|
||||
signature []byte
|
||||
}
|
||||
|
||||
func errNotSupported(funcName string, ver int) error {
|
||||
return errors.Wrap(ErrUnsupportedGetter, fmt.Sprintf("%s is not supported for %s", funcName, version.String(ver)))
|
||||
}
|
||||
1
go.mod
1
go.mod
@@ -9,6 +9,7 @@ require (
|
||||
github.com/aristanetworks/goarista v0.0.0-20200805130819-fd197cf57d96
|
||||
github.com/bazelbuild/rules_go v0.23.2
|
||||
github.com/d4l3k/messagediff v1.2.1
|
||||
github.com/dave/jennifer v1.2.0
|
||||
github.com/dgraph-io/ristretto v0.0.4-0.20210318174700-74754f61e018
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/emicklei/dot v0.11.0
|
||||
|
||||
1
go.sum
1
go.sum
@@ -235,6 +235,7 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
|
||||
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
|
||||
github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U=
|
||||
github.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo=
|
||||
github.com/dave/jennifer v1.2.0 h1:S15ZkFMRoJ36mGAQgWL1tnr0NQJh9rZ8qatseX/VbBc=
|
||||
github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
|
||||
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
||||
@@ -31,14 +31,7 @@ func (e Endpoint) HttpClient() *http.Client {
|
||||
if e.Auth.Method != authorization.Bearer {
|
||||
return http.DefaultClient
|
||||
}
|
||||
authTransport := &jwtTransport{
|
||||
underlyingTransport: http.DefaultTransport,
|
||||
jwtSecret: []byte(e.Auth.Value),
|
||||
}
|
||||
return &http.Client{
|
||||
Timeout: DefaultRPCHTTPTimeout,
|
||||
Transport: authTransport,
|
||||
}
|
||||
return NewHttpClientWithSecret(e.Auth.Value)
|
||||
}
|
||||
|
||||
// Equals compares two authorization data objects for equality.
|
||||
@@ -70,3 +63,16 @@ func Method(auth string) authorization.AuthorizationMethod {
|
||||
}
|
||||
return authorization.None
|
||||
}
|
||||
|
||||
// NewHttpClientWithSecret returns a http client that utilizes
|
||||
// jwt authentication.
|
||||
func NewHttpClientWithSecret(secret string) *http.Client {
|
||||
authTransport := &jwtTransport{
|
||||
underlyingTransport: http.DefaultTransport,
|
||||
jwtSecret: []byte(secret),
|
||||
}
|
||||
return &http.Client{
|
||||
Timeout: DefaultRPCHTTPTimeout,
|
||||
Transport: authTransport,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ ssz_gen_marshal(
|
||||
"BeaconBlockHeader",
|
||||
"Checkpoint",
|
||||
"Deposit",
|
||||
"DepositData",
|
||||
"Eth1Data",
|
||||
"IndexedAttestation",
|
||||
"ProposerSlashing",
|
||||
@@ -92,7 +91,8 @@ go_proto_library(
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
":ssz_generated_files",
|
||||
":ssz_generated_files", # keep
|
||||
"methodical.ssz.go",
|
||||
],
|
||||
embed = [
|
||||
":go_grpc_gateway_library",
|
||||
|
||||
2940
proto/eth/v1/methodical.ssz.go
Normal file
2940
proto/eth/v1/methodical.ssz.go
Normal file
File diff suppressed because it is too large
Load Diff
@@ -165,6 +165,7 @@ go_library(
|
||||
"sync_committee_mainnet.go",
|
||||
"sync_committee_minimal.go", # keep
|
||||
":ssz_generated_files", # keep
|
||||
"methodical.ssz.go",
|
||||
],
|
||||
embed = [
|
||||
":go_grpc_gateway_library",
|
||||
|
||||
1559
proto/prysm/v1alpha1/beacon_chain.pb.go
generated
1559
proto/prysm/v1alpha1/beacon_chain.pb.go
generated
File diff suppressed because it is too large
Load Diff
@@ -474,6 +474,9 @@ message ChainHead {
|
||||
|
||||
// Previous 32 byte justified block root.
|
||||
bytes previous_justified_block_root = 12 [(ethereum.eth.ext.ssz_size) = "32"];
|
||||
|
||||
// Optimistic status of the current head
|
||||
bool optimistic_status = 13;
|
||||
}
|
||||
|
||||
message ListCommitteesRequest {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// Code generated by fastssz. DO NOT EDIT.
|
||||
|
||||
// Hash: 926169eadd07a1db289a5e8416388f330cfb302b03fb1a1590af7fc8f52db228
|
||||
|
||||
package eth
|
||||
|
||||
import (
|
||||
|
||||
1
spectest/shared/altair/ssz_static/BUILD.bazel
Normal file
1
spectest/shared/altair/ssz_static/BUILD.bazel
Normal file
@@ -0,0 +1 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library")
|
||||
44
spectest/shared/phase0/ssz_static/sszstatic_test.go
Normal file
44
spectest/shared/phase0/ssz_static/sszstatic_test.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package ssz_static
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/snappy"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
||||
|
||||
//"github.com/prysmaticlabs/prysm/shared/testutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
||||
"github.com/prysmaticlabs/prysm/spectest/utils"
|
||||
)
|
||||
|
||||
func TestFailingHTR(t *testing.T) {
|
||||
fh, err := os.Open("testdata/serialized.ssz_snappy")
|
||||
require.NoError(t, err)
|
||||
defer fh.Close()
|
||||
buf := bytes.NewBuffer(nil)
|
||||
_, err = buf.ReadFrom(fh)
|
||||
sszBytes, err := snappy.Decode(nil, buf.Bytes())
|
||||
require.NoError(t, err)
|
||||
o := ðpb.AggregateAttestationAndProof{}
|
||||
err = o.XXUnmarshalSSZ(sszBytes)
|
||||
err = o.UnmarshalSSZ(sszBytes)
|
||||
require.NoError(t, err, "Could not unmarshall serialized SSZ")
|
||||
|
||||
fh, err = os.Open("testdata/roots.yaml")
|
||||
require.NoError(t, err)
|
||||
defer fh.Close()
|
||||
buf = bytes.NewBuffer(nil)
|
||||
buf.ReadFrom(fh)
|
||||
rootsYaml := &SSZRoots{}
|
||||
require.NoError(t, utils.UnmarshalYaml(buf.Bytes(), rootsYaml))
|
||||
|
||||
root, err := o.HashTreeRoot()
|
||||
require.NoError(t, err)
|
||||
|
||||
rootBytes, err := hex.DecodeString(rootsYaml.Root[2:])
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, rootBytes, root[:], "Did not receive expected hash tree root")
|
||||
}
|
||||
32
sszgen/BUILD.bazel
Normal file
32
sszgen/BUILD.bazel
Normal file
@@ -0,0 +1,32 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"indexer.go",
|
||||
"parser.go",
|
||||
"representer.go",
|
||||
"tagparse.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/sszgen",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//sszgen/types:go_default_library",
|
||||
"@org_golang_x_tools//go/packages:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"indexer_test.go",
|
||||
"parser_test.go",
|
||||
"representer_test.go",
|
||||
"tagparse_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//shared/testutil/require:go_default_library",
|
||||
"//sszgen/types:go_default_library",
|
||||
],
|
||||
)
|
||||
46
sszgen/backend/BUILD.bazel
Normal file
46
sszgen/backend/BUILD.bazel
Normal file
@@ -0,0 +1,46 @@
|
||||
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"bool.go",
|
||||
"byte.go",
|
||||
"caster.go",
|
||||
"container.go",
|
||||
"genhtr.go",
|
||||
"genmarshal.go",
|
||||
"gensize.go",
|
||||
"genunmarshal.go",
|
||||
"list.go",
|
||||
"overlay.go",
|
||||
"pointer.go",
|
||||
"render.go",
|
||||
"uint.go",
|
||||
"union.go",
|
||||
"vector.go",
|
||||
"visitor.go",
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/sszgen/backend",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//sszgen/types:go_default_library"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"container_test.go",
|
||||
"genhtr_test.go",
|
||||
"genmarshal_test.go",
|
||||
"gensize_test.go",
|
||||
"genunmarshal_test.go",
|
||||
"render_test.go",
|
||||
],
|
||||
data = glob(["testdata/**"]),
|
||||
embed = [":go_default_library"],
|
||||
# dummy importpath to unbreak debugging
|
||||
importpath = "github.com/prysmaticlabs/prysm/sszgen/backend/tests-dummy",
|
||||
deps = [
|
||||
"//shared/testutil/require:go_default_library",
|
||||
"//sszgen/types:go_default_library",
|
||||
],
|
||||
)
|
||||
37
sszgen/backend/bool.go
Normal file
37
sszgen/backend/bool.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package backend
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/prysmaticlabs/prysm/sszgen/types"
|
||||
)
|
||||
|
||||
type generateBool struct {
|
||||
valRep *types.ValueBool
|
||||
targetPackage string
|
||||
casterConfig
|
||||
}
|
||||
|
||||
func (g *generateBool) generateHTRPutter(fieldName string) string {
|
||||
return fmt.Sprintf("hh.PutBool(%s)", fieldName)
|
||||
}
|
||||
|
||||
func (g *generateBool) coerce() func(string) string {
|
||||
return func(fieldName string) string {
|
||||
return fmt.Sprintf("%s(%s)", g.valRep.TypeName(), fieldName)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *generateBool) generateFixedMarshalValue(fieldName string) string {
|
||||
return fmt.Sprintf("dst = ssz.MarshalBool(dst, %s)", fieldName)
|
||||
}
|
||||
|
||||
func (g *generateBool) generateUnmarshalValue(fieldName string, offset string) string {
|
||||
convert := fmt.Sprintf("ssz.UnmarshalBool(%s)", offset)
|
||||
return fmt.Sprintf("%s = %s", fieldName, g.casterConfig.toOverlay(convert))
|
||||
}
|
||||
|
||||
func (g *generateBool) variableSizeSSZ(fieldname string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
var _ valueGenerator = &generateBool{}
|
||||
36
sszgen/backend/byte.go
Normal file
36
sszgen/backend/byte.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package backend
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/sszgen/types"
|
||||
)
|
||||
|
||||
type generateByte struct {
|
||||
*types.ValueByte
|
||||
targetPackage string
|
||||
}
|
||||
|
||||
func (g *generateByte) generateHTRPutter(fieldName string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (g *generateByte) coerce() func(string) string {
|
||||
return func(fieldName string) string {
|
||||
return fmt.Sprintf("%s(%s)", g.TypeName(), fieldName)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *generateByte) generateFixedMarshalValue(fieldName string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (g *generateByte) generateUnmarshalValue(fieldName string, s string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (g *generateByte) variableSizeSSZ(fieldname string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
var _ valueGenerator = &generateByte{}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user