Sync with develop

This commit is contained in:
terence tsao
2021-05-26 10:44:10 -07:00
259 changed files with 3232 additions and 1751 deletions

View File

@@ -120,6 +120,7 @@ nogo(
"//tools/analyzers/shadowpredecl:go_tool_library",
"//tools/analyzers/nop:go_tool_library",
"//tools/analyzers/slicedirect:go_tool_library",
"//tools/analyzers/interfacechecker:go_tool_library",
"//tools/analyzers/ineffassign:go_tool_library",
"//tools/analyzers/properpermissions:go_tool_library",
] + select({

View File

@@ -346,33 +346,6 @@ http_archive(
# External dependencies
http_archive(
name = "sszgen", # Hack because we don't want to build this binary with libfuzzer, but need it to build.
build_file_content = """
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_binary")
go_library(
name = "go_default_library",
srcs = [
"sszgen/main.go",
"sszgen/marshal.go",
"sszgen/size.go",
"sszgen/unmarshal.go",
],
importpath = "github.com/ferranbt/fastssz/sszgen",
visibility = ["//visibility:private"],
)
go_binary(
name = "sszgen",
embed = [":go_default_library"],
visibility = ["//visibility:public"],
)
""",
strip_prefix = "fastssz-06015a5d84f9e4eefe2c21377ca678fa8f1a1b09",
urls = ["https://github.com/ferranbt/fastssz/archive/06015a5d84f9e4eefe2c21377ca678fa8f1a1b09.tar.gz"],
)
http_archive(
name = "prysm_web_ui",
build_file_content = """

View File

@@ -42,14 +42,15 @@ go_library(
"//beacon-chain/p2p:go_default_library",
"//beacon-chain/powchain:go_default_library",
"//beacon-chain/state/interface:go_default_library",
"//beacon-chain/state/stateV0:go_default_library",
"//beacon-chain/state/stategen:go_default_library",
"//cmd/beacon-chain/flags:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/attestationutil:go_default_library",
"//shared/blockutil:go_default_library",
"//shared/bls:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/featureconfig:go_default_library",
"//shared/interfaces:go_default_library",
"//shared/mputil:go_default_library",
"//shared/params:go_default_library",
"//shared/slotutil:go_default_library",
@@ -104,6 +105,7 @@ go_test(
"//beacon-chain/db/testing:go_default_library",
"//beacon-chain/p2p:go_default_library",
"//beacon-chain/powchain:go_default_library",
"//beacon-chain/state/stateV0:go_default_library",
"//beacon-chain/state/stateutil:go_default_library",
"//proto/beacon/db:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",

View File

@@ -9,9 +9,10 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/blockutil"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"go.opencensus.io/trace"
)
@@ -41,7 +42,7 @@ type GenesisFetcher interface {
type HeadFetcher interface {
HeadSlot() types.Slot
HeadRoot(ctx context.Context) ([]byte, error)
HeadBlock(ctx context.Context) (*ethpb.SignedBeaconBlock, error)
HeadBlock(ctx context.Context) (interfaces.SignedBeaconBlock, error)
HeadState(ctx context.Context) (iface.BeaconState, error)
HeadValidatorsIndices(ctx context.Context, epoch types.Epoch) ([]types.ValidatorIndex, error)
HeadSeed(ctx context.Context, epoch types.Epoch) ([32]byte, error)
@@ -76,7 +77,7 @@ func (s *Service) FinalizedCheckpt() *ethpb.Checkpoint {
return &ethpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}
}
return stateV0.CopyCheckpoint(s.finalizedCheckpt)
return blockutil.CopyCheckpoint(s.finalizedCheckpt)
}
// CurrentJustifiedCheckpt returns the current justified checkpoint from head state.
@@ -85,7 +86,7 @@ func (s *Service) CurrentJustifiedCheckpt() *ethpb.Checkpoint {
return &ethpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}
}
return stateV0.CopyCheckpoint(s.justifiedCheckpt)
return blockutil.CopyCheckpoint(s.justifiedCheckpt)
}
// PreviousJustifiedCheckpt returns the previous justified checkpoint from head state.
@@ -94,7 +95,7 @@ func (s *Service) PreviousJustifiedCheckpt() *ethpb.Checkpoint {
return &ethpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}
}
return stateV0.CopyCheckpoint(s.prevJustifiedCheckpt)
return blockutil.CopyCheckpoint(s.prevJustifiedCheckpt)
}
// HeadSlot returns the slot of the head of the chain.
@@ -123,11 +124,11 @@ func (s *Service) HeadRoot(ctx context.Context) ([]byte, error) {
if err != nil {
return nil, err
}
if b == nil {
if b == nil || b.IsNil() {
return params.BeaconConfig().ZeroHash[:], nil
}
r, err := b.Block.HashTreeRoot()
r, err := b.Block().HashTreeRoot()
if err != nil {
return nil, err
}
@@ -138,7 +139,7 @@ func (s *Service) HeadRoot(ctx context.Context) ([]byte, error) {
// HeadBlock returns the head block of the chain.
// If the head is nil from service struct,
// it will attempt to get the head block from DB.
func (s *Service) HeadBlock(ctx context.Context) (*ethpb.SignedBeaconBlock, error) {
func (s *Service) HeadBlock(ctx context.Context) (interfaces.SignedBeaconBlock, error) {
s.headLock.RLock()
defer s.headLock.RUnlock()

View File

@@ -7,6 +7,7 @@ import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
@@ -38,7 +39,7 @@ func TestHeadBlock_DataRace(t *testing.T) {
beaconDB := testDB.SetupDB(t)
s := &Service{
cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
head: &head{block: &ethpb.SignedBeaconBlock{}},
head: &head{block: interfaces.NewWrappedSignedBeaconBlock(&ethpb.SignedBeaconBlock{})},
}
go func() {
require.NoError(t, s.saveHead(context.Background(), [32]byte{}))

View File

@@ -13,6 +13,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -125,7 +126,7 @@ func TestHeadRoot_UseDB(t *testing.T) {
b := testutil.NewBeaconBlock()
br, err := b.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, beaconDB.SaveBlock(context.Background(), b))
require.NoError(t, beaconDB.SaveBlock(context.Background(), interfaces.NewWrappedSignedBeaconBlock(b)))
require.NoError(t, beaconDB.SaveStateSummary(context.Background(), &pb.StateSummary{Root: br[:]}))
require.NoError(t, beaconDB.SaveHeadBlockRoot(context.Background(), br))
r, err := c.HeadRoot(context.Background())
@@ -139,11 +140,11 @@ func TestHeadBlock_CanRetrieve(t *testing.T) {
s, err := stateV0.InitializeFromProto(&pb.BeaconState{})
require.NoError(t, err)
c := &Service{}
c.head = &head{block: b, state: s}
c.head = &head{block: interfaces.NewWrappedSignedBeaconBlock(b), state: s}
recevied, err := c.HeadBlock(context.Background())
require.NoError(t, err)
assert.DeepEqual(t, b, recevied, "Incorrect head block received")
assert.DeepEqual(t, b, recevied.Proto(), "Incorrect head block received")
}
func TestHeadState_CanRetrieve(t *testing.T) {
@@ -221,7 +222,7 @@ func TestIsCanonical_Ok(t *testing.T) {
blk.Block.Slot = 0
root, err := blk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, beaconDB.SaveBlock(ctx, blk))
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(blk)))
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, root))
can, err := c.IsCanonical(ctx, root)
require.NoError(t, err)

View File

@@ -7,14 +7,13 @@ import (
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
@@ -22,10 +21,10 @@ import (
// This defines the current chain service's view of head.
type head struct {
slot types.Slot // current head slot.
root [32]byte // current head root.
block *ethpb.SignedBeaconBlock // current head block.
state iface.BeaconState // current head state.
slot types.Slot // current head slot.
root [32]byte // current head root.
block interfaces.SignedBeaconBlock // current head block.
state iface.BeaconState // current head state.
}
// Determined the head from the fork choice service and saves its new data
@@ -64,7 +63,7 @@ func (s *Service) updateHead(ctx context.Context, balances []uint64) error {
return err
}
s.cfg.ForkChoiceStore = protoarray.New(j.Epoch, f.Epoch, bytesutil.ToBytes32(f.Root))
if err := s.insertBlockToForkChoiceStore(ctx, jb.Block, headStartRoot, f, j); err != nil {
if err := s.insertBlockToForkChoiceStore(ctx, jb.Block(), headStartRoot, f, j); err != nil {
return err
}
}
@@ -104,7 +103,7 @@ func (s *Service) saveHead(ctx context.Context, headRoot [32]byte) error {
if err != nil {
return err
}
if newHeadBlock == nil || newHeadBlock.Block == nil {
if newHeadBlock == nil || newHeadBlock.IsNil() || newHeadBlock.Block().IsNil() {
return errors.New("cannot save nil head block")
}
@@ -113,21 +112,21 @@ func (s *Service) saveHead(ctx context.Context, headRoot [32]byte) error {
if err != nil {
return errors.Wrap(err, "could not retrieve head state in DB")
}
if newHeadState == nil {
if newHeadState == nil || newHeadState.IsNil() {
return errors.New("cannot save nil head state")
}
// A chain re-org occurred, so we fire an event notifying the rest of the services.
headSlot := s.HeadSlot()
if bytesutil.ToBytes32(newHeadBlock.Block.ParentRoot) != bytesutil.ToBytes32(r) {
if bytesutil.ToBytes32(newHeadBlock.Block().ParentRoot()) != bytesutil.ToBytes32(r) {
log.WithFields(logrus.Fields{
"newSlot": fmt.Sprintf("%d", newHeadBlock.Block.Slot),
"newSlot": fmt.Sprintf("%d", newHeadBlock.Block().Slot()),
"oldSlot": fmt.Sprintf("%d", headSlot),
}).Debug("Chain reorg occurred")
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.Reorg,
Data: &statefeed.ReorgData{
NewSlot: newHeadBlock.Block.Slot,
NewSlot: newHeadBlock.Block().Slot(),
OldSlot: headSlot,
},
})
@@ -149,7 +148,7 @@ func (s *Service) saveHead(ctx context.Context, headRoot [32]byte) error {
// This gets called to update canonical root mapping. It does not save head block
// root in DB. With the inception of initial-sync-cache-state flag, it uses finalized
// check point as anchors to resume sync therefore head is no longer needed to be saved on per slot basis.
func (s *Service) saveHeadNoDB(ctx context.Context, b *ethpb.SignedBeaconBlock, r [32]byte, hs iface.BeaconState) error {
func (s *Service) saveHeadNoDB(ctx context.Context, b interfaces.SignedBeaconBlock, r [32]byte, hs iface.BeaconState) error {
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
return err
}
@@ -161,20 +160,20 @@ func (s *Service) saveHeadNoDB(ctx context.Context, b *ethpb.SignedBeaconBlock,
return nil
}
s.setHeadInitialSync(r, stateV0.CopySignedBeaconBlock(b), hs)
s.setHeadInitialSync(r, b.Copy(), hs)
return nil
}
// This sets head view object which is used to track the head slot, root, block and state.
func (s *Service) setHead(root [32]byte, block *ethpb.SignedBeaconBlock, state iface.BeaconState) {
func (s *Service) setHead(root [32]byte, block interfaces.SignedBeaconBlock, state iface.BeaconState) {
s.headLock.Lock()
defer s.headLock.Unlock()
// This does a full copy of the block and state.
s.head = &head{
slot: block.Block.Slot,
slot: block.Block().Slot(),
root: root,
block: stateV0.CopySignedBeaconBlock(block),
block: block.Copy(),
state: state.Copy(),
}
}
@@ -182,15 +181,15 @@ func (s *Service) setHead(root [32]byte, block *ethpb.SignedBeaconBlock, state i
// This sets head view object which is used to track the head slot, root, block and state. The method
// assumes that state being passed into the method will not be modified by any other alternate
// caller which holds the state's reference.
func (s *Service) setHeadInitialSync(root [32]byte, block *ethpb.SignedBeaconBlock, state iface.BeaconState) {
func (s *Service) setHeadInitialSync(root [32]byte, block interfaces.SignedBeaconBlock, state iface.BeaconState) {
s.headLock.Lock()
defer s.headLock.Unlock()
// This does a full copy of the block only.
s.head = &head{
slot: block.Block.Slot,
slot: block.Block().Slot(),
root: root,
block: stateV0.CopySignedBeaconBlock(block),
block: block.Copy(),
state: state,
}
}
@@ -215,8 +214,8 @@ func (s *Service) headRoot() [32]byte {
// This returns the head block.
// It does a full copy on head block for immutability.
// This is a lock free version.
func (s *Service) headBlock() *ethpb.SignedBeaconBlock {
return stateV0.CopySignedBeaconBlock(s.head.block)
func (s *Service) headBlock() interfaces.SignedBeaconBlock {
return s.head.block.Copy()
}
// This returns the head state.
@@ -262,7 +261,7 @@ func (s *Service) cacheJustifiedStateBalances(ctx context.Context, justifiedRoot
return err
}
}
if justifiedState == nil {
if justifiedState == nil || justifiedState.IsNil() {
return errors.New("justified state can't be nil")
}

View File

@@ -9,6 +9,7 @@ import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
@@ -39,7 +40,7 @@ func TestSaveHead_Different(t *testing.T) {
newHeadSignedBlock.Block.Slot = 1
newHeadBlock := newHeadSignedBlock.Block
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), newHeadSignedBlock))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), interfaces.NewWrappedSignedBeaconBlock(newHeadSignedBlock)))
newRoot, err := newHeadBlock.HashTreeRoot()
require.NoError(t, err)
headState, err := testutil.NewBeaconState()
@@ -54,7 +55,7 @@ func TestSaveHead_Different(t *testing.T) {
cachedRoot, err := service.HeadRoot(context.Background())
require.NoError(t, err)
assert.DeepEqual(t, cachedRoot, newRoot[:], "Head did not change")
assert.DeepEqual(t, newHeadSignedBlock, service.headBlock(), "Head did not change")
assert.DeepEqual(t, newHeadSignedBlock, service.headBlock().Proto(), "Head did not change")
assert.DeepSSZEqual(t, headState.CloneInnerState(), service.headState(ctx).CloneInnerState(), "Head did not change")
}
@@ -73,7 +74,7 @@ func TestSaveHead_Different_Reorg(t *testing.T) {
newHeadSignedBlock.Block.ParentRoot = reorgChainParent[:]
newHeadBlock := newHeadSignedBlock.Block
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), newHeadSignedBlock))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), interfaces.NewWrappedSignedBeaconBlock(newHeadSignedBlock)))
newRoot, err := newHeadBlock.HashTreeRoot()
require.NoError(t, err)
headState, err := testutil.NewBeaconState()
@@ -90,7 +91,7 @@ func TestSaveHead_Different_Reorg(t *testing.T) {
if !bytes.Equal(cachedRoot, newRoot[:]) {
t.Error("Head did not change")
}
assert.DeepEqual(t, newHeadSignedBlock, service.headBlock(), "Head did not change")
assert.DeepEqual(t, newHeadSignedBlock, service.headBlock().Proto(), "Head did not change")
assert.DeepSSZEqual(t, headState.CloneInnerState(), service.headState(ctx).CloneInnerState(), "Head did not change")
require.LogsContain(t, hook, "Chain reorg occurred")
}
@@ -112,7 +113,7 @@ func TestUpdateHead_MissingJustifiedRoot(t *testing.T) {
service := setupBeaconChain(t, beaconDB)
b := testutil.NewBeaconBlock()
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), b))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), interfaces.NewWrappedSignedBeaconBlock(b)))
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)

View File

@@ -39,7 +39,7 @@ func (s *Service) TreeHandler(w http.ResponseWriter, r *http.Request) {
log.WithError(err).Error("Could not get head state")
return
}
if headState == nil {
if headState == nil || headState.IsNil() {
if _, err := w.Write([]byte("Unavailable during initial syncing")); err != nil {
log.WithError(err).Error("Failed to render p2p info page")
}

View File

@@ -9,6 +9,7 @@ import (
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -37,7 +38,7 @@ func TestService_TreeHandler(t *testing.T) {
require.NoError(t, err)
require.NoError(t, s.cfg.ForkChoiceStore.ProcessBlock(ctx, 0, [32]byte{'a'}, [32]byte{'g'}, [32]byte{'c'}, 0, 0))
require.NoError(t, s.cfg.ForkChoiceStore.ProcessBlock(ctx, 1, [32]byte{'b'}, [32]byte{'a'}, [32]byte{'c'}, 0, 0))
s.setHead([32]byte{'a'}, testutil.NewBeaconBlock(), headState)
s.setHead([32]byte{'a'}, interfaces.NewWrappedSignedBeaconBlock(testutil.NewBeaconBlock()), headState)
rr := httptest.NewRecorder()
handler := http.HandlerFunc(s.TreeHandler)

View File

@@ -1,11 +1,11 @@
package blockchain
import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/interfaces"
)
// This saves a beacon block to the initial sync blocks cache.
func (s *Service) saveInitSyncBlock(r [32]byte, b *ethpb.SignedBeaconBlock) {
func (s *Service) saveInitSyncBlock(r [32]byte, b interfaces.SignedBeaconBlock) {
s.initSyncBlocksLock.Lock()
defer s.initSyncBlocksLock.Unlock()
s.initSyncBlocks[r] = b
@@ -22,7 +22,7 @@ func (s *Service) hasInitSyncBlock(r [32]byte) bool {
// This retrieves a beacon block from the initial sync blocks cache using the root of
// the block.
func (s *Service) getInitSyncBlock(r [32]byte) *ethpb.SignedBeaconBlock {
func (s *Service) getInitSyncBlock(r [32]byte) interfaces.SignedBeaconBlock {
s.initSyncBlocksLock.RLock()
defer s.initSyncBlocksLock.RUnlock()
b := s.initSyncBlocks[r]
@@ -31,11 +31,11 @@ func (s *Service) getInitSyncBlock(r [32]byte) *ethpb.SignedBeaconBlock {
// This retrieves all the beacon blocks from the initial sync blocks cache, the returned
// blocks are unordered.
func (s *Service) getInitSyncBlocks() []*ethpb.SignedBeaconBlock {
func (s *Service) getInitSyncBlocks() []interfaces.SignedBeaconBlock {
s.initSyncBlocksLock.RLock()
defer s.initSyncBlocksLock.RUnlock()
blks := make([]*ethpb.SignedBeaconBlock, 0, len(s.initSyncBlocks))
blks := make([]interfaces.SignedBeaconBlock, 0, len(s.initSyncBlocks))
for _, b := range s.initSyncBlocks {
blks = append(blks, b)
}
@@ -46,5 +46,5 @@ func (s *Service) getInitSyncBlocks() []*ethpb.SignedBeaconBlock {
func (s *Service) clearInitSyncBlocks() {
s.initSyncBlocksLock.Lock()
defer s.initSyncBlocksLock.Unlock()
s.initSyncBlocks = make(map[[32]byte]*ethpb.SignedBeaconBlock)
s.initSyncBlocks = make(map[[32]byte]interfaces.SignedBeaconBlock)
}

View File

@@ -7,6 +7,7 @@ import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/timeutils"
"github.com/sirupsen/logrus"
@@ -15,36 +16,36 @@ import (
var log = logrus.WithField("prefix", "blockchain")
// logs state transition related data every slot.
func logStateTransitionData(b *ethpb.BeaconBlock) {
func logStateTransitionData(b interfaces.BeaconBlock) {
log := log.WithField("slot", b.Slot)
if len(b.Body.Attestations) > 0 {
log = log.WithField("attestations", len(b.Body.Attestations))
if len(b.Body().Attestations()) > 0 {
log = log.WithField("attestations", len(b.Body().Attestations()))
}
if len(b.Body.Deposits) > 0 {
log = log.WithField("deposits", len(b.Body.Deposits))
if len(b.Body().Deposits()) > 0 {
log = log.WithField("deposits", len(b.Body().Deposits()))
}
if len(b.Body.AttesterSlashings) > 0 {
log = log.WithField("attesterSlashings", len(b.Body.AttesterSlashings))
if len(b.Body().AttesterSlashings()) > 0 {
log = log.WithField("attesterSlashings", len(b.Body().AttesterSlashings()))
}
if len(b.Body.ProposerSlashings) > 0 {
log = log.WithField("proposerSlashings", len(b.Body.ProposerSlashings))
if len(b.Body().ProposerSlashings()) > 0 {
log = log.WithField("proposerSlashings", len(b.Body().ProposerSlashings()))
}
if len(b.Body.VoluntaryExits) > 0 {
log = log.WithField("voluntaryExits", len(b.Body.VoluntaryExits))
if len(b.Body().VoluntaryExits()) > 0 {
log = log.WithField("voluntaryExits", len(b.Body().VoluntaryExits()))
}
log.Info("Finished applying state transition")
}
func logBlockSyncStatus(block *ethpb.BeaconBlock, blockRoot [32]byte, finalized *ethpb.Checkpoint, receivedTime time.Time, genesisTime uint64) error {
startTime, err := helpers.SlotToTime(genesisTime, block.Slot)
func logBlockSyncStatus(block interfaces.BeaconBlock, blockRoot [32]byte, finalized *ethpb.Checkpoint, receivedTime time.Time, genesisTime uint64) error {
startTime, err := helpers.SlotToTime(genesisTime, block.Slot())
if err != nil {
return err
}
log.WithFields(logrus.Fields{
"slot": block.Slot,
"slotInEpoch": block.Slot % params.BeaconConfig().SlotsPerEpoch,
"slot": block.Slot(),
"slotInEpoch": block.Slot() % params.BeaconConfig().SlotsPerEpoch,
"block": fmt.Sprintf("0x%s...", hex.EncodeToString(blockRoot[:])[:8]),
"epoch": helpers.SlotToEpoch(block.Slot),
"epoch": helpers.SlotToEpoch(block.Slot()),
"finalizedEpoch": finalized.Epoch,
"finalizedRoot": fmt.Sprintf("0x%s...", hex.EncodeToString(finalized.Root)[:8]),
}).Info("Synced new block")

View File

@@ -10,6 +10,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
)
@@ -227,8 +228,8 @@ func reportEpochMetrics(ctx context.Context, postState, headState iface.BeaconSt
return nil
}
func reportAttestationInclusion(blk *ethpb.BeaconBlock) {
for _, att := range blk.Body.Attestations {
attestationInclusionDelay.Observe(float64(blk.Slot - att.Data.Slot))
func reportAttestationInclusion(blk interfaces.BeaconBlock) {
for _, att := range blk.Body().Attestations() {
attestationInclusionDelay.Observe(float64(blk.Slot() - att.Data.Slot))
}
}

View File

@@ -6,8 +6,8 @@ import (
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/blockutil"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/timeutils"
@@ -46,7 +46,7 @@ func (s *Service) onAttestation(ctx context.Context, a *ethpb.Attestation) error
if err := helpers.ValidateSlotTargetEpoch(a.Data); err != nil {
return err
}
tgt := stateV0.CopyCheckpoint(a.Data.Target)
tgt := blockutil.CopyCheckpoint(a.Data.Target)
// Note that target root check is ignored here because it was performed in sync's validation pipeline:
// validate_aggregate_proof.go and validate_beacon_attestation.go

View File

@@ -29,7 +29,7 @@ func (s *Service) getAttPreState(ctx context.Context, c *ethpb.Checkpoint) (ifac
if err != nil {
return nil, errors.Wrap(err, "could not get cached checkpoint state")
}
if cachedState != nil {
if cachedState != nil && !cachedState.IsNil() {
return cachedState, nil
}
@@ -99,14 +99,14 @@ func (s *Service) verifyBeaconBlock(ctx context.Context, data *ethpb.Attestation
}
// If the block does not exist in db, check again if block exists in initial sync block cache.
// This could happen as the node first syncs to head.
if b == nil && s.hasInitSyncBlock(r) {
if (b == nil || b.IsNil()) && s.hasInitSyncBlock(r) {
b = s.getInitSyncBlock(r)
}
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
return err
}
if b.Block.Slot > data.Slot {
return fmt.Errorf("could not process attestation for future block, block.Slot=%d > attestation.Data.Slot=%d", b.Block.Slot, data.Slot)
if b.Block().Slot() > data.Slot {
return fmt.Errorf("could not process attestation for future block, block.Slot=%d > attestation.Data.Slot=%d", b.Block().Slot(), data.Slot)
}
return nil
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -37,13 +38,13 @@ func TestStore_OnAttestation_ErrorConditions(t *testing.T) {
BlkWithOutState := testutil.NewBeaconBlock()
BlkWithOutState.Block.Slot = 0
require.NoError(t, beaconDB.SaveBlock(ctx, BlkWithOutState))
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(BlkWithOutState)))
BlkWithOutStateRoot, err := BlkWithOutState.Block.HashTreeRoot()
require.NoError(t, err)
BlkWithStateBadAtt := testutil.NewBeaconBlock()
BlkWithStateBadAtt.Block.Slot = 1
require.NoError(t, beaconDB.SaveBlock(ctx, BlkWithStateBadAtt))
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(BlkWithStateBadAtt)))
BlkWithStateBadAttRoot, err := BlkWithStateBadAtt.Block.HashTreeRoot()
require.NoError(t, err)
@@ -54,7 +55,7 @@ func TestStore_OnAttestation_ErrorConditions(t *testing.T) {
BlkWithValidState := testutil.NewBeaconBlock()
BlkWithValidState.Block.Slot = 2
require.NoError(t, beaconDB.SaveBlock(ctx, BlkWithValidState))
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(BlkWithValidState)))
BlkWithValidStateRoot, err := BlkWithValidState.Block.HashTreeRoot()
require.NoError(t, err)
@@ -321,7 +322,7 @@ func TestVerifyBeaconBlock_futureBlock(t *testing.T) {
b := testutil.NewBeaconBlock()
b.Block.Slot = 2
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b)))
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
d := &ethpb.AttestationData{Slot: 1, BeaconBlockRoot: r[:]}
@@ -339,7 +340,7 @@ func TestVerifyBeaconBlock_OK(t *testing.T) {
b := testutil.NewBeaconBlock()
b.Block.Slot = 2
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b)))
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
d := &ethpb.AttestationData{Slot: 2, BeaconBlockRoot: r[:]}
@@ -357,7 +358,7 @@ func TestVerifyFinalizedConsistency_InconsistentRoot(t *testing.T) {
b32 := testutil.NewBeaconBlock()
b32.Block.Slot = 32
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b32))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b32)))
r32, err := b32.Block.HashTreeRoot()
require.NoError(t, err)
@@ -366,7 +367,7 @@ func TestVerifyFinalizedConsistency_InconsistentRoot(t *testing.T) {
b33 := testutil.NewBeaconBlock()
b33.Block.Slot = 33
b33.Block.ParentRoot = r32[:]
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b33))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b33)))
r33, err := b33.Block.HashTreeRoot()
require.NoError(t, err)
@@ -384,7 +385,7 @@ func TestVerifyFinalizedConsistency_OK(t *testing.T) {
b32 := testutil.NewBeaconBlock()
b32.Block.Slot = 32
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b32))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b32)))
r32, err := b32.Block.HashTreeRoot()
require.NoError(t, err)
@@ -393,7 +394,7 @@ func TestVerifyFinalizedConsistency_OK(t *testing.T) {
b33 := testutil.NewBeaconBlock()
b33.Block.Slot = 33
b33.Block.ParentRoot = r32[:]
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b33))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b33)))
r33, err := b33.Block.HashTreeRoot()
require.NoError(t, err)

View File

@@ -17,6 +17,7 @@ import (
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"go.opencensus.io/trace"
)
@@ -81,14 +82,14 @@ var initialSyncBlockCacheSize = uint64(2 * params.BeaconConfig().SlotsPerEpoch)
// ancestor_at_finalized_slot = get_ancestor(store, store.justified_checkpoint.root, finalized_slot)
// if ancestor_at_finalized_slot != store.finalized_checkpoint.root:
// store.justified_checkpoint = state.current_justified_checkpoint
func (s *Service) onBlock(ctx context.Context, signed *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
func (s *Service) onBlock(ctx context.Context, signed interfaces.SignedBeaconBlock, blockRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "blockChain.onBlock")
defer span.End()
if signed == nil || signed.Block == nil {
if signed == nil || signed.IsNil() || signed.Block().IsNil() {
return errors.New("nil block")
}
b := signed.Block
b := signed.Block()
preState, err := s.getBlockPreState(ctx, b)
if err != nil {
@@ -143,7 +144,7 @@ func (s *Service) onBlock(ctx context.Context, signed *ethpb.SignedBeaconBlock,
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
Slot: signed.Block.Slot,
Slot: signed.Block().Slot(),
BlockRoot: blockRoot,
SignedBlock: signed,
Verified: true,
@@ -182,7 +183,7 @@ func (s *Service) onBlock(ctx context.Context, signed *ethpb.SignedBeaconBlock,
return s.handleEpochBoundary(ctx, postState)
}
func (s *Service) onBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBlock,
func (s *Service) onBlockBatch(ctx context.Context, blks []interfaces.SignedBeaconBlock,
blockRoots [][32]byte) ([]*ethpb.Checkpoint, []*ethpb.Checkpoint, error) {
ctx, span := trace.StartSpan(ctx, "blockChain.onBlockBatch")
defer span.End()
@@ -190,21 +191,21 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBl
if len(blks) == 0 || len(blockRoots) == 0 {
return nil, nil, errors.New("no blocks provided")
}
if blks[0] == nil || blks[0].Block == nil {
if blks[0] == nil || blks[0].IsNil() || blks[0].Block().IsNil() {
return nil, nil, errors.New("nil block")
}
b := blks[0].Block
b := blks[0].Block()
// Retrieve incoming block's pre state.
if err := s.verifyBlkPreState(ctx, b); err != nil {
return nil, nil, err
}
preState, err := s.cfg.StateGen.StateByRootInitialSync(ctx, bytesutil.ToBytes32(b.ParentRoot))
preState, err := s.cfg.StateGen.StateByRootInitialSync(ctx, bytesutil.ToBytes32(b.ParentRoot()))
if err != nil {
return nil, nil, err
}
if preState == nil {
return nil, nil, fmt.Errorf("nil pre state for slot %d", b.Slot)
if preState == nil || preState.IsNil() {
return nil, nil, fmt.Errorf("nil pre state for slot %d", b.Slot())
}
jCheckpoints := make([]*ethpb.Checkpoint, len(blks))
@@ -258,16 +259,16 @@ func (s *Service) onBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBl
// handles a block after the block's batch has been verified, where we can save blocks
// their state summaries and split them off to relative hot/cold storage.
func (s *Service) handleBlockAfterBatchVerify(ctx context.Context, signed *ethpb.SignedBeaconBlock,
func (s *Service) handleBlockAfterBatchVerify(ctx context.Context, signed interfaces.SignedBeaconBlock,
blockRoot [32]byte, fCheckpoint, jCheckpoint *ethpb.Checkpoint) error {
b := signed.Block
b := signed.Block()
s.saveInitSyncBlock(blockRoot, signed)
if err := s.insertBlockToForkChoiceStore(ctx, b, blockRoot, fCheckpoint, jCheckpoint); err != nil {
return err
}
if err := s.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{
Slot: signed.Block.Slot,
Slot: signed.Block().Slot(),
Root: blockRoot[:],
}); err != nil {
return err
@@ -336,7 +337,7 @@ func (s *Service) handleEpochBoundary(ctx context.Context, postState iface.Beaco
// This feeds in the block and block's attestations to fork choice store. It's allows fork choice store
// to gain information on the most current chain.
func (s *Service) insertBlockAndAttestationsToForkChoiceStore(ctx context.Context, blk *ethpb.BeaconBlock, root [32]byte,
func (s *Service) insertBlockAndAttestationsToForkChoiceStore(ctx context.Context, blk interfaces.BeaconBlock, root [32]byte,
st iface.BeaconState) error {
fCheckpoint := st.FinalizedCheckpoint()
jCheckpoint := st.CurrentJustifiedCheckpoint()
@@ -344,7 +345,7 @@ func (s *Service) insertBlockAndAttestationsToForkChoiceStore(ctx context.Contex
return err
}
// Feed in block's attestations to fork choice store.
for _, a := range blk.Body.Attestations {
for _, a := range blk.Body().Attestations() {
committee, err := helpers.BeaconCommitteeFromState(st, a.Data.Slot, a.Data.CommitteeIndex)
if err != nil {
return err
@@ -358,14 +359,14 @@ func (s *Service) insertBlockAndAttestationsToForkChoiceStore(ctx context.Contex
return nil
}
func (s *Service) insertBlockToForkChoiceStore(ctx context.Context, blk *ethpb.BeaconBlock,
func (s *Service) insertBlockToForkChoiceStore(ctx context.Context, blk interfaces.BeaconBlock,
root [32]byte, fCheckpoint, jCheckpoint *ethpb.Checkpoint) error {
if err := s.fillInForkChoiceMissingBlocks(ctx, blk, fCheckpoint, jCheckpoint); err != nil {
return err
}
// Feed in block to fork choice store.
if err := s.cfg.ForkChoiceStore.ProcessBlock(ctx,
blk.Slot, root, bytesutil.ToBytes32(blk.ParentRoot), bytesutil.ToBytes32(blk.Body.Graffiti),
blk.Slot(), root, bytesutil.ToBytes32(blk.ParentRoot()), bytesutil.ToBytes32(blk.Body().Graffiti()),
jCheckpoint.Epoch,
fCheckpoint.Epoch); err != nil {
return errors.Wrap(err, "could not process block for proto array fork choice")
@@ -375,19 +376,19 @@ func (s *Service) insertBlockToForkChoiceStore(ctx context.Context, blk *ethpb.B
// This saves post state info to DB or cache. This also saves post state info to fork choice store.
// Post state info consists of processed block and state. Do not call this method unless the block and state are verified.
func (s *Service) savePostStateInfo(ctx context.Context, r [32]byte, b *ethpb.SignedBeaconBlock, st iface.BeaconState, initSync bool) error {
func (s *Service) savePostStateInfo(ctx context.Context, r [32]byte, b interfaces.SignedBeaconBlock, st iface.BeaconState, initSync bool) error {
ctx, span := trace.StartSpan(ctx, "blockChain.savePostStateInfo")
defer span.End()
if initSync {
s.saveInitSyncBlock(r, b)
} else if err := s.cfg.BeaconDB.SaveBlock(ctx, b); err != nil {
return errors.Wrapf(err, "could not save block from slot %d", b.Block.Slot)
return errors.Wrapf(err, "could not save block from slot %d", b.Block().Slot())
}
if err := s.cfg.StateGen.SaveState(ctx, r, st); err != nil {
return errors.Wrap(err, "could not save state")
}
if err := s.insertBlockAndAttestationsToForkChoiceStore(ctx, b.Block, r, st); err != nil {
return errors.Wrapf(err, "could not insert block %d to fork choice store", b.Block.Slot)
if err := s.insertBlockAndAttestationsToForkChoiceStore(ctx, b.Block(), r, st); err != nil {
return errors.Wrapf(err, "could not insert block %d to fork choice store", b.Block().Slot())
}
return nil
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/traceutil"
"go.opencensus.io/trace"
@@ -26,7 +27,7 @@ func (s *Service) CurrentSlot() types.Slot {
// getBlockPreState returns the pre state of an incoming block. It uses the parent root of the block
// to retrieve the state in DB. It verifies the pre state's validity and the incoming block
// is in the correct time window.
func (s *Service) getBlockPreState(ctx context.Context, b *ethpb.BeaconBlock) (iface.BeaconState, error) {
func (s *Service) getBlockPreState(ctx context.Context, b interfaces.BeaconBlock) (iface.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "blockChain.getBlockPreState")
defer span.End()
@@ -35,16 +36,16 @@ func (s *Service) getBlockPreState(ctx context.Context, b *ethpb.BeaconBlock) (i
return nil, err
}
preState, err := s.cfg.StateGen.StateByRoot(ctx, bytesutil.ToBytes32(b.ParentRoot))
preState, err := s.cfg.StateGen.StateByRoot(ctx, bytesutil.ToBytes32(b.ParentRoot()))
if err != nil {
return nil, errors.Wrapf(err, "could not get pre state for slot %d", b.Slot)
return nil, errors.Wrapf(err, "could not get pre state for slot %d", b.Slot())
}
if preState == nil {
return nil, errors.Wrapf(err, "nil pre state for slot %d", b.Slot)
if preState == nil || preState.IsNil() {
return nil, errors.Wrapf(err, "nil pre state for slot %d", b.Slot())
}
// Verify block slot time is not from the future.
if err := helpers.VerifySlotTime(preState.GenesisTime(), b.Slot, params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
if err := helpers.VerifySlotTime(preState.GenesisTime(), b.Slot(), params.BeaconNetworkConfig().MaximumGossipClockDisparity); err != nil {
return nil, err
}
@@ -57,11 +58,11 @@ func (s *Service) getBlockPreState(ctx context.Context, b *ethpb.BeaconBlock) (i
}
// verifyBlkPreState validates input block has a valid pre-state.
func (s *Service) verifyBlkPreState(ctx context.Context, b *ethpb.BeaconBlock) error {
func (s *Service) verifyBlkPreState(ctx context.Context, b interfaces.BeaconBlock) error {
ctx, span := trace.StartSpan(ctx, "blockChain.verifyBlkPreState")
defer span.End()
parentRoot := bytesutil.ToBytes32(b.ParentRoot)
parentRoot := bytesutil.ToBytes32(b.ParentRoot())
// Loosen the check to HasBlock because state summary gets saved in batches
// during initial syncing. There's no risk given a state summary object is just a
// a subset of the block object.
@@ -69,7 +70,7 @@ func (s *Service) verifyBlkPreState(ctx context.Context, b *ethpb.BeaconBlock) e
return errors.New("could not reconstruct parent state")
}
if err := s.VerifyBlkDescendant(ctx, bytesutil.ToBytes32(b.ParentRoot)); err != nil {
if err := s.VerifyBlkDescendant(ctx, bytesutil.ToBytes32(b.ParentRoot())); err != nil {
return err
}
@@ -96,11 +97,11 @@ func (s *Service) VerifyBlkDescendant(ctx context.Context, root [32]byte) error
if err != nil {
return err
}
if finalizedBlkSigned == nil || finalizedBlkSigned.Block == nil {
if finalizedBlkSigned == nil || finalizedBlkSigned.IsNil() || finalizedBlkSigned.Block().IsNil() {
return errors.New("nil finalized block")
}
finalizedBlk := finalizedBlkSigned.Block
bFinalizedRoot, err := s.ancestor(ctx, root[:], finalizedBlk.Slot)
finalizedBlk := finalizedBlkSigned.Block()
bFinalizedRoot, err := s.ancestor(ctx, root[:], finalizedBlk.Slot())
if err != nil {
return errors.Wrap(err, "could not get finalized block root")
}
@@ -110,7 +111,7 @@ func (s *Service) VerifyBlkDescendant(ctx context.Context, root [32]byte) error
if !bytes.Equal(bFinalizedRoot, fRoot[:]) {
err := fmt.Errorf("block %#x is not a descendent of the current finalized block slot %d, %#x != %#x",
bytesutil.Trunc(root[:]), finalizedBlk.Slot, bytesutil.Trunc(bFinalizedRoot),
bytesutil.Trunc(root[:]), finalizedBlk.Slot(), bytesutil.Trunc(bFinalizedRoot),
bytesutil.Trunc(fRoot[:]))
traceutil.AnnotateError(span, err)
return err
@@ -120,13 +121,13 @@ func (s *Service) VerifyBlkDescendant(ctx context.Context, root [32]byte) error
// verifyBlkFinalizedSlot validates input block is not less than or equal
// to current finalized slot.
func (s *Service) verifyBlkFinalizedSlot(b *ethpb.BeaconBlock) error {
func (s *Service) verifyBlkFinalizedSlot(b interfaces.BeaconBlock) error {
finalizedSlot, err := helpers.StartSlot(s.finalizedCheckpt.Epoch)
if err != nil {
return err
}
if finalizedSlot >= b.Slot {
return fmt.Errorf("block is equal or earlier than finalized block, slot %d < slot %d", b.Slot, finalizedSlot)
if finalizedSlot >= b.Slot() {
return fmt.Errorf("block is equal or earlier than finalized block, slot %d < slot %d", b.Slot(), finalizedSlot)
}
return nil
}
@@ -139,7 +140,7 @@ func (s *Service) shouldUpdateCurrentJustified(ctx context.Context, newJustified
if helpers.SlotsSinceEpochStarts(s.CurrentSlot()) < params.BeaconConfig().SafeSlotsToUpdateJustified {
return true, nil
}
var newJustifiedBlockSigned *ethpb.SignedBeaconBlock
var newJustifiedBlockSigned interfaces.SignedBeaconBlock
justifiedRoot := s.ensureRootNotZeros(bytesutil.ToBytes32(newJustifiedCheckpt.Root))
var err error
if s.hasInitSyncBlock(justifiedRoot) {
@@ -150,19 +151,19 @@ func (s *Service) shouldUpdateCurrentJustified(ctx context.Context, newJustified
return false, err
}
}
if newJustifiedBlockSigned == nil || newJustifiedBlockSigned.Block == nil {
if newJustifiedBlockSigned == nil || newJustifiedBlockSigned.IsNil() || newJustifiedBlockSigned.Block().IsNil() {
return false, errors.New("nil new justified block")
}
newJustifiedBlock := newJustifiedBlockSigned.Block
newJustifiedBlock := newJustifiedBlockSigned.Block()
jSlot, err := helpers.StartSlot(s.justifiedCheckpt.Epoch)
if err != nil {
return false, err
}
if newJustifiedBlock.Slot <= jSlot {
if newJustifiedBlock.Slot() <= jSlot {
return false, nil
}
var justifiedBlockSigned *ethpb.SignedBeaconBlock
var justifiedBlockSigned interfaces.SignedBeaconBlock
cachedJustifiedRoot := s.ensureRootNotZeros(bytesutil.ToBytes32(s.justifiedCheckpt.Root))
if s.hasInitSyncBlock(cachedJustifiedRoot) {
justifiedBlockSigned = s.getInitSyncBlock(cachedJustifiedRoot)
@@ -173,11 +174,11 @@ func (s *Service) shouldUpdateCurrentJustified(ctx context.Context, newJustified
}
}
if justifiedBlockSigned == nil || justifiedBlockSigned.Block == nil {
if justifiedBlockSigned == nil || justifiedBlockSigned.IsNil() || justifiedBlockSigned.Block().IsNil() {
return false, errors.New("nil justified block")
}
justifiedBlock := justifiedBlockSigned.Block
b, err := s.ancestor(ctx, justifiedRoot[:], justifiedBlock.Slot)
justifiedBlock := justifiedBlockSigned.Block()
b, err := s.ancestor(ctx, justifiedRoot[:], justifiedBlock.Slot())
if err != nil {
return false, err
}
@@ -307,15 +308,15 @@ func (s *Service) ancestorByDB(ctx context.Context, r [32]byte, slot types.Slot)
signed = s.getInitSyncBlock(r)
}
if signed == nil || signed.Block == nil {
if signed == nil || signed.IsNil() || signed.Block().IsNil() {
return nil, errors.New("nil block")
}
b := signed.Block
if b.Slot == slot || b.Slot < slot {
b := signed.Block()
if b.Slot() == slot || b.Slot() < slot {
return r[:], nil
}
return s.ancestorByDB(ctx, bytesutil.ToBytes32(b.ParentRoot), slot)
return s.ancestorByDB(ctx, bytesutil.ToBytes32(b.ParentRoot()), slot)
}
// This updates justified check point in store, if the new justified is later than stored justified or
@@ -363,13 +364,13 @@ func (s *Service) finalizedImpliesNewJustified(ctx context.Context, state iface.
// This retrieves missing blocks from DB (ie. the blocks that couldn't be received over sync) and inserts them to fork choice store.
// This is useful for block tree visualizer and additional vote accounting.
func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk *ethpb.BeaconBlock,
func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk interfaces.BeaconBlock,
fCheckpoint, jCheckpoint *ethpb.Checkpoint) error {
pendingNodes := make([]*ethpb.BeaconBlock, 0)
pendingNodes := make([]interfaces.BeaconBlock, 0)
pendingRoots := make([][32]byte, 0)
parentRoot := bytesutil.ToBytes32(blk.ParentRoot)
slot := blk.Slot
parentRoot := bytesutil.ToBytes32(blk.ParentRoot())
slot := blk.Slot()
// Fork choice only matters from last finalized slot.
fSlot, err := helpers.StartSlot(s.finalizedCheckpt.Epoch)
if err != nil {
@@ -383,11 +384,11 @@ func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk *ethpb.
return err
}
pendingNodes = append(pendingNodes, b.Block)
pendingNodes = append(pendingNodes, b.Block())
copiedRoot := parentRoot
pendingRoots = append(pendingRoots, copiedRoot)
parentRoot = bytesutil.ToBytes32(b.Block.ParentRoot)
slot = b.Block.Slot
parentRoot = bytesutil.ToBytes32(b.Block().ParentRoot())
slot = b.Block().Slot()
higherThanFinalized = slot > fSlot
}
@@ -397,7 +398,7 @@ func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk *ethpb.
b := pendingNodes[i]
r := pendingRoots[i]
if err := s.cfg.ForkChoiceStore.ProcessBlock(ctx,
b.Slot, r, bytesutil.ToBytes32(b.ParentRoot), bytesutil.ToBytes32(b.Body.Graffiti),
b.Slot(), r, bytesutil.ToBytes32(b.ParentRoot()), bytesutil.ToBytes32(b.Body().Graffiti()),
jCheckpoint.Epoch,
fCheckpoint.Epoch); err != nil {
return errors.Wrap(err, "could not process block for proto array fork choice")

View File

@@ -23,6 +23,7 @@ import (
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -43,7 +44,7 @@ func TestStore_OnBlock(t *testing.T) {
require.NoError(t, err)
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
assert.NoError(t, beaconDB.SaveBlock(ctx, genesis))
assert.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(genesis)))
validGenesisRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err)
st, err := testutil.NewBeaconState()
@@ -54,7 +55,7 @@ func TestStore_OnBlock(t *testing.T) {
random := testutil.NewBeaconBlock()
random.Block.Slot = 1
random.Block.ParentRoot = validGenesisRoot[:]
assert.NoError(t, beaconDB.SaveBlock(ctx, random))
assert.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(random)))
randomParentRoot, err := random.Block.HashTreeRoot()
assert.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: st.Slot(), Root: randomParentRoot[:]}))
@@ -120,7 +121,7 @@ func TestStore_OnBlock(t *testing.T) {
root, err := tt.blk.Block.HashTreeRoot()
assert.NoError(t, err)
err = service.onBlock(ctx, tt.blk, root)
err = service.onBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(tt.blk), root)
assert.ErrorContains(t, tt.wantErrString, err)
})
}
@@ -139,38 +140,40 @@ func TestStore_OnBlockBatch(t *testing.T) {
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
assert.NoError(t, beaconDB.SaveBlock(ctx, genesis))
assert.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(genesis)))
gRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err)
service.finalizedCheckpt = &ethpb.Checkpoint{
Root: gRoot[:],
}
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{})
service.saveInitSyncBlock(gRoot, genesis)
service.saveInitSyncBlock(gRoot, interfaces.NewWrappedSignedBeaconBlock(genesis))
st, keys := testutil.DeterministicGenesisState(t, 64)
bState := st.Copy()
var blks []*ethpb.SignedBeaconBlock
var blks []interfaces.SignedBeaconBlock
var blkRoots [][32]byte
var firstState iface.BeaconState
for i := 1; i < 10; i++ {
b, err := testutil.GenerateFullBlock(bState, keys, testutil.DefaultBlockGenConfig(), types.Slot(i))
require.NoError(t, err)
bState, err = state.ExecuteStateTransition(ctx, bState, b)
bState, err = state.ExecuteStateTransition(ctx, bState, interfaces.NewWrappedSignedBeaconBlock(b))
require.NoError(t, err)
if i == 1 {
firstState = bState.Copy()
}
root, err := b.Block.HashTreeRoot()
require.NoError(t, err)
service.saveInitSyncBlock(root, b)
blks = append(blks, b)
service.saveInitSyncBlock(root, interfaces.NewWrappedSignedBeaconBlock(b))
blks = append(blks, interfaces.NewWrappedSignedBeaconBlock(b))
blkRoots = append(blkRoots, root)
}
blks[0].Block.ParentRoot = gRoot[:]
rBlock, err := blks[0].PbPhase0Block()
assert.NoError(t, err)
rBlock.Block.ParentRoot = gRoot[:]
require.NoError(t, beaconDB.SaveBlock(context.Background(), blks[0]))
require.NoError(t, service.cfg.StateGen.SaveState(ctx, blkRoots[0], firstState))
_, _, err = service.onBlockBatch(ctx, blks[1:], blkRoots[1:])
@@ -200,8 +203,8 @@ func TestRemoveStateSinceLastFinalized_EmptyStartSlot(t *testing.T) {
newJustifiedBlk.Block.ParentRoot = bytesutil.PadTo(lastJustifiedRoot[:], 32)
newJustifiedRoot, err := newJustifiedBlk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, newJustifiedBlk))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, lastJustifiedBlk))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(newJustifiedBlk)))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(lastJustifiedBlk)))
diff := params.BeaconConfig().SlotsPerEpoch.Sub(1).Mul(params.BeaconConfig().SecondsPerSlot)
service.genesisTime = time.Unix(time.Now().Unix()-int64(diff), 0)
@@ -228,8 +231,8 @@ func TestShouldUpdateJustified_ReturnFalse(t *testing.T) {
newJustifiedBlk.Block.ParentRoot = bytesutil.PadTo(lastJustifiedRoot[:], 32)
newJustifiedRoot, err := newJustifiedBlk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, newJustifiedBlk))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, lastJustifiedBlk))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(newJustifiedBlk)))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(lastJustifiedBlk)))
diff := params.BeaconConfig().SlotsPerEpoch.Sub(1).Mul(params.BeaconConfig().SecondsPerSlot)
service.genesisTime = time.Unix(time.Now().Unix()-int64(diff), 0)
@@ -256,21 +259,21 @@ func TestCachedPreState_CanGetFromStateSummary(t *testing.T) {
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
assert.NoError(t, beaconDB.SaveBlock(ctx, genesis))
assert.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(genesis)))
gRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err)
service.finalizedCheckpt = &ethpb.Checkpoint{
Root: gRoot[:],
}
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{})
service.saveInitSyncBlock(gRoot, genesis)
service.saveInitSyncBlock(gRoot, interfaces.NewWrappedSignedBeaconBlock(genesis))
b := testutil.NewBeaconBlock()
b.Block.Slot = 1
b.Block.ParentRoot = gRoot[:]
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: 1, Root: gRoot[:]}))
require.NoError(t, service.cfg.StateGen.SaveState(ctx, gRoot, s))
require.NoError(t, service.verifyBlkPreState(ctx, b.Block))
require.NoError(t, service.verifyBlkPreState(ctx, interfaces.NewWrappedBeaconBlock(b.Block)))
}
func TestCachedPreState_CanGetFromDB(t *testing.T) {
@@ -286,19 +289,19 @@ func TestCachedPreState_CanGetFromDB(t *testing.T) {
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
assert.NoError(t, beaconDB.SaveBlock(ctx, genesis))
assert.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(genesis)))
gRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err)
service.finalizedCheckpt = &ethpb.Checkpoint{
Root: gRoot[:],
}
service.cfg.ForkChoiceStore = protoarray.New(0, 0, [32]byte{})
service.saveInitSyncBlock(gRoot, genesis)
service.saveInitSyncBlock(gRoot, interfaces.NewWrappedSignedBeaconBlock(genesis))
b := testutil.NewBeaconBlock()
b.Block.Slot = 1
service.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
err = service.verifyBlkPreState(ctx, b.Block)
err = service.verifyBlkPreState(ctx, interfaces.NewWrappedBeaconBlock(b.Block))
wanted := "could not reconstruct parent state"
assert.ErrorContains(t, wanted, err)
@@ -307,7 +310,7 @@ func TestCachedPreState_CanGetFromDB(t *testing.T) {
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Slot: 1, Root: gRoot[:]}))
require.NoError(t, service.cfg.StateGen.SaveState(ctx, gRoot, s))
require.NoError(t, service.verifyBlkPreState(ctx, b.Block))
require.NoError(t, service.verifyBlkPreState(ctx, interfaces.NewWrappedSignedBeaconBlock(b).Block()))
}
func TestUpdateJustified_CouldUpdateBest(t *testing.T) {
@@ -319,7 +322,7 @@ func TestUpdateJustified_CouldUpdateBest(t *testing.T) {
require.NoError(t, err)
signedBlock := testutil.NewBeaconBlock()
require.NoError(t, beaconDB.SaveBlock(ctx, signedBlock))
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(signedBlock)))
r, err := signedBlock.Block.HashTreeRoot()
require.NoError(t, err)
service.justifiedCheckpt = &ethpb.Checkpoint{Root: []byte{'A'}}
@@ -355,7 +358,7 @@ func TestFillForkChoiceMissingBlocks_CanSave(t *testing.T) {
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
require.NoError(t, beaconDB.SaveBlock(ctx, genesis))
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(genesis)))
validGenesisRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err)
st, err := testutil.NewBeaconState()
@@ -371,7 +374,7 @@ func TestFillForkChoiceMissingBlocks_CanSave(t *testing.T) {
block.Block.ParentRoot = roots[8]
err = service.fillInForkChoiceMissingBlocks(
context.Background(), block.Block, beaconState.FinalizedCheckpoint(), beaconState.CurrentJustifiedCheckpoint())
context.Background(), interfaces.NewWrappedSignedBeaconBlock(block).Block(), beaconState.FinalizedCheckpoint(), beaconState.CurrentJustifiedCheckpoint())
require.NoError(t, err)
// 5 nodes from the block tree 1. B0 - B3 - B4 - B6 - B8
@@ -393,7 +396,7 @@ func TestFillForkChoiceMissingBlocks_RootsMatch(t *testing.T) {
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
require.NoError(t, beaconDB.SaveBlock(ctx, genesis))
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(genesis)))
validGenesisRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err)
st, err := testutil.NewBeaconState()
@@ -409,7 +412,7 @@ func TestFillForkChoiceMissingBlocks_RootsMatch(t *testing.T) {
block.Block.ParentRoot = roots[8]
err = service.fillInForkChoiceMissingBlocks(
context.Background(), block.Block, beaconState.FinalizedCheckpoint(), beaconState.CurrentJustifiedCheckpoint())
context.Background(), interfaces.NewWrappedSignedBeaconBlock(block).Block(), beaconState.FinalizedCheckpoint(), beaconState.CurrentJustifiedCheckpoint())
require.NoError(t, err)
// 5 nodes from the block tree 1. B0 - B3 - B4 - B6 - B8
@@ -435,7 +438,7 @@ func TestFillForkChoiceMissingBlocks_FilterFinalized(t *testing.T) {
genesisStateRoot := [32]byte{}
genesis := blocks.NewGenesisBlock(genesisStateRoot[:])
assert.NoError(t, beaconDB.SaveBlock(ctx, genesis))
assert.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(genesis)))
validGenesisRoot, err := genesis.Block.HashTreeRoot()
assert.NoError(t, err)
st, err := testutil.NewBeaconState()
@@ -446,23 +449,23 @@ func TestFillForkChoiceMissingBlocks_FilterFinalized(t *testing.T) {
// Define a tree branch, slot 63 <- 64 <- 65
b63 := testutil.NewBeaconBlock()
b63.Block.Slot = 63
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b63))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b63)))
r63, err := b63.Block.HashTreeRoot()
require.NoError(t, err)
b64 := testutil.NewBeaconBlock()
b64.Block.Slot = 64
b64.Block.ParentRoot = r63[:]
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b64))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b64)))
r64, err := b64.Block.HashTreeRoot()
require.NoError(t, err)
b65 := testutil.NewBeaconBlock()
b65.Block.Slot = 65
b65.Block.ParentRoot = r64[:]
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b65))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b65)))
beaconState, _ := testutil.DeterministicGenesisState(t, 32)
err = service.fillInForkChoiceMissingBlocks(
context.Background(), b65.Block, beaconState.FinalizedCheckpoint(), beaconState.CurrentJustifiedCheckpoint())
context.Background(), interfaces.NewWrappedSignedBeaconBlock(b65).Block(), beaconState.FinalizedCheckpoint(), beaconState.CurrentJustifiedCheckpoint())
require.NoError(t, err)
// There should be 2 nodes, block 65 and block 64.
@@ -542,7 +545,7 @@ func blockTree1(t *testing.T, beaconDB db.Database, genesisRoot []byte) ([][]byt
beaconBlock := testutil.NewBeaconBlock()
beaconBlock.Block.Slot = b.Block.Slot
beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32)
if err := beaconDB.SaveBlock(context.Background(), beaconBlock); err != nil {
if err := beaconDB.SaveBlock(context.Background(), interfaces.NewWrappedSignedBeaconBlock(beaconBlock)); err != nil {
return nil, err
}
if err := beaconDB.SaveState(context.Background(), st.Copy(), bytesutil.ToBytes32(beaconBlock.Block.ParentRoot)); err != nil {
@@ -604,7 +607,7 @@ func TestAncestor_HandleSkipSlot(t *testing.T) {
beaconBlock := testutil.NewBeaconBlock()
beaconBlock.Block.Slot = b.Block.Slot
beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32)
require.NoError(t, beaconDB.SaveBlock(context.Background(), beaconBlock))
require.NoError(t, beaconDB.SaveBlock(context.Background(), interfaces.NewWrappedSignedBeaconBlock(beaconBlock)))
}
// Slots 100 to 200 are skip slots. Requesting root at 150 will yield root at 100. The last physical block.
@@ -686,7 +689,7 @@ func TestAncestor_CanUseDB(t *testing.T) {
beaconBlock := testutil.NewBeaconBlock()
beaconBlock.Block.Slot = b.Block.Slot
beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32)
require.NoError(t, beaconDB.SaveBlock(context.Background(), beaconBlock)) // Saves blocks to DB.
require.NoError(t, beaconDB.SaveBlock(context.Background(), interfaces.NewWrappedSignedBeaconBlock(beaconBlock))) // Saves blocks to DB.
}
require.NoError(t, service.cfg.ForkChoiceStore.ProcessBlock(context.Background(), 200, r200, r200, [32]byte{}, 0, 0))
@@ -778,7 +781,7 @@ func TestFinalizedImpliesNewJustified(t *testing.T) {
beaconBlock := testutil.NewBeaconBlock()
beaconBlock.Block.Slot = b.Block.Slot
beaconBlock.Block.ParentRoot = bytesutil.PadTo(b.Block.ParentRoot, 32)
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), beaconBlock))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(context.Background(), interfaces.NewWrappedSignedBeaconBlock(beaconBlock)))
}
service.finalizedCheckpt = &ethpb.Checkpoint{Root: []byte{'c'}, Epoch: 1}
service.justifiedCheckpt.Root = r100[:]
@@ -797,14 +800,14 @@ func TestVerifyBlkDescendant(t *testing.T) {
b.Block.Slot = 1
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, beaconDB.SaveBlock(ctx, b))
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b)))
b1 := testutil.NewBeaconBlock()
b1.Block.Slot = 1
b1.Block.Body.Graffiti = bytesutil.PadTo([]byte{'a'}, 32)
r1, err := b1.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, beaconDB.SaveBlock(ctx, b1))
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b1)))
type args struct {
parentRoot [32]byte
@@ -871,7 +874,7 @@ func TestUpdateJustifiedInitSync(t *testing.T) {
gBlk := testutil.NewBeaconBlock()
gRoot, err := gBlk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, gBlk))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(gBlk)))
require.NoError(t, service.cfg.BeaconDB.SaveGenesisBlockRoot(ctx, gRoot))
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: gRoot[:]}))
beaconState, _ := testutil.DeterministicGenesisState(t, 32)
@@ -935,7 +938,7 @@ func TestOnBlock_CanFinalize(t *testing.T) {
require.NoError(t, service.saveGenesisData(ctx, gs))
gBlk, err := service.cfg.BeaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block.HashTreeRoot()
gRoot, err := gBlk.Block().HashTreeRoot()
require.NoError(t, err)
service.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
@@ -945,7 +948,7 @@ func TestOnBlock_CanFinalize(t *testing.T) {
require.NoError(t, err)
r, err := blk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, service.onBlock(ctx, blk, r))
require.NoError(t, service.onBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(blk), r))
testState, err = service.cfg.StateGen.StateByRoot(ctx, r)
require.NoError(t, err)
}
@@ -971,7 +974,7 @@ func TestInsertFinalizedDeposits(t *testing.T) {
require.NoError(t, service.saveGenesisData(ctx, gs))
gBlk, err := service.cfg.BeaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block.HashTreeRoot()
gRoot, err := gBlk.Block().HashTreeRoot()
require.NoError(t, err)
service.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
gs = gs.Copy()

View File

@@ -14,6 +14,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
@@ -43,13 +44,13 @@ func TestVerifyLMDFFGConsistent_NotOK(t *testing.T) {
b32 := testutil.NewBeaconBlock()
b32.Block.Slot = 32
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b32))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b32)))
r32, err := b32.Block.HashTreeRoot()
require.NoError(t, err)
b33 := testutil.NewBeaconBlock()
b33.Block.Slot = 33
b33.Block.ParentRoot = r32[:]
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b33))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b33)))
r33, err := b33.Block.HashTreeRoot()
require.NoError(t, err)
@@ -71,13 +72,13 @@ func TestVerifyLMDFFGConsistent_OK(t *testing.T) {
b32 := testutil.NewBeaconBlock()
b32.Block.Slot = 32
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b32))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b32)))
r32, err := b32.Block.HashTreeRoot()
require.NoError(t, err)
b33 := testutil.NewBeaconBlock()
b33.Block.Slot = 33
b33.Block.ParentRoot = r32[:]
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, b33))
require.NoError(t, service.cfg.BeaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b33)))
r33, err := b33.Block.HashTreeRoot()
require.NoError(t, err)

View File

@@ -5,12 +5,11 @@ import (
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/timeutils"
"github.com/prysmaticlabs/prysm/shared/traceutil"
"go.opencensus.io/trace"
@@ -21,8 +20,8 @@ var epochsSinceFinalitySaveHotStateDB = types.Epoch(100)
// BlockReceiver interface defines the methods of chain service receive and processing new blocks.
type BlockReceiver interface {
ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error
ReceiveBlockBatch(ctx context.Context, blocks []*ethpb.SignedBeaconBlock, blkRoots [][32]byte) error
ReceiveBlock(ctx context.Context, block interfaces.SignedBeaconBlock, blockRoot [32]byte) error
ReceiveBlockBatch(ctx context.Context, blocks []interfaces.SignedBeaconBlock, blkRoots [][32]byte) error
HasInitSyncBlock(root [32]byte) bool
}
@@ -31,11 +30,11 @@ type BlockReceiver interface {
// 1. Validate block, apply state transition and update check points
// 2. Apply fork choice to the processed block
// 3. Save latest head info
func (s *Service) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlock, blockRoot [32]byte) error {
func (s *Service) ReceiveBlock(ctx context.Context, block interfaces.SignedBeaconBlock, blockRoot [32]byte) error {
ctx, span := trace.StartSpan(ctx, "blockChain.ReceiveBlock")
defer span.End()
receivedTime := timeutils.Now()
blockCopy := stateV0.CopySignedBeaconBlock(block)
blockCopy := block.Copy()
// Apply state transition on the new block.
if err := s.onBlock(ctx, blockCopy, blockRoot); err != nil {
@@ -53,7 +52,7 @@ func (s *Service) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlo
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
Slot: blockCopy.Block.Slot,
Slot: blockCopy.Block().Slot(),
BlockRoot: blockRoot,
SignedBlock: blockCopy,
Verified: true,
@@ -62,7 +61,7 @@ func (s *Service) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlo
}
// Handle post block operations such as attestations and exits.
if err := s.handlePostBlockOperations(blockCopy.Block); err != nil {
if err := s.handlePostBlockOperations(blockCopy.Block()); err != nil {
return err
}
@@ -72,14 +71,14 @@ func (s *Service) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlo
}
// Reports on block and fork choice metrics.
reportSlotMetrics(blockCopy.Block.Slot, s.HeadSlot(), s.CurrentSlot(), s.finalizedCheckpt)
reportSlotMetrics(blockCopy.Block().Slot(), s.HeadSlot(), s.CurrentSlot(), s.finalizedCheckpt)
// Log block sync status.
if err := logBlockSyncStatus(blockCopy.Block, blockRoot, s.finalizedCheckpt, receivedTime, uint64(s.genesisTime.Unix())); err != nil {
if err := logBlockSyncStatus(blockCopy.Block(), blockRoot, s.finalizedCheckpt, receivedTime, uint64(s.genesisTime.Unix())); err != nil {
return err
}
// Log state transition data.
logStateTransitionData(blockCopy.Block)
logStateTransitionData(blockCopy.Block())
return nil
}
@@ -87,7 +86,7 @@ func (s *Service) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlo
// ReceiveBlockBatch processes the whole block batch at once, assuming the block batch is linear ,transitioning
// the state, performing batch verification of all collected signatures and then performing the appropriate
// actions for a block post-transition.
func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []*ethpb.SignedBeaconBlock, blkRoots [][32]byte) error {
func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []interfaces.SignedBeaconBlock, blkRoots [][32]byte) error {
ctx, span := trace.StartSpan(ctx, "blockChain.ReceiveBlockBatch")
defer span.End()
@@ -100,7 +99,7 @@ func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []*ethpb.SignedB
}
for i, b := range blocks {
blockCopy := stateV0.CopySignedBeaconBlock(b)
blockCopy := b.Copy()
if err = s.handleBlockAfterBatchVerify(ctx, blockCopy, blkRoots[i], fCheckpoints[i], jCheckpoints[i]); err != nil {
traceutil.AnnotateError(span, err)
return err
@@ -109,7 +108,7 @@ func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []*ethpb.SignedB
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
Slot: blockCopy.Block.Slot,
Slot: blockCopy.Block().Slot(),
BlockRoot: blkRoots[i],
SignedBlock: blockCopy,
Verified: true,
@@ -117,7 +116,7 @@ func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []*ethpb.SignedB
})
// Reports on blockCopy and fork choice metrics.
reportSlotMetrics(blockCopy.Block.Slot, s.HeadSlot(), s.CurrentSlot(), s.finalizedCheckpt)
reportSlotMetrics(blockCopy.Block().Slot(), s.HeadSlot(), s.CurrentSlot(), s.finalizedCheckpt)
}
if err := s.VerifyWeakSubjectivityRoot(s.ctx); err != nil {
@@ -135,24 +134,24 @@ func (s *Service) HasInitSyncBlock(root [32]byte) bool {
return s.hasInitSyncBlock(root)
}
func (s *Service) handlePostBlockOperations(b *ethpb.BeaconBlock) error {
func (s *Service) handlePostBlockOperations(b interfaces.BeaconBlock) error {
// Delete the processed block attestations from attestation pool.
if err := s.deletePoolAtts(b.Body.Attestations); err != nil {
if err := s.deletePoolAtts(b.Body().Attestations()); err != nil {
return err
}
// Add block attestations to the fork choice pool to compute head.
if err := s.cfg.AttPool.SaveBlockAttestations(b.Body.Attestations); err != nil {
if err := s.cfg.AttPool.SaveBlockAttestations(b.Body().Attestations()); err != nil {
log.Errorf("Could not save block attestations for fork choice: %v", err)
return nil
}
// Mark block exits as seen so we don't include same ones in future blocks.
for _, e := range b.Body.VoluntaryExits {
for _, e := range b.Body().VoluntaryExits() {
s.cfg.ExitPool.MarkIncluded(e)
}
// Mark attester slashings as seen so we don't include same ones in future blocks.
for _, as := range b.Body.AttesterSlashings {
for _, as := range b.Body().AttesterSlashings() {
s.cfg.SlashingPool.MarkIncludedAttesterSlashing(as)
}
return nil

View File

@@ -15,6 +15,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/operations/voluntaryexits"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -53,7 +54,7 @@ func TestService_ReceiveBlock(t *testing.T) {
if hs := s.head.state.Slot(); hs != 2 {
t.Errorf("Unexpected state slot. Got %d but wanted %d", hs, 2)
}
if bs := s.head.block.Block.Slot; bs != 2 {
if bs := s.head.block.Block().Slot(); bs != 2 {
t.Errorf("Unexpected head block slot. Got %d but wanted %d", bs, 2)
}
},
@@ -139,12 +140,12 @@ func TestService_ReceiveBlock(t *testing.T) {
require.NoError(t, s.saveGenesisData(ctx, genesis))
gBlk, err := s.cfg.BeaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block.HashTreeRoot()
gRoot, err := gBlk.Block().HashTreeRoot()
require.NoError(t, err)
s.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
root, err := tt.args.block.Block.HashTreeRoot()
require.NoError(t, err)
err = s.ReceiveBlock(ctx, tt.args.block, root)
err = s.ReceiveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(tt.args.block), root)
if tt.wantedErr != "" {
assert.ErrorContains(t, tt.wantedErr, err)
} else {
@@ -180,7 +181,7 @@ func TestService_ReceiveBlockUpdateHead(t *testing.T) {
require.NoError(t, s.saveGenesisData(ctx, genesis))
gBlk, err := s.cfg.BeaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block.HashTreeRoot()
gRoot, err := gBlk.Block().HashTreeRoot()
require.NoError(t, err)
s.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
root, err := b.Block.HashTreeRoot()
@@ -188,7 +189,7 @@ func TestService_ReceiveBlockUpdateHead(t *testing.T) {
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
require.NoError(t, s.ReceiveBlock(ctx, b, root))
require.NoError(t, s.ReceiveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b), root))
wg.Done()
}()
wg.Wait()
@@ -225,7 +226,7 @@ func TestService_ReceiveBlockBatch(t *testing.T) {
},
check: func(t *testing.T, s *Service) {
assert.Equal(t, types.Slot(2), s.head.state.Slot(), "Incorrect head state slot")
assert.Equal(t, types.Slot(2), s.head.block.Block.Slot, "Incorrect head block slot")
assert.Equal(t, types.Slot(2), s.head.block.Block().Slot(), "Incorrect head block slot")
},
},
{
@@ -263,12 +264,12 @@ func TestService_ReceiveBlockBatch(t *testing.T) {
gBlk, err := s.cfg.BeaconDB.GenesisBlock(ctx)
require.NoError(t, err)
gRoot, err := gBlk.Block.HashTreeRoot()
gRoot, err := gBlk.Block().HashTreeRoot()
require.NoError(t, err)
s.finalizedCheckpt = &ethpb.Checkpoint{Root: gRoot[:]}
root, err := tt.args.block.Block.HashTreeRoot()
require.NoError(t, err)
blks := []*ethpb.SignedBeaconBlock{tt.args.block}
blks := []interfaces.SignedBeaconBlock{interfaces.NewWrappedSignedBeaconBlock(tt.args.block)}
roots := [][32]byte{root}
err = s.ReceiveBlockBatch(ctx, blks, roots)
if tt.wantedErr != "" {
@@ -288,7 +289,7 @@ func TestService_HasInitSyncBlock(t *testing.T) {
if s.HasInitSyncBlock(r) {
t.Error("Should not have block")
}
s.saveInitSyncBlock(r, testutil.NewBeaconBlock())
s.saveInitSyncBlock(r, interfaces.NewWrappedSignedBeaconBlock(testutil.NewBeaconBlock()))
if !s.HasInitSyncBlock(r) {
t.Error("Should have block")
}

View File

@@ -28,10 +28,11 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
"github.com/prysmaticlabs/prysm/shared/blockutil"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/slotutil"
"github.com/sirupsen/logrus"
@@ -60,7 +61,7 @@ type Service struct {
nextEpochBoundarySlot types.Slot
boundaryRoots [][32]byte
checkpointStateCache *cache.CheckpointStateCache
initSyncBlocks map[[32]byte]*ethpb.SignedBeaconBlock
initSyncBlocks map[[32]byte]interfaces.SignedBeaconBlock
initSyncBlocksLock sync.RWMutex
justifiedBalances []uint64
justifiedBalancesLock sync.RWMutex
@@ -95,7 +96,7 @@ func NewService(ctx context.Context, cfg *Config) (*Service, error) {
cancel: cancel,
boundaryRoots: [][32]byte{},
checkpointStateCache: cache.NewCheckpointStateCache(),
initSyncBlocks: make(map[[32]byte]*ethpb.SignedBeaconBlock),
initSyncBlocks: make(map[[32]byte]interfaces.SignedBeaconBlock),
justifiedBalances: make([]uint64, 0),
}, nil
}
@@ -119,8 +120,8 @@ func (s *Service) Start() {
if err != nil {
log.Fatalf("Could not fetch finalized cp: %v", err)
}
if genesisBlock != nil {
r, err = genesisBlock.Block.HashTreeRoot()
if genesisBlock != nil && !genesisBlock.IsNil() {
r, err = genesisBlock.Block().HashTreeRoot()
if err != nil {
log.Fatalf("Could not tree hash genesis block: %v", err)
}
@@ -135,7 +136,7 @@ func (s *Service) Start() {
attestationProcessorSubscribed := make(chan struct{}, 1)
// If the chain has already been initialized, simply start the block processing routine.
if beaconState != nil {
if beaconState != nil && !beaconState.IsNil() {
log.Info("Blockchain data already exists in DB, initializing...")
s.genesisTime = time.Unix(int64(beaconState.GenesisTime()), 0)
s.cfg.OpsService.SetGenesisTime(beaconState.GenesisTime())
@@ -164,25 +165,25 @@ func (s *Service) Start() {
}
// Resume fork choice.
s.justifiedCheckpt = stateV0.CopyCheckpoint(justifiedCheckpoint)
s.justifiedCheckpt = blockutil.CopyCheckpoint(justifiedCheckpoint)
if err := s.cacheJustifiedStateBalances(s.ctx, s.ensureRootNotZeros(bytesutil.ToBytes32(s.justifiedCheckpt.Root))); err != nil {
log.Fatalf("Could not cache justified state balances: %v", err)
}
s.prevJustifiedCheckpt = stateV0.CopyCheckpoint(justifiedCheckpoint)
s.bestJustifiedCheckpt = stateV0.CopyCheckpoint(justifiedCheckpoint)
s.finalizedCheckpt = stateV0.CopyCheckpoint(finalizedCheckpoint)
s.prevFinalizedCheckpt = stateV0.CopyCheckpoint(finalizedCheckpoint)
s.prevJustifiedCheckpt = blockutil.CopyCheckpoint(justifiedCheckpoint)
s.bestJustifiedCheckpt = blockutil.CopyCheckpoint(justifiedCheckpoint)
s.finalizedCheckpt = blockutil.CopyCheckpoint(finalizedCheckpoint)
s.prevFinalizedCheckpt = blockutil.CopyCheckpoint(finalizedCheckpoint)
s.resumeForkChoice(justifiedCheckpoint, finalizedCheckpoint)
ss, err := helpers.StartSlot(s.finalizedCheckpt.Epoch)
if err != nil {
log.Fatalf("Could not get start slot of finalized epoch: %v", err)
}
h := s.headBlock().Block
if h.Slot > ss {
h := s.headBlock().Block()
if h.Slot() > ss {
log.WithFields(logrus.Fields{
"startSlot": ss,
"endSlot": h.Slot,
"endSlot": h.Slot(),
}).Info("Loading blocks to fork choice store, this may take a while.")
if err := s.fillInForkChoiceMissingBlocks(s.ctx, h, s.finalizedCheckpt, s.justifiedCheckpt); err != nil {
log.Fatalf("Could not fill in fork choice store missing blocks: %v", err)
@@ -337,10 +338,10 @@ func (s *Service) saveGenesisData(ctx context.Context, genesisState iface.Beacon
return errors.Wrap(err, "could not save genesis data")
}
genesisBlk, err := s.cfg.BeaconDB.GenesisBlock(ctx)
if err != nil || genesisBlk == nil {
if err != nil || genesisBlk == nil || genesisBlk.IsNil() {
return fmt.Errorf("could not load genesis block: %v", err)
}
genesisBlkRoot, err := genesisBlk.Block.HashTreeRoot()
genesisBlkRoot, err := genesisBlk.Block().HashTreeRoot()
if err != nil {
return errors.Wrap(err, "could not get genesis block root")
}
@@ -351,17 +352,17 @@ func (s *Service) saveGenesisData(ctx context.Context, genesisState iface.Beacon
// Finalized checkpoint at genesis is a zero hash.
genesisCheckpoint := genesisState.FinalizedCheckpoint()
s.justifiedCheckpt = stateV0.CopyCheckpoint(genesisCheckpoint)
s.justifiedCheckpt = blockutil.CopyCheckpoint(genesisCheckpoint)
if err := s.cacheJustifiedStateBalances(ctx, genesisBlkRoot); err != nil {
return err
}
s.prevJustifiedCheckpt = stateV0.CopyCheckpoint(genesisCheckpoint)
s.bestJustifiedCheckpt = stateV0.CopyCheckpoint(genesisCheckpoint)
s.finalizedCheckpt = stateV0.CopyCheckpoint(genesisCheckpoint)
s.prevFinalizedCheckpt = stateV0.CopyCheckpoint(genesisCheckpoint)
s.prevJustifiedCheckpt = blockutil.CopyCheckpoint(genesisCheckpoint)
s.bestJustifiedCheckpt = blockutil.CopyCheckpoint(genesisCheckpoint)
s.finalizedCheckpt = blockutil.CopyCheckpoint(genesisCheckpoint)
s.prevFinalizedCheckpt = blockutil.CopyCheckpoint(genesisCheckpoint)
if err := s.cfg.ForkChoiceStore.ProcessBlock(ctx,
genesisBlk.Block.Slot,
genesisBlk.Block().Slot(),
genesisBlkRoot,
params.BeaconConfig().ZeroHash,
[32]byte{},
@@ -380,10 +381,10 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
if err != nil {
return errors.Wrap(err, "could not get genesis block from db")
}
if genesisBlock == nil {
if genesisBlock == nil || genesisBlock.IsNil() {
return errors.New("no genesis block in db")
}
genesisBlkRoot, err := genesisBlock.Block.HashTreeRoot()
genesisBlkRoot, err := genesisBlock.Block().HashTreeRoot()
if err != nil {
return errors.Wrap(err, "could not get signing root of genesis block")
}
@@ -411,7 +412,7 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
if err != nil {
return errors.Wrap(err, "could not retrieve head block")
}
headEpoch := helpers.SlotToEpoch(headBlock.Block.Slot)
headEpoch := helpers.SlotToEpoch(headBlock.Block().Slot())
var epochsSinceFinality types.Epoch
if headEpoch > finalized.Epoch {
epochsSinceFinality = headEpoch - finalized.Epoch
@@ -419,7 +420,7 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
// Head sync when node is far enough beyond known finalized epoch,
// this becomes really useful during long period of non-finality.
if epochsSinceFinality >= headSyncMinEpochsAfterCheckpoint {
headRoot, err := headBlock.Block.HashTreeRoot()
headRoot, err := headBlock.Block().HashTreeRoot()
if err != nil {
return errors.Wrap(err, "could not hash head block")
}
@@ -428,7 +429,7 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
return errors.Wrap(err, "could not get finalized state from db")
}
log.Infof("Regenerating state from the last checkpoint at slot %d to current head slot of %d."+
"This process may take a while, please wait.", finalizedState.Slot(), headBlock.Block.Slot)
"This process may take a while, please wait.", finalizedState.Slot(), headBlock.Block().Slot())
headState, err := s.cfg.StateGen.StateByRoot(ctx, headRoot)
if err != nil {
return errors.Wrap(err, "could not retrieve head state")
@@ -447,7 +448,7 @@ func (s *Service) initializeChainInfo(ctx context.Context) error {
return errors.Wrap(err, "could not get finalized block from db")
}
if finalizedState == nil || finalizedBlock == nil {
if finalizedState == nil || finalizedState.IsNil() || finalizedBlock == nil || finalizedBlock.IsNil() {
return errors.New("finalized state and block can't be nil")
}
s.setHead(finalizedRoot, finalizedBlock, finalizedState)

View File

@@ -28,6 +28,7 @@ import (
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/event"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -134,7 +135,7 @@ func TestChainStartStop_Initialized(t *testing.T) {
genesisBlk := testutil.NewBeaconBlock()
blkRoot, err := genesisBlk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, beaconDB.SaveBlock(ctx, genesisBlk))
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(genesisBlk)))
s, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, s.SetSlot(1))
@@ -164,7 +165,7 @@ func TestChainStartStop_GenesisZeroHashes(t *testing.T) {
genesisBlk := testutil.NewBeaconBlock()
blkRoot, err := genesisBlk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, beaconDB.SaveBlock(ctx, genesisBlk))
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(genesisBlk)))
s, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, beaconDB.SaveState(ctx, s, blkRoot))
@@ -233,7 +234,7 @@ func TestChainService_CorrectGenesisRoots(t *testing.T) {
genesisBlk := testutil.NewBeaconBlock()
blkRoot, err := genesisBlk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, beaconDB.SaveBlock(ctx, genesisBlk))
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(genesisBlk)))
s, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, s.SetSlot(0))
@@ -260,7 +261,7 @@ func TestChainService_InitializeChainInfo(t *testing.T) {
genesisRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, genesisRoot))
require.NoError(t, beaconDB.SaveBlock(ctx, genesis))
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(genesis)))
finalizedSlot := params.BeaconConfig().SlotsPerEpoch*2 + 1
headBlock := testutil.NewBeaconBlock()
@@ -274,13 +275,13 @@ func TestChainService_InitializeChainInfo(t *testing.T) {
require.NoError(t, err)
require.NoError(t, beaconDB.SaveState(ctx, headState, headRoot))
require.NoError(t, beaconDB.SaveState(ctx, headState, genesisRoot))
require.NoError(t, beaconDB.SaveBlock(ctx, headBlock))
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(headBlock)))
require.NoError(t, beaconDB.SaveFinalizedCheckpoint(ctx, &ethpb.Checkpoint{Epoch: helpers.SlotToEpoch(finalizedSlot), Root: headRoot[:]}))
c := &Service{cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)}}
require.NoError(t, c.initializeChainInfo(ctx))
headBlk, err := c.HeadBlock(ctx)
require.NoError(t, err)
assert.DeepEqual(t, headBlock, headBlk, "Head block incorrect")
assert.DeepEqual(t, headBlock, headBlk.Proto(), "Head block incorrect")
s, err := c.HeadState(ctx)
require.NoError(t, err)
assert.DeepSSZEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
@@ -301,7 +302,7 @@ func TestChainService_InitializeChainInfo_SetHeadAtGenesis(t *testing.T) {
genesisRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, genesisRoot))
require.NoError(t, beaconDB.SaveBlock(ctx, genesis))
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(genesis)))
finalizedSlot := params.BeaconConfig().SlotsPerEpoch*2 + 1
headBlock := testutil.NewBeaconBlock()
@@ -315,14 +316,14 @@ func TestChainService_InitializeChainInfo_SetHeadAtGenesis(t *testing.T) {
require.NoError(t, err)
require.NoError(t, beaconDB.SaveState(ctx, headState, headRoot))
require.NoError(t, beaconDB.SaveState(ctx, headState, genesisRoot))
require.NoError(t, beaconDB.SaveBlock(ctx, headBlock))
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(headBlock)))
c := &Service{cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)}}
require.NoError(t, c.initializeChainInfo(ctx))
s, err := c.HeadState(ctx)
require.NoError(t, err)
assert.DeepSSZEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
assert.Equal(t, genesisRoot, c.genesisRoot, "Genesis block root incorrect")
assert.DeepEqual(t, genesis, c.head.block)
assert.DeepEqual(t, genesis, c.head.block.Proto())
}
func TestChainService_InitializeChainInfo_HeadSync(t *testing.T) {
@@ -343,14 +344,14 @@ func TestChainService_InitializeChainInfo_HeadSync(t *testing.T) {
genesisRoot, err := genesisBlock.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, genesisRoot))
require.NoError(t, beaconDB.SaveBlock(ctx, genesisBlock))
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(genesisBlock)))
finalizedBlock := testutil.NewBeaconBlock()
finalizedBlock.Block.Slot = finalizedSlot
finalizedBlock.Block.ParentRoot = genesisRoot[:]
finalizedRoot, err := finalizedBlock.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, beaconDB.SaveBlock(ctx, finalizedBlock))
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(finalizedBlock)))
// Set head slot close to the finalization point, no head sync is triggered.
headBlock := testutil.NewBeaconBlock()
@@ -358,7 +359,7 @@ func TestChainService_InitializeChainInfo_HeadSync(t *testing.T) {
headBlock.Block.ParentRoot = finalizedRoot[:]
headRoot, err := headBlock.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, beaconDB.SaveBlock(ctx, headBlock))
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(headBlock)))
headState, err := testutil.NewBeaconState()
require.NoError(t, err)
@@ -381,7 +382,7 @@ func TestChainService_InitializeChainInfo_HeadSync(t *testing.T) {
assert.DeepSSZEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
assert.Equal(t, genesisRoot, c.genesisRoot, "Genesis block root incorrect")
// Since head sync is not triggered, chain is initialized to the last finalization checkpoint.
assert.DeepEqual(t, finalizedBlock, c.head.block)
assert.DeepEqual(t, finalizedBlock, c.head.block.Proto())
assert.LogsContain(t, hook, "resetting head from the checkpoint ('--head-sync' flag is ignored)")
assert.LogsDoNotContain(t, hook, "Regenerating state from the last checkpoint at slot")
@@ -391,7 +392,7 @@ func TestChainService_InitializeChainInfo_HeadSync(t *testing.T) {
headBlock.Block.ParentRoot = finalizedRoot[:]
headRoot, err = headBlock.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, beaconDB.SaveBlock(ctx, headBlock))
require.NoError(t, beaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(headBlock)))
require.NoError(t, beaconDB.SaveState(ctx, headState, headRoot))
require.NoError(t, beaconDB.SaveHeadBlockRoot(ctx, headRoot))
@@ -402,7 +403,7 @@ func TestChainService_InitializeChainInfo_HeadSync(t *testing.T) {
assert.DeepSSZEqual(t, headState.InnerStateUnsafe(), s.InnerStateUnsafe(), "Head state incorrect")
assert.Equal(t, genesisRoot, c.genesisRoot, "Genesis block root incorrect")
// Head slot is far beyond the latest finalized checkpoint, head sync is triggered.
assert.DeepEqual(t, headBlock, c.head.block)
assert.DeepEqual(t, headBlock, c.head.block.Proto())
assert.LogsContain(t, hook, "Regenerating state from the last checkpoint at slot 225")
assert.LogsDoNotContain(t, hook, "resetting head from the checkpoint ('--head-sync' flag is ignored)")
}
@@ -420,7 +421,7 @@ func TestChainService_SaveHeadNoDB(t *testing.T) {
newState, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, s.cfg.StateGen.SaveState(ctx, r, newState))
require.NoError(t, s.saveHeadNoDB(ctx, blk, r, newState))
require.NoError(t, s.saveHeadNoDB(ctx, interfaces.NewWrappedSignedBeaconBlock(blk), r, newState))
newB, err := s.cfg.BeaconDB.HeadBlock(ctx)
require.NoError(t, err)
@@ -441,7 +442,7 @@ func TestHasBlock_ForkChoiceAndDB(t *testing.T) {
require.NoError(t, err)
beaconState, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, s.insertBlockAndAttestationsToForkChoiceStore(ctx, block.Block, r, beaconState))
require.NoError(t, s.insertBlockAndAttestationsToForkChoiceStore(ctx, interfaces.NewWrappedSignedBeaconBlock(block).Block(), r, beaconState))
assert.Equal(t, false, s.hasBlock(ctx, [32]byte{}), "Should not have block")
assert.Equal(t, true, s.hasBlock(ctx, r), "Should have block")
@@ -454,12 +455,12 @@ func TestServiceStop_SaveCachedBlocks(t *testing.T) {
cfg: &Config{BeaconDB: beaconDB, StateGen: stategen.New(beaconDB)},
ctx: ctx,
cancel: cancel,
initSyncBlocks: make(map[[32]byte]*ethpb.SignedBeaconBlock),
initSyncBlocks: make(map[[32]byte]interfaces.SignedBeaconBlock),
}
b := testutil.NewBeaconBlock()
r, err := b.Block.HashTreeRoot()
block := testutil.NewBeaconBlock()
r, err := block.Block.HashTreeRoot()
require.NoError(t, err)
s.saveInitSyncBlock(r, b)
s.saveInitSyncBlock(r, interfaces.NewWrappedSignedBeaconBlock(block))
require.NoError(t, s.Stop())
require.Equal(t, true, s.cfg.BeaconDB.HasBlock(ctx, r))
}
@@ -485,7 +486,7 @@ func BenchmarkHasBlockDB(b *testing.B) {
cfg: &Config{BeaconDB: beaconDB},
}
block := testutil.NewBeaconBlock()
require.NoError(b, s.cfg.BeaconDB.SaveBlock(ctx, block))
require.NoError(b, s.cfg.BeaconDB.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(block)))
r, err := block.Block.HashTreeRoot()
require.NoError(b, err)
@@ -508,7 +509,7 @@ func BenchmarkHasBlockForkChoiceStore(b *testing.B) {
bs := &pb.BeaconState{FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)}, CurrentJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, 32)}}
beaconState, err := stateV0.InitializeFromProto(bs)
require.NoError(b, err)
require.NoError(b, s.insertBlockAndAttestationsToForkChoiceStore(ctx, block.Block, r, beaconState))
require.NoError(b, s.insertBlockAndAttestationsToForkChoiceStore(ctx, interfaces.NewWrappedSignedBeaconBlock(block).Block(), r, beaconState))
b.ResetTimer()
for i := 0; i < b.N; i++ {

View File

@@ -23,6 +23,7 @@ go_library(
"//proto/beacon/p2p/v1:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/event:go_default_library",
"//shared/interfaces:go_default_library",
"//shared/params:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",

View File

@@ -24,6 +24,7 @@ import (
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/event"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/sirupsen/logrus"
)
@@ -32,11 +33,11 @@ import (
type ChainService struct {
State iface.BeaconState
Root []byte
Block *ethpb.SignedBeaconBlock
Block interfaces.SignedBeaconBlock
FinalizedCheckPoint *ethpb.Checkpoint
CurrentJustifiedCheckPoint *ethpb.Checkpoint
PreviousJustifiedCheckPoint *ethpb.Checkpoint
BlocksReceived []*ethpb.SignedBeaconBlock
BlocksReceived []interfaces.SignedBeaconBlock
Balance *precompute.Balance
Genesis time.Time
ValidatorsRoot [32]byte
@@ -149,18 +150,18 @@ func (mon *MockOperationNotifier) OperationFeed() *event.Feed {
}
// ReceiveBlockInitialSync mocks ReceiveBlockInitialSync method in chain service.
func (s *ChainService) ReceiveBlockInitialSync(ctx context.Context, block *ethpb.SignedBeaconBlock, _ [32]byte) error {
func (s *ChainService) ReceiveBlockInitialSync(ctx context.Context, block interfaces.SignedBeaconBlock, _ [32]byte) error {
if s.State == nil {
s.State = &stateV0.BeaconState{}
}
if !bytes.Equal(s.Root, block.Block.ParentRoot) {
return errors.Errorf("wanted %#x but got %#x", s.Root, block.Block.ParentRoot)
if !bytes.Equal(s.Root, block.Block().ParentRoot()) {
return errors.Errorf("wanted %#x but got %#x", s.Root, block.Block().ParentRoot())
}
if err := s.State.SetSlot(block.Block.Slot); err != nil {
if err := s.State.SetSlot(block.Block().Slot()); err != nil {
return err
}
s.BlocksReceived = append(s.BlocksReceived, block)
signingRoot, err := block.Block.HashTreeRoot()
signingRoot, err := block.Block().HashTreeRoot()
if err != nil {
return err
}
@@ -168,7 +169,7 @@ func (s *ChainService) ReceiveBlockInitialSync(ctx context.Context, block *ethpb
if err := s.DB.SaveBlock(ctx, block); err != nil {
return err
}
logrus.Infof("Saved block with root: %#x at slot %d", signingRoot, block.Block.Slot)
logrus.Infof("Saved block with root: %#x at slot %d", signingRoot, block.Block().Slot())
}
s.Root = signingRoot[:]
s.Block = block
@@ -176,19 +177,19 @@ func (s *ChainService) ReceiveBlockInitialSync(ctx context.Context, block *ethpb
}
// ReceiveBlockBatch processes blocks in batches from initial-sync.
func (s *ChainService) ReceiveBlockBatch(ctx context.Context, blks []*ethpb.SignedBeaconBlock, _ [][32]byte) error {
func (s *ChainService) ReceiveBlockBatch(ctx context.Context, blks []interfaces.SignedBeaconBlock, _ [][32]byte) error {
if s.State == nil {
s.State = &stateV0.BeaconState{}
}
for _, block := range blks {
if !bytes.Equal(s.Root, block.Block.ParentRoot) {
return errors.Errorf("wanted %#x but got %#x", s.Root, block.Block.ParentRoot)
if !bytes.Equal(s.Root, block.Block().ParentRoot()) {
return errors.Errorf("wanted %#x but got %#x", s.Root, block.Block().ParentRoot())
}
if err := s.State.SetSlot(block.Block.Slot); err != nil {
if err := s.State.SetSlot(block.Block().Slot()); err != nil {
return err
}
s.BlocksReceived = append(s.BlocksReceived, block)
signingRoot, err := block.Block.HashTreeRoot()
signingRoot, err := block.Block().HashTreeRoot()
if err != nil {
return err
}
@@ -196,7 +197,7 @@ func (s *ChainService) ReceiveBlockBatch(ctx context.Context, blks []*ethpb.Sign
if err := s.DB.SaveBlock(ctx, block); err != nil {
return err
}
logrus.Infof("Saved block with root: %#x at slot %d", signingRoot, block.Block.Slot)
logrus.Infof("Saved block with root: %#x at slot %d", signingRoot, block.Block().Slot())
}
s.Root = signingRoot[:]
s.Block = block
@@ -205,18 +206,18 @@ func (s *ChainService) ReceiveBlockBatch(ctx context.Context, blks []*ethpb.Sign
}
// ReceiveBlock mocks ReceiveBlock method in chain service.
func (s *ChainService) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeaconBlock, _ [32]byte) error {
func (s *ChainService) ReceiveBlock(ctx context.Context, block interfaces.SignedBeaconBlock, _ [32]byte) error {
if s.State == nil {
s.State = &stateV0.BeaconState{}
}
if !bytes.Equal(s.Root, block.Block.ParentRoot) {
return errors.Errorf("wanted %#x but got %#x", s.Root, block.Block.ParentRoot)
if !bytes.Equal(s.Root, block.Block().ParentRoot()) {
return errors.Errorf("wanted %#x but got %#x", s.Root, block.Block().ParentRoot())
}
if err := s.State.SetSlot(block.Block.Slot); err != nil {
if err := s.State.SetSlot(block.Block().Slot()); err != nil {
return err
}
s.BlocksReceived = append(s.BlocksReceived, block)
signingRoot, err := block.Block.HashTreeRoot()
signingRoot, err := block.Block().HashTreeRoot()
if err != nil {
return err
}
@@ -224,7 +225,7 @@ func (s *ChainService) ReceiveBlock(ctx context.Context, block *ethpb.SignedBeac
if err := s.DB.SaveBlock(ctx, block); err != nil {
return err
}
logrus.Infof("Saved block with root: %#x at slot %d", signingRoot, block.Block.Slot)
logrus.Infof("Saved block with root: %#x at slot %d", signingRoot, block.Block().Slot())
}
s.Root = signingRoot[:]
s.Block = block
@@ -248,7 +249,7 @@ func (s *ChainService) HeadRoot(_ context.Context) ([]byte, error) {
}
// HeadBlock mocks HeadBlock method in chain service.
func (s *ChainService) HeadBlock(context.Context) (*ethpb.SignedBeaconBlock, error) {
func (s *ChainService) HeadBlock(context.Context) (interfaces.SignedBeaconBlock, error) {
return s.Block, nil
}

View File

@@ -8,6 +8,7 @@ import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
@@ -17,7 +18,7 @@ func TestService_VerifyWeakSubjectivityRoot(t *testing.T) {
b := testutil.NewBeaconBlock()
b.Block.Slot = 32
require.NoError(t, beaconDB.SaveBlock(context.Background(), b))
require.NoError(t, beaconDB.SaveBlock(context.Background(), interfaces.NewWrappedSignedBeaconBlock(b)))
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
tests := []struct {

View File

@@ -34,7 +34,7 @@ go_library(
],
deps = [
"//beacon-chain/state/interface:go_default_library",
"//beacon-chain/state/stateV0:go_default_library",
"//shared/blockutil:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/params:go_default_library",

View File

@@ -11,7 +11,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
"github.com/prysmaticlabs/prysm/shared/blockutil"
"k8s.io/client-go/tools/cache"
)
@@ -98,7 +98,7 @@ func (c *AttestationCache) Get(ctx context.Context, req *ethpb.AttestationDataRe
if exists && item != nil && item.(*attestationReqResWrapper).res != nil {
attestationCacheHit.Inc()
return stateV0.CopyAttestationData(item.(*attestationReqResWrapper).res), nil
return blockutil.CopyAttestationData(item.(*attestationReqResWrapper).res), nil
}
attestationCacheMiss.Inc()
return nil, nil

View File

@@ -28,13 +28,14 @@ go_library(
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/validators:go_default_library",
"//beacon-chain/state/interface:go_default_library",
"//beacon-chain/state/stateV0:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/attestationutil:go_default_library",
"//shared/blockutil:go_default_library",
"//shared/bls:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/depositutil:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/interfaces:go_default_library",
"//shared/mathutil:go_default_library",
"//shared/params:go_default_library",
"//shared/slashutil:go_default_library",
@@ -80,8 +81,10 @@ go_test(
"//shared/aggregation:go_default_library",
"//shared/aggregation/attestations:go_default_library",
"//shared/attestationutil:go_default_library",
"//shared/blockutil:go_default_library",
"//shared/bls:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/interfaces:go_default_library",
"//shared/params:go_default_library",
"//shared/testutil:go_default_library",
"//shared/testutil/assert:go_default_library",

View File

@@ -12,6 +12,7 @@ import (
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"go.opencensus.io/trace"
)
@@ -21,14 +22,14 @@ import (
func ProcessAttestations(
ctx context.Context,
beaconState iface.BeaconState,
b *ethpb.SignedBeaconBlock,
b interfaces.SignedBeaconBlock,
) (iface.BeaconState, error) {
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
return nil, err
}
var err error
for idx, attestation := range b.Block.Body.Attestations {
for idx, attestation := range b.Block().Body().Attestations() {
beaconState, err = ProcessAttestation(ctx, beaconState, attestation)
if err != nil {
return nil, errors.Wrapf(err, "could not verify attestation at index %d in block", idx)
@@ -83,14 +84,14 @@ func ProcessAttestation(
func ProcessAttestationsNoVerifySignature(
ctx context.Context,
beaconState iface.BeaconState,
b *ethpb.SignedBeaconBlock,
b interfaces.SignedBeaconBlock,
) (iface.BeaconState, error) {
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
return nil, err
}
body := b.Block.Body
body := b.Block().Body()
var err error
for idx, attestation := range body.Attestations {
for idx, attestation := range body.Attestations() {
beaconState, err = ProcessAttestationNoVerifySignature(ctx, beaconState, attestation)
if err != nil {
return nil, errors.Wrapf(err, "could not verify attestation at index %d in block", idx)

View File

@@ -3,6 +3,7 @@ package blocks_test
import (
"context"
"fmt"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"testing"
types "github.com/prysmaticlabs/eth2-types"
@@ -46,7 +47,7 @@ func TestProcessAttestations_InclusionDelayFailure(t *testing.T) {
params.BeaconConfig().MinAttestationInclusionDelay,
beaconState.Slot(),
)
_, err := blocks.ProcessAttestations(context.Background(), beaconState, b)
_, err := blocks.ProcessAttestations(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(b))
assert.ErrorContains(t, want, err)
}
@@ -76,7 +77,7 @@ func TestProcessAttestations_NeitherCurrentNorPrevEpoch(t *testing.T) {
helpers.PrevEpoch(beaconState),
helpers.CurrentEpoch(beaconState),
)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(b))
assert.ErrorContains(t, want, err)
}
@@ -104,11 +105,11 @@ func TestProcessAttestations_CurrentEpochFFGDataMismatches(t *testing.T) {
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
want := "source check point not equal to current justified checkpoint"
_, err := blocks.ProcessAttestations(context.Background(), beaconState, b)
_, err := blocks.ProcessAttestations(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(b))
assert.ErrorContains(t, want, err)
b.Block.Body.Attestations[0].Data.Source.Epoch = helpers.CurrentEpoch(beaconState)
b.Block.Body.Attestations[0].Data.Source.Root = []byte{}
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(b))
assert.ErrorContains(t, want, err)
}
@@ -142,12 +143,12 @@ func TestProcessAttestations_PrevEpochFFGDataMismatches(t *testing.T) {
require.NoError(t, beaconState.AppendPreviousEpochAttestations(&pb.PendingAttestation{}))
want := "source check point not equal to previous justified checkpoint"
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(b))
assert.ErrorContains(t, want, err)
b.Block.Body.Attestations[0].Data.Source.Epoch = helpers.PrevEpoch(beaconState)
b.Block.Body.Attestations[0].Data.Target.Epoch = helpers.PrevEpoch(beaconState)
b.Block.Body.Attestations[0].Data.Source.Root = []byte{}
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(b))
assert.ErrorContains(t, want, err)
}
@@ -178,7 +179,7 @@ func TestProcessAttestations_InvalidAggregationBitsLength(t *testing.T) {
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
expected := "failed to verify aggregation bitfield: wanted participants bitfield length 3, got: 4"
_, err = blocks.ProcessAttestations(context.Background(), beaconState, b)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(b))
assert.ErrorContains(t, expected, err)
}
@@ -221,7 +222,7 @@ func TestProcessAttestations_OK(t *testing.T) {
err = beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
require.NoError(t, err)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, block)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(block))
assert.NoError(t, err)
}
@@ -352,7 +353,7 @@ func TestProcessAggregatedAttestation_NoOverlappingBits(t *testing.T) {
err = beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
require.NoError(t, err)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, block)
_, err = blocks.ProcessAttestations(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(block))
assert.NoError(t, err)
}

View File

@@ -10,6 +10,7 @@ import (
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
@@ -41,7 +42,7 @@ func TestFuzzProcessBlockHeader_10000(t *testing.T) {
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
_, err = ProcessBlockHeader(context.Background(), s, block)
_, err = ProcessBlockHeader(context.Background(), s, interfaces.NewWrappedSignedBeaconBlock(block))
_ = err
}
}
@@ -139,7 +140,7 @@ func TestFuzzProcessRandao_10000(t *testing.T) {
fuzzer.Fuzz(b)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessRandao(context.Background(), s, b)
r, err := ProcessRandao(context.Background(), s, interfaces.NewWrappedSignedBeaconBlock(b))
if err != nil && r != nil {
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
}
@@ -258,7 +259,7 @@ func TestFuzzProcessAttestations_10000(t *testing.T) {
fuzzer.Fuzz(b)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessAttestations(ctx, s, b)
r, err := ProcessAttestations(ctx, s, interfaces.NewWrappedSignedBeaconBlock(b))
if err != nil && r != nil {
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
}
@@ -275,7 +276,7 @@ func TestFuzzProcessAttestationsNoVerify_10000(t *testing.T) {
fuzzer.Fuzz(b)
s, err := stateV0.InitializeFromProtoUnsafe(state)
require.NoError(t, err)
r, err := ProcessAttestationsNoVerifySignature(ctx, s, b)
r, err := ProcessAttestationsNoVerifySignature(ctx, s, interfaces.NewWrappedSignedBeaconBlock(b))
if err != nil && r != nil {
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and block: %v", r, err, state, b)
}

View File

@@ -7,7 +7,7 @@ import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
"github.com/prysmaticlabs/prysm/shared/blockutil"
"github.com/prysmaticlabs/prysm/shared/params"
)
@@ -21,7 +21,7 @@ import (
// if state.eth1_data_votes.count(body.eth1_data) * 2 > EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH:
// state.eth1_data = body.eth1_data
func ProcessEth1DataInBlock(_ context.Context, beaconState iface.BeaconState, eth1Data *ethpb.Eth1Data) (iface.BeaconState, error) {
if beaconState == nil {
if beaconState == nil || beaconState.IsNil() {
return nil, errors.New("nil state")
}
if err := beaconState.AppendEth1DataVotes(eth1Data); err != nil {
@@ -58,7 +58,7 @@ func AreEth1DataEqual(a, b *ethpb.Eth1Data) bool {
// votes to see if they match the eth1data.
func Eth1DataHasEnoughSupport(beaconState iface.ReadOnlyBeaconState, data *ethpb.Eth1Data) (bool, error) {
voteCount := uint64(0)
data = stateV0.CopyETH1Data(data)
data = blockutil.CopyETH1Data(data)
for _, vote := range beaconState.Eth1DataVotes() {
if AreEth1DataEqual(vote, data) {

View File

@@ -10,6 +10,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/blockutil"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
@@ -188,7 +189,7 @@ func TestProcessEth1Data_SetsCorrectly(t *testing.T) {
if len(newETH1DataVotes) <= 1 {
t.Error("Expected new ETH1 data votes to have length > 1")
}
if !proto.Equal(beaconState.Eth1Data(), stateV0.CopyETH1Data(b.Block.Body.Eth1Data)) {
if !proto.Equal(beaconState.Eth1Data(), blockutil.CopyETH1Data(b.Block.Body.Eth1Data)) {
t.Errorf(
"Expected latest eth1 data to have been set to %v, received %v",
b.Block.Body.Eth1Data,

View File

@@ -9,6 +9,7 @@ import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
)
@@ -40,22 +41,22 @@ import (
func ProcessBlockHeader(
_ context.Context,
beaconState iface.BeaconState,
block *ethpb.SignedBeaconBlock,
block interfaces.SignedBeaconBlock,
) (iface.BeaconState, error) {
if err := helpers.VerifyNilBeaconBlock(block); err != nil {
return nil, err
}
bodyRoot, err := block.Block.Body.HashTreeRoot()
bodyRoot, err := block.Block().Body().HashTreeRoot()
if err != nil {
return nil, err
}
beaconState, err = ProcessBlockHeaderNoVerify(beaconState, block.Block.Slot, block.Block.ProposerIndex, block.Block.ParentRoot, bodyRoot[:])
beaconState, err = ProcessBlockHeaderNoVerify(beaconState, block.Block().Slot(), block.Block().ProposerIndex(), block.Block().ParentRoot(), bodyRoot[:])
if err != nil {
return nil, err
}
// Verify proposer signature.
if err := VerifyBlockSignature(beaconState, block.Block.ProposerIndex, block.Signature, block.Block.HashTreeRoot); err != nil {
if err := VerifyBlockSignature(beaconState, block.Block().ProposerIndex(), block.Signature(), block.Block().HashTreeRoot); err != nil {
return nil, err
}

View File

@@ -11,6 +11,7 @@ import (
p2ptypes "github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -65,7 +66,7 @@ func TestProcessBlockHeader_ImproperBlockSlot(t *testing.T) {
err = state.UpdateValidatorAtIndex(proposerIdx, validators[proposerIdx])
require.NoError(t, err)
_, err = blocks.ProcessBlockHeader(context.Background(), state, block)
_, err = blocks.ProcessBlockHeader(context.Background(), state, interfaces.NewWrappedSignedBeaconBlock(block))
assert.ErrorContains(t, "block.Slot 10 must be greater than state.LatestBlockHeader.Slot 10", err)
}
@@ -91,7 +92,7 @@ func TestProcessBlockHeader_WrongProposerSig(t *testing.T) {
block.Signature, err = helpers.ComputeDomainAndSign(beaconState, 0, block.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[proposerIdx+1])
require.NoError(t, err)
_, err = blocks.ProcessBlockHeader(context.Background(), beaconState, block)
_, err = blocks.ProcessBlockHeader(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(block))
want := "signature did not verify"
assert.ErrorContains(t, want, err)
}
@@ -133,7 +134,7 @@ func TestProcessBlockHeader_DifferentSlots(t *testing.T) {
Signature: blockSig,
})
_, err = blocks.ProcessBlockHeader(context.Background(), state, block)
_, err = blocks.ProcessBlockHeader(context.Background(), state, interfaces.NewWrappedSignedBeaconBlock(block))
want := "is different than block slot"
assert.ErrorContains(t, want, err)
}
@@ -172,7 +173,7 @@ func TestProcessBlockHeader_PreviousBlockRootNotSignedRoot(t *testing.T) {
block.Block.ParentRoot = bytesutil.PadTo([]byte{'A'}, 32)
block.Signature = blockSig
_, err = blocks.ProcessBlockHeader(context.Background(), state, block)
_, err = blocks.ProcessBlockHeader(context.Background(), state, interfaces.NewWrappedSignedBeaconBlock(block))
want := "does not match"
assert.ErrorContains(t, want, err)
}
@@ -214,7 +215,7 @@ func TestProcessBlockHeader_SlashedProposer(t *testing.T) {
block.Block.ParentRoot = parentRoot[:]
block.Signature = blockSig
_, err = blocks.ProcessBlockHeader(context.Background(), state, block)
_, err = blocks.ProcessBlockHeader(context.Background(), state, interfaces.NewWrappedSignedBeaconBlock(block))
want := "was previously slashed"
assert.ErrorContains(t, want, err)
}
@@ -263,7 +264,7 @@ func TestProcessBlockHeader_OK(t *testing.T) {
err = state.UpdateValidatorAtIndex(proposerIdx, validators[proposerIdx])
require.NoError(t, err)
newState, err := blocks.ProcessBlockHeader(context.Background(), state, block)
newState, err := blocks.ProcessBlockHeader(context.Background(), state, interfaces.NewWrappedSignedBeaconBlock(block))
require.NoError(t, err, "Failed to process block header got")
var zeroHash [32]byte
nsh := newState.LatestBlockHeader()

View File

@@ -4,10 +4,10 @@ import (
"context"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/shared/hashutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
)
@@ -28,21 +28,21 @@ import (
func ProcessRandao(
_ context.Context,
beaconState iface.BeaconState,
b *ethpb.SignedBeaconBlock,
b interfaces.SignedBeaconBlock,
) (iface.BeaconState, error) {
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
return nil, err
}
body := b.Block.Body
body := b.Block().Body()
buf, proposerPub, domain, err := randaoSigningData(beaconState)
if err != nil {
return nil, err
}
if err := verifySignature(buf, proposerPub, body.RandaoReveal, domain); err != nil {
if err := verifySignature(buf, proposerPub, body.RandaoReveal(), domain); err != nil {
return nil, errors.Wrap(err, "could not verify block randao")
}
beaconState, err = ProcessRandaoNoVerify(beaconState, body.RandaoReveal)
beaconState, err = ProcessRandaoNoVerify(beaconState, body.RandaoReveal())
if err != nil {
return nil, errors.Wrap(err, "could not process randao")
}

View File

@@ -10,6 +10,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -38,7 +39,7 @@ func TestProcessRandao_IncorrectProposerFailsVerification(t *testing.T) {
}
want := "block randao: signature did not verify"
_, err = blocks.ProcessRandao(context.Background(), beaconState, b)
_, err = blocks.ProcessRandao(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(b))
assert.ErrorContains(t, want, err)
}
@@ -59,7 +60,7 @@ func TestProcessRandao_SignatureVerifiesAndUpdatesLatestStateMixes(t *testing.T)
newState, err := blocks.ProcessRandao(
context.Background(),
beaconState,
b,
interfaces.NewWrappedSignedBeaconBlock(b),
)
require.NoError(t, err, "Unexpected error processing block randao")
currentEpoch := helpers.CurrentEpoch(beaconState)

View File

@@ -13,9 +13,9 @@ go_library(
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/validators:go_default_library",
"//beacon-chain/state/interface:go_default_library",
"//beacon-chain/state/stateV0:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/attestationutil:go_default_library",
"//shared/blockutil:go_default_library",
"//shared/featureconfig:go_default_library",
"//shared/mathutil:go_default_library",
"//shared/params:go_default_library",

View File

@@ -14,9 +14,9 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/attestationutil"
"github.com/prysmaticlabs/prysm/shared/blockutil"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/mathutil"
"github.com/prysmaticlabs/prysm/shared/params"
@@ -258,7 +258,7 @@ func ProcessEffectiveBalanceUpdates(state iface.BeaconState) (iface.BeaconState,
balance := bals[idx]
if balance+downwardThreshold < val.EffectiveBalance || val.EffectiveBalance+upwardThreshold < balance {
newVal := stateV0.CopyValidator(val)
newVal := blockutil.CopyValidator(val)
newVal.EffectiveBalance = maxEffBalance
if newVal.EffectiveBalance > balance-balance%effBalanceInc {
newVal.EffectiveBalance = balance - balance%effBalanceInc
@@ -284,7 +284,7 @@ func ProcessEffectiveBalanceUpdates(state iface.BeaconState) (iface.BeaconState,
effectiveBal = balance - balance%effBalanceInc
}
if effectiveBal != val.EffectiveBalance {
newVal := stateV0.CopyValidator(val)
newVal := blockutil.CopyValidator(val)
newVal.EffectiveBalance = effectiveBal
return true, newVal, nil
}

View File

@@ -68,13 +68,14 @@ func AttestationsDelta(state iface.ReadOnlyBeaconState, pBal *Balance, vp []*Val
prevEpoch := helpers.PrevEpoch(state)
finalizedEpoch := state.FinalizedCheckpointEpoch()
sqrtActiveCurrentEpoch := mathutil.IntegerSquareRoot(pBal.ActiveCurrentEpoch)
for i, v := range vp {
rewards[i], penalties[i] = attestationDelta(pBal, v, prevEpoch, finalizedEpoch)
rewards[i], penalties[i] = attestationDelta(pBal, sqrtActiveCurrentEpoch, v, prevEpoch, finalizedEpoch)
}
return rewards, penalties, nil
}
func attestationDelta(pBal *Balance, v *Validator, prevEpoch, finalizedEpoch types.Epoch) (uint64, uint64) {
func attestationDelta(pBal *Balance, sqrtActiveCurrentEpoch uint64, v *Validator, prevEpoch, finalizedEpoch types.Epoch) (uint64, uint64) {
if !EligibleForRewards(v) || pBal.ActiveCurrentEpoch == 0 {
return 0, 0
}
@@ -82,7 +83,7 @@ func attestationDelta(pBal *Balance, v *Validator, prevEpoch, finalizedEpoch typ
baseRewardsPerEpoch := params.BeaconConfig().BaseRewardsPerEpoch
effectiveBalanceIncrement := params.BeaconConfig().EffectiveBalanceIncrement
vb := v.CurrentEpochEffectiveBalance
br := vb * params.BeaconConfig().BaseRewardFactor / mathutil.IntegerSquareRoot(pBal.ActiveCurrentEpoch) / baseRewardsPerEpoch
br := vb * params.BeaconConfig().BaseRewardFactor / sqrtActiveCurrentEpoch / baseRewardsPerEpoch
r, p := uint64(0), uint64(0)
currentEpochBalance := pBal.ActiveCurrentEpoch / effectiveBalanceIncrement

View File

@@ -10,6 +10,6 @@ go_library(
visibility = ["//beacon-chain:__subpackages__"],
deps = [
"//shared/event:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"//shared/interfaces:go_default_library",
],
)

View File

@@ -2,9 +2,7 @@
// during the runtime of a beacon node.
package block
import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
)
import "github.com/prysmaticlabs/prysm/shared/interfaces"
const (
// ReceivedBlock is sent after a block has been received by the beacon node via p2p or RPC.
@@ -13,5 +11,5 @@ const (
// ReceivedBlockData is the data sent with ReceivedBlock events.
type ReceivedBlockData struct {
SignedBlock *ethpb.SignedBeaconBlock
SignedBlock interfaces.SignedBeaconBlock
}

View File

@@ -10,7 +10,7 @@ go_library(
visibility = ["//beacon-chain:__subpackages__"],
deps = [
"//shared/event:go_default_library",
"//shared/interfaces:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
],
)

View File

@@ -7,7 +7,7 @@ import (
"time"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/interfaces"
)
const (
@@ -31,7 +31,7 @@ type BlockProcessedData struct {
// BlockRoot of the processed block.
BlockRoot [32]byte
// SignedBlock is the physical processed block.
SignedBlock *ethpb.SignedBeaconBlock
SignedBlock interfaces.SignedBeaconBlock
// Verified is true if the block's BLS contents have been verified.
Verified bool
}

View File

@@ -40,6 +40,7 @@ go_library(
"//shared/bls:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/interfaces:go_default_library",
"//shared/mathutil:go_default_library",
"//shared/params:go_default_library",
"//shared/sliceutil:go_default_library",

View File

@@ -5,22 +5,22 @@ import (
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
)
// VerifyNilBeaconBlock 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 VerifyNilBeaconBlock(b *ethpb.SignedBeaconBlock) error {
if b == nil {
func VerifyNilBeaconBlock(b interfaces.SignedBeaconBlock) error {
if b == nil || b.IsNil() {
return errors.New("signed beacon block can't be nil")
}
if b.Block == nil {
if b.Block().IsNil() {
return errors.New("beacon block can't be nil")
}
if b.Block.Body == nil {
if b.Block().Body().IsNil() {
return errors.New("beacon block body can't be nil")
}
return nil

View File

@@ -121,7 +121,7 @@ func ComputeWeakSubjectivityPeriod(st iface.ReadOnlyBeaconState) (types.Epoch, e
func IsWithinWeakSubjectivityPeriod(
currentEpoch types.Epoch, wsState iface.ReadOnlyBeaconState, wsCheckpoint *eth.WeakSubjectivityCheckpoint) (bool, error) {
// Make sure that incoming objects are not nil.
if wsState == nil || wsState.LatestBlockHeader() == nil || wsCheckpoint == nil {
if wsState == nil || wsState.IsNil() || wsState.LatestBlockHeader() == nil || wsCheckpoint == nil {
return false, errors.New("invalid weak subjectivity state or checkpoint")
}

View File

@@ -40,6 +40,7 @@ go_library(
"//shared/bytesutil:go_default_library",
"//shared/featureconfig:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/interfaces:go_default_library",
"//shared/mathutil:go_default_library",
"//shared/params:go_default_library",
"//shared/traceutil:go_default_library",
@@ -83,6 +84,7 @@ go_test(
"//shared/bls:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/interfaces:go_default_library",
"//shared/params:go_default_library",
"//shared/testutil:go_default_library",
"//shared/testutil/assert:go_default_library",

View File

@@ -10,6 +10,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/benchutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
"google.golang.org/protobuf/proto"
@@ -27,7 +28,7 @@ func BenchmarkExecuteStateTransition_FullBlock(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := coreState.ExecuteStateTransition(context.Background(), cleanStates[i], block)
_, err := coreState.ExecuteStateTransition(context.Background(), cleanStates[i], interfaces.NewWrappedSignedBeaconBlock(block))
require.NoError(b, err)
}
}
@@ -48,12 +49,12 @@ func BenchmarkExecuteStateTransition_WithCache(b *testing.B) {
require.NoError(b, helpers.UpdateCommitteeCache(beaconState, helpers.CurrentEpoch(beaconState)))
require.NoError(b, beaconState.SetSlot(currentSlot))
// Run the state transition once to populate the cache.
_, err = coreState.ExecuteStateTransition(context.Background(), beaconState, block)
_, err = coreState.ExecuteStateTransition(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(block))
require.NoError(b, err, "Failed to process block, benchmarks will fail")
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := coreState.ExecuteStateTransition(context.Background(), cleanStates[i], block)
_, err := coreState.ExecuteStateTransition(context.Background(), cleanStates[i], interfaces.NewWrappedSignedBeaconBlock(block))
require.NoError(b, err, "Failed to process block, benchmarks will fail")
}
}

View File

@@ -16,7 +16,7 @@ go_library(
"//beacon-chain/state/interface:go_default_library",
"//shared/featureconfig:go_default_library",
"//shared/fileutil:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"//shared/interfaces:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
],
)

View File

@@ -5,18 +5,18 @@ import (
"os"
"path"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/fileutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
)
// WriteBlockToDisk as a block ssz. Writes to temp directory. Debug!
func WriteBlockToDisk(block *ethpb.SignedBeaconBlock, failed bool) {
func WriteBlockToDisk(block interfaces.SignedBeaconBlock, failed bool) {
if !featureconfig.Get().WriteSSZStateTransitions {
return
}
filename := fmt.Sprintf("beacon_block_%d.ssz", block.Block.Slot)
filename := fmt.Sprintf("beacon_block_%d.ssz", block.Block().Slot())
if failed {
filename = "failed_" + filename
}

View File

@@ -8,6 +8,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -30,11 +31,11 @@ func TestSkipSlotCache_OK(t *testing.T) {
// with the state
blk, err := testutil.GenerateFullBlock(bState, privs, blkCfg, originalState.Slot()+10)
require.NoError(t, err)
executedState, err := state.ExecuteStateTransition(context.Background(), originalState, blk)
executedState, err := state.ExecuteStateTransition(context.Background(), originalState, interfaces.NewWrappedSignedBeaconBlock(blk))
require.NoError(t, err, "Could not run state transition")
originalState, ok := executedState.(*stateV0.BeaconState)
require.Equal(t, true, ok)
bState, err = state.ExecuteStateTransition(context.Background(), bState, blk)
bState, err = state.ExecuteStateTransition(context.Background(), bState, interfaces.NewWrappedSignedBeaconBlock(blk))
require.NoError(t, err, "Could not process state transition")
assert.DeepEqual(t, originalState.CloneInnerState(), bState.CloneInnerState(), "Skipped slots cache leads to different states")
@@ -56,7 +57,7 @@ func TestSkipSlotCache_ConcurrentMixup(t *testing.T) {
// with the state
blk, err := testutil.GenerateFullBlock(bState, privs, blkCfg, originalState.Slot()+10)
require.NoError(t, err)
executedState, err := state.ExecuteStateTransition(context.Background(), originalState, blk)
executedState, err := state.ExecuteStateTransition(context.Background(), originalState, interfaces.NewWrappedSignedBeaconBlock(blk))
require.NoError(t, err, "Could not run state transition")
originalState, ok := executedState.(*stateV0.BeaconState)
require.Equal(t, true, ok)
@@ -70,7 +71,7 @@ func TestSkipSlotCache_ConcurrentMixup(t *testing.T) {
signature, err := testutil.BlockSignature(originalState, blk.Block, privs)
require.NoError(t, err)
blk.Signature = signature.Marshal()
state1, err = state.ExecuteStateTransition(context.Background(), originalState.Copy(), blk)
state1, err = state.ExecuteStateTransition(context.Background(), originalState.Copy(), interfaces.NewWrappedSignedBeaconBlock(blk))
require.NoError(t, err, "Could not run state transition")
}
@@ -81,7 +82,7 @@ func TestSkipSlotCache_ConcurrentMixup(t *testing.T) {
signature, err := testutil.BlockSignature(originalState, blk.Block, privs)
require.NoError(t, err)
blk.Signature = signature.Marshal()
state2, err = state.ExecuteStateTransition(context.Background(), originalState.Copy(), blk)
state2, err = state.ExecuteStateTransition(context.Background(), originalState.Copy(), interfaces.NewWrappedSignedBeaconBlock(blk))
require.NoError(t, err, "Could not run state transition")
}

View File

@@ -10,7 +10,6 @@ import (
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
b "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
e "github.com/prysmaticlabs/prysm/beacon-chain/core/epoch"
@@ -18,6 +17,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/mathutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/traceutil"
@@ -25,25 +25,25 @@ import (
)
// processFunc is a function that processes a block with a given state. State is mutated.
type processFunc func(context.Context, iface.BeaconState, *ethpb.SignedBeaconBlock) (iface.BeaconState, error)
type processFunc func(context.Context, iface.BeaconState, interfaces.SignedBeaconBlock) (iface.BeaconState, error)
var processDepositsFunc = func(ctx context.Context, s iface.BeaconState, blk *ethpb.SignedBeaconBlock) (iface.BeaconState, error) {
return b.ProcessDeposits(ctx, s, blk.Block.Body.Deposits)
var processDepositsFunc = func(ctx context.Context, s iface.BeaconState, blk interfaces.SignedBeaconBlock) (iface.BeaconState, error) {
return b.ProcessDeposits(ctx, s, blk.Block().Body().Deposits())
}
var processProposerSlashingFunc = func(ctx context.Context, s iface.BeaconState, blk *ethpb.SignedBeaconBlock) (iface.BeaconState, error) {
return b.ProcessProposerSlashings(ctx, s, blk.Block.Body.ProposerSlashings, v.SlashValidator)
var processProposerSlashingFunc = func(ctx context.Context, s iface.BeaconState, blk interfaces.SignedBeaconBlock) (iface.BeaconState, error) {
return b.ProcessProposerSlashings(ctx, s, blk.Block().Body().ProposerSlashings(), v.SlashValidator)
}
var processAttesterSlashingFunc = func(ctx context.Context, s iface.BeaconState, blk *ethpb.SignedBeaconBlock) (iface.BeaconState, error) {
return b.ProcessAttesterSlashings(ctx, s, blk.Block.Body.AttesterSlashings, v.SlashValidator)
var processAttesterSlashingFunc = func(ctx context.Context, s iface.BeaconState, blk interfaces.SignedBeaconBlock) (iface.BeaconState, error) {
return b.ProcessAttesterSlashings(ctx, s, blk.Block().Body().AttesterSlashings(), v.SlashValidator)
}
var processEth1DataFunc = func(ctx context.Context, s iface.BeaconState, blk *ethpb.SignedBeaconBlock) (iface.BeaconState, error) {
return b.ProcessEth1DataInBlock(ctx, s, blk.Block.Body.Eth1Data)
var processEth1DataFunc = func(ctx context.Context, s iface.BeaconState, blk interfaces.SignedBeaconBlock) (iface.BeaconState, error) {
return b.ProcessEth1DataInBlock(ctx, s, blk.Block().Body().Eth1Data())
}
var processExitFunc = func(ctx context.Context, s iface.BeaconState, blk *ethpb.SignedBeaconBlock) (iface.BeaconState, error) {
return b.ProcessVoluntaryExits(ctx, s, blk.Block.Body.VoluntaryExits)
var processExitFunc = func(ctx context.Context, s iface.BeaconState, blk interfaces.SignedBeaconBlock) (iface.BeaconState, error) {
return b.ProcessVoluntaryExits(ctx, s, blk.Block().Body().VoluntaryExits())
}
// This defines the processing block routine as outlined in eth2 spec:
@@ -81,12 +81,12 @@ var processingPipeline = []processFunc{
func ExecuteStateTransition(
ctx context.Context,
state iface.BeaconState,
signed *ethpb.SignedBeaconBlock,
signed interfaces.SignedBeaconBlock,
) (iface.BeaconState, error) {
if ctx.Err() != nil {
return nil, ctx.Err()
}
if signed == nil || signed.Block == nil {
if signed == nil || signed.IsNil() || signed.Block().IsNil() {
return nil, errors.New("nil block")
}
@@ -179,7 +179,7 @@ func ProcessSlotsUsingNextSlotCache(
}
// If the next slot state is not nil (i.e. cache hit).
// We replace next slot state with parent state.
if nextSlotState != nil {
if nextSlotState != nil && !nextSlotState.IsNil() {
parentState = nextSlotState
}
@@ -208,7 +208,7 @@ func ProcessSlotsUsingNextSlotCache(
func ProcessSlots(ctx context.Context, state iface.BeaconState, slot types.Slot) (iface.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "core.state.ProcessSlots")
defer span.End()
if state == nil {
if state == nil || state.IsNil() {
return nil, errors.New("nil state")
}
span.AddAttributes(trace.Int64Attribute("slots", int64(slot)-int64(state.Slot())))
@@ -232,7 +232,7 @@ func ProcessSlots(ctx context.Context, state iface.BeaconState, slot types.Slot)
return nil, err
}
if cachedState != nil && cachedState.Slot() < slot {
if cachedState != nil && !cachedState.IsNil() && cachedState.Slot() < slot {
highestSlot = cachedState.Slot()
state = cachedState
}
@@ -241,7 +241,7 @@ func ProcessSlots(ctx context.Context, state iface.BeaconState, slot types.Slot)
if err != nil {
return nil, err
}
if cachedState != nil && cachedState.Slot() < slot {
if cachedState != nil && !cachedState.IsNil() && cachedState.Slot() < slot {
highestSlot = cachedState.Slot()
state = cachedState
}
@@ -308,7 +308,7 @@ func ProcessSlots(ctx context.Context, state iface.BeaconState, slot types.Slot)
func ProcessBlock(
ctx context.Context,
state iface.BeaconState,
signed *ethpb.SignedBeaconBlock,
signed interfaces.SignedBeaconBlock,
) (iface.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "core.state.ProcessBlock")
defer span.End()
@@ -329,40 +329,40 @@ func ProcessBlock(
}
// VerifyOperationLengths verifies that block operation lengths are valid.
func VerifyOperationLengths(_ context.Context, state iface.BeaconState, b *ethpb.SignedBeaconBlock) (iface.BeaconState, error) {
func VerifyOperationLengths(_ context.Context, state iface.BeaconState, b interfaces.SignedBeaconBlock) (iface.BeaconState, error) {
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
return nil, err
}
body := b.Block.Body
body := b.Block().Body()
if uint64(len(body.ProposerSlashings)) > params.BeaconConfig().MaxProposerSlashings {
if uint64(len(body.ProposerSlashings())) > params.BeaconConfig().MaxProposerSlashings {
return nil, fmt.Errorf(
"number of proposer slashings (%d) in block body exceeds allowed threshold of %d",
len(body.ProposerSlashings),
len(body.ProposerSlashings()),
params.BeaconConfig().MaxProposerSlashings,
)
}
if uint64(len(body.AttesterSlashings)) > params.BeaconConfig().MaxAttesterSlashings {
if uint64(len(body.AttesterSlashings())) > params.BeaconConfig().MaxAttesterSlashings {
return nil, fmt.Errorf(
"number of attester slashings (%d) in block body exceeds allowed threshold of %d",
len(body.AttesterSlashings),
len(body.AttesterSlashings()),
params.BeaconConfig().MaxAttesterSlashings,
)
}
if uint64(len(body.Attestations)) > params.BeaconConfig().MaxAttestations {
if uint64(len(body.Attestations())) > params.BeaconConfig().MaxAttestations {
return nil, fmt.Errorf(
"number of attestations (%d) in block body exceeds allowed threshold of %d",
len(body.Attestations),
len(body.Attestations()),
params.BeaconConfig().MaxAttestations,
)
}
if uint64(len(body.VoluntaryExits)) > params.BeaconConfig().MaxVoluntaryExits {
if uint64(len(body.VoluntaryExits())) > params.BeaconConfig().MaxVoluntaryExits {
return nil, fmt.Errorf(
"number of voluntary exits (%d) in block body exceeds allowed threshold of %d",
len(body.VoluntaryExits),
len(body.VoluntaryExits()),
params.BeaconConfig().MaxVoluntaryExits,
)
}
@@ -375,9 +375,9 @@ func VerifyOperationLengths(_ context.Context, state iface.BeaconState, b *ethpb
}
maxDeposits := mathutil.Min(params.BeaconConfig().MaxDeposits, eth1Data.DepositCount-state.Eth1DepositIndex())
// Verify outstanding deposits are processed up to max number of deposits
if uint64(len(body.Deposits)) != maxDeposits {
if uint64(len(body.Deposits())) != maxDeposits {
return nil, fmt.Errorf("incorrect outstanding deposits in block body, wanted: %d, got: %d",
maxDeposits, len(body.Deposits))
maxDeposits, len(body.Deposits()))
}
return state, nil
@@ -399,7 +399,7 @@ func ProcessEpochPrecompute(ctx context.Context, state iface.BeaconState) (iface
defer span.End()
span.AddAttributes(trace.Int64Attribute("epoch", int64(helpers.CurrentEpoch(state))))
if state == nil {
if state == nil || state.IsNil() {
return nil, errors.New("nil state")
}
vp, bp, err := precompute.New(ctx, state)

View File

@@ -8,6 +8,7 @@ import (
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
"github.com/prysmaticlabs/prysm/shared/interfaces"
)
func TestFuzzExecuteStateTransition_1000(t *testing.T) {
@@ -21,7 +22,7 @@ func TestFuzzExecuteStateTransition_1000(t *testing.T) {
for i := 0; i < 1000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(sb)
s, err := ExecuteStateTransition(ctx, state, sb)
s, err := ExecuteStateTransition(ctx, state, interfaces.NewWrappedSignedBeaconBlock(sb))
if err != nil && s != nil {
t.Fatalf("state should be nil on err. found: %v on error: %v for state: %v and signed block: %v", s, err, state, sb)
}
@@ -39,7 +40,7 @@ func TestFuzzCalculateStateRoot_1000(t *testing.T) {
for i := 0; i < 1000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(sb)
stateRoot, err := CalculateStateRoot(ctx, state, sb)
stateRoot, err := CalculateStateRoot(ctx, state, interfaces.NewWrappedSignedBeaconBlock(sb))
if err != nil && stateRoot != [32]byte{} {
t.Fatalf("state root should be empty on err. found: %v on error: %v for signed block: %v", stateRoot, err, sb)
}
@@ -91,7 +92,7 @@ func TestFuzzProcessBlock_1000(t *testing.T) {
for i := 0; i < 1000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(sb)
s, err := ProcessBlock(ctx, state, sb)
s, err := ProcessBlock(ctx, state, interfaces.NewWrappedSignedBeaconBlock(sb))
if err != nil && s != nil {
t.Fatalf("state should be nil on err. found: %v on error: %v for signed block: %v", s, err, sb)
}
@@ -109,7 +110,7 @@ func TestFuzzProcessOperations_1000(t *testing.T) {
for i := 0; i < 1000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(bb)
s, err := ProcessBlock(ctx, state, bb)
s, err := ProcessBlock(ctx, state, interfaces.NewWrappedSignedBeaconBlock(bb))
if err != nil && s != nil {
t.Fatalf("state should be nil on err. found: %v on error: %v for block body: %v", s, err, bb)
}
@@ -127,7 +128,7 @@ func TestFuzzprocessOperationsNoVerify_1000(t *testing.T) {
for i := 0; i < 1000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(bb)
s, err := ProcessOperationsNoVerifyAttsSigs(ctx, state, bb)
s, err := ProcessOperationsNoVerifyAttsSigs(ctx, state, interfaces.NewWrappedSignedBeaconBlock(bb))
if err != nil && s != nil {
t.Fatalf("state should be nil on err. found: %v on error: %v for block body: %v", s, err, bb)
}
@@ -144,7 +145,7 @@ func TestFuzzverifyOperationLengths_10000(t *testing.T) {
for i := 0; i < 10000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(bb)
_, err := VerifyOperationLengths(context.Background(), state, bb)
_, err := VerifyOperationLengths(context.Background(), state, interfaces.NewWrappedSignedBeaconBlock(bb))
_ = err
}
}
@@ -188,7 +189,7 @@ func TestFuzzProcessBlockForStateRoot_1000(t *testing.T) {
for i := 0; i < 1000; i++ {
fuzzer.Fuzz(state)
fuzzer.Fuzz(sb)
s, err := ProcessBlockForStateRoot(ctx, state, sb)
s, err := ProcessBlockForStateRoot(ctx, state, interfaces.NewWrappedSignedBeaconBlock(sb))
if err != nil && s != nil {
t.Fatalf("state should be nil on err. found: %v on error: %v for signed block: %v", s, err, sb)
}

View File

@@ -6,7 +6,6 @@ import (
"fmt"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
b "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state/interop"
@@ -14,6 +13,7 @@ import (
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/traceutil"
"go.opencensus.io/trace"
)
@@ -42,12 +42,12 @@ import (
func ExecuteStateTransitionNoVerifyAnySig(
ctx context.Context,
state iface.BeaconState,
signed *ethpb.SignedBeaconBlock,
signed interfaces.SignedBeaconBlock,
) (*bls.SignatureSet, iface.BeaconState, error) {
if ctx.Err() != nil {
return nil, nil, ctx.Err()
}
if signed == nil || signed.Block == nil {
if signed == nil || signed.IsNil() || signed.Block().IsNil() {
return nil, nil, errors.New("nil block")
}
@@ -59,12 +59,12 @@ func ExecuteStateTransitionNoVerifyAnySig(
interop.WriteStateToDisk(state)
if featureconfig.Get().EnableNextSlotStateCache {
state, err = ProcessSlotsUsingNextSlotCache(ctx, state, signed.Block.ParentRoot, signed.Block.Slot)
state, err = ProcessSlotsUsingNextSlotCache(ctx, state, signed.Block().ParentRoot(), signed.Block().Slot())
if err != nil {
return nil, nil, errors.Wrap(err, "could not process slots")
}
} else {
state, err = ProcessSlots(ctx, state, signed.Block.Slot)
state, err = ProcessSlots(ctx, state, signed.Block().Slot())
if err != nil {
return nil, nil, errors.Wrap(err, "could not process slot")
}
@@ -81,9 +81,9 @@ func ExecuteStateTransitionNoVerifyAnySig(
if err != nil {
return nil, nil, err
}
if !bytes.Equal(postStateRoot[:], signed.Block.StateRoot) {
if !bytes.Equal(postStateRoot[:], signed.Block().StateRoot()) {
return nil, nil, fmt.Errorf("could not validate state root, wanted: %#x, received: %#x",
postStateRoot[:], signed.Block.StateRoot)
postStateRoot[:], signed.Block().StateRoot())
}
return set, state, nil
@@ -113,7 +113,7 @@ func ExecuteStateTransitionNoVerifyAnySig(
func CalculateStateRoot(
ctx context.Context,
state iface.BeaconState,
signed *ethpb.SignedBeaconBlock,
signed interfaces.SignedBeaconBlock,
) ([32]byte, error) {
ctx, span := trace.StartSpan(ctx, "core.state.CalculateStateRoot")
defer span.End()
@@ -121,10 +121,10 @@ func CalculateStateRoot(
traceutil.AnnotateError(span, ctx.Err())
return [32]byte{}, ctx.Err()
}
if state == nil {
if state == nil || state.IsNil() {
return [32]byte{}, errors.New("nil state")
}
if signed == nil || signed.Block == nil {
if signed == nil || signed.IsNil() || signed.Block().IsNil() {
return [32]byte{}, errors.New("nil block")
}
@@ -134,12 +134,12 @@ func CalculateStateRoot(
// Execute per slots transition.
var err error
if featureconfig.Get().EnableNextSlotStateCache {
state, err = ProcessSlotsUsingNextSlotCache(ctx, state, signed.Block.ParentRoot, signed.Block.Slot)
state, err = ProcessSlotsUsingNextSlotCache(ctx, state, signed.Block().ParentRoot(), signed.Block().Slot())
if err != nil {
return [32]byte{}, errors.Wrap(err, "could not process slots")
}
} else {
state, err = ProcessSlots(ctx, state, signed.Block.Slot)
state, err = ProcessSlots(ctx, state, signed.Block().Slot())
if err != nil {
return [32]byte{}, errors.Wrap(err, "could not process slot")
}
@@ -169,7 +169,7 @@ func CalculateStateRoot(
func ProcessBlockNoVerifyAnySig(
ctx context.Context,
state iface.BeaconState,
signed *ethpb.SignedBeaconBlock,
signed interfaces.SignedBeaconBlock,
) (*bls.SignatureSet, iface.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "core.state.ProcessBlockNoVerifyAnySig")
defer span.End()
@@ -177,23 +177,23 @@ func ProcessBlockNoVerifyAnySig(
return nil, nil, err
}
blk := signed.Block
blk := signed.Block()
state, err := ProcessBlockForStateRoot(ctx, state, signed)
if err != nil {
return nil, nil, err
}
bSet, err := b.BlockSignatureSet(state, blk.ProposerIndex, signed.Signature, blk.HashTreeRoot)
bSet, err := b.BlockSignatureSet(state, blk.ProposerIndex(), signed.Signature(), blk.HashTreeRoot)
if err != nil {
traceutil.AnnotateError(span, err)
return nil, nil, errors.Wrap(err, "could not retrieve block signature set")
}
rSet, err := b.RandaoSignatureSet(state, signed.Block.Body.RandaoReveal)
rSet, err := b.RandaoSignatureSet(state, signed.Block().Body().RandaoReveal())
if err != nil {
traceutil.AnnotateError(span, err)
return nil, nil, errors.Wrap(err, "could not retrieve randao signature set")
}
aSet, err := b.AttestationSignatureSet(ctx, state, signed.Block.Body.Attestations)
aSet, err := b.AttestationSignatureSet(ctx, state, signed.Block().Body().Attestations())
if err != nil {
return nil, nil, errors.Wrap(err, "could not retrieve attestation signature set")
}
@@ -229,7 +229,7 @@ func ProcessBlockNoVerifyAnySig(
func ProcessOperationsNoVerifyAttsSigs(
ctx context.Context,
state iface.BeaconState,
signedBeaconBlock *ethpb.SignedBeaconBlock) (iface.BeaconState, error) {
signedBeaconBlock interfaces.SignedBeaconBlock) (iface.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "core.state.ProcessOperationsNoVerifyAttsSigs")
defer span.End()
if err := helpers.VerifyNilBeaconBlock(signedBeaconBlock); err != nil {
@@ -240,11 +240,11 @@ func ProcessOperationsNoVerifyAttsSigs(
return nil, errors.Wrap(err, "could not verify operation lengths")
}
state, err := b.ProcessProposerSlashings(ctx, state, signedBeaconBlock.Block.Body.ProposerSlashings, v.SlashValidator)
state, err := b.ProcessProposerSlashings(ctx, state, signedBeaconBlock.Block().Body().ProposerSlashings(), v.SlashValidator)
if err != nil {
return nil, errors.Wrap(err, "could not process block proposer slashings")
}
state, err = b.ProcessAttesterSlashings(ctx, state, signedBeaconBlock.Block.Body.AttesterSlashings, v.SlashValidator)
state, err = b.ProcessAttesterSlashings(ctx, state, signedBeaconBlock.Block().Body().AttesterSlashings(), v.SlashValidator)
if err != nil {
return nil, errors.Wrap(err, "could not process block attester slashings")
}
@@ -252,11 +252,11 @@ func ProcessOperationsNoVerifyAttsSigs(
if err != nil {
return nil, errors.Wrap(err, "could not process block attestations")
}
state, err = b.ProcessDeposits(ctx, state, signedBeaconBlock.Block.Body.Deposits)
state, err = b.ProcessDeposits(ctx, state, signedBeaconBlock.Block().Body().Deposits())
if err != nil {
return nil, errors.Wrap(err, "could not process block validator deposits")
}
state, err = b.ProcessVoluntaryExits(ctx, state, signedBeaconBlock.Block.Body.VoluntaryExits)
state, err = b.ProcessVoluntaryExits(ctx, state, signedBeaconBlock.Block().Body().VoluntaryExits())
if err != nil {
return nil, errors.Wrap(err, "could not process validator exits")
}
@@ -269,7 +269,7 @@ func ProcessOperationsNoVerifyAttsSigs(
func ProcessBlockForStateRoot(
ctx context.Context,
state iface.BeaconState,
signed *ethpb.SignedBeaconBlock,
signed interfaces.SignedBeaconBlock,
) (iface.BeaconState, error) {
ctx, span := trace.StartSpan(ctx, "core.state.ProcessBlockForStateRoot")
defer span.End()
@@ -277,25 +277,25 @@ func ProcessBlockForStateRoot(
return nil, err
}
blk := signed.Block
body := blk.Body
blk := signed.Block()
body := blk.Body()
bodyRoot, err := body.HashTreeRoot()
if err != nil {
return nil, err
}
state, err = b.ProcessBlockHeaderNoVerify(state, blk.Slot, blk.ProposerIndex, blk.ParentRoot, bodyRoot[:])
state, err = b.ProcessBlockHeaderNoVerify(state, blk.Slot(), blk.ProposerIndex(), blk.ParentRoot(), bodyRoot[:])
if err != nil {
traceutil.AnnotateError(span, err)
return nil, errors.Wrap(err, "could not process block header")
}
state, err = b.ProcessRandaoNoVerify(state, signed.Block.Body.RandaoReveal)
state, err = b.ProcessRandaoNoVerify(state, signed.Block().Body().RandaoReveal())
if err != nil {
traceutil.AnnotateError(span, err)
return nil, errors.Wrap(err, "could not verify and process randao")
}
state, err = b.ProcessEth1DataInBlock(ctx, state, signed.Block.Body.Eth1Data)
state, err = b.ProcessEth1DataInBlock(ctx, state, signed.Block().Body().Eth1Data())
if err != nil {
traceutil.AnnotateError(span, err)
return nil, errors.Wrap(err, "could not process eth1 data")

View File

@@ -8,6 +8,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -50,7 +51,7 @@ func TestExecuteStateTransitionNoVerify_FullProcess(t *testing.T) {
block.Block.Body.RandaoReveal = randaoReveal
block.Block.Body.Eth1Data = eth1Data
stateRoot, err := state.CalculateStateRoot(context.Background(), beaconState, block)
stateRoot, err := state.CalculateStateRoot(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(block))
require.NoError(t, err)
block.Block.StateRoot = stateRoot[:]
@@ -59,7 +60,7 @@ func TestExecuteStateTransitionNoVerify_FullProcess(t *testing.T) {
require.NoError(t, err)
block.Signature = sig.Marshal()
set, _, err := state.ExecuteStateTransitionNoVerifyAnySig(context.Background(), beaconState, block)
set, _, err := state.ExecuteStateTransitionNoVerifyAnySig(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(block))
assert.NoError(t, err)
verified, err := set.Verify()
assert.NoError(t, err)
@@ -102,7 +103,7 @@ func TestExecuteStateTransitionNoVerifySignature_CouldNotVerifyStateRoot(t *test
block.Block.Body.RandaoReveal = randaoReveal
block.Block.Body.Eth1Data = eth1Data
stateRoot, err := state.CalculateStateRoot(context.Background(), beaconState, block)
stateRoot, err := state.CalculateStateRoot(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(block))
require.NoError(t, err)
block.Block.StateRoot = stateRoot[:]
@@ -112,13 +113,13 @@ func TestExecuteStateTransitionNoVerifySignature_CouldNotVerifyStateRoot(t *test
block.Signature = sig.Marshal()
block.Block.StateRoot = bytesutil.PadTo([]byte{'a'}, 32)
_, _, err = state.ExecuteStateTransitionNoVerifyAnySig(context.Background(), beaconState, block)
_, _, err = state.ExecuteStateTransitionNoVerifyAnySig(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(block))
require.ErrorContains(t, "could not validate state root", err)
}
func TestProcessBlockNoVerify_PassesProcessingConditions(t *testing.T) {
beaconState, block, _, _, _ := createFullBlockWithOperations(t)
set, _, err := state.ProcessBlockNoVerifyAnySig(context.Background(), beaconState, block)
set, _, err := state.ProcessBlockNoVerifyAnySig(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(block))
require.NoError(t, err)
// Test Signature set verifies.
verified, err := set.Verify()

View File

@@ -19,6 +19,7 @@ import (
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/hashutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -43,7 +44,7 @@ func TestExecuteStateTransition_IncorrectSlot(t *testing.T) {
},
}
want := "expected state.slot"
_, err = state.ExecuteStateTransition(context.Background(), beaconState, block)
_, err = state.ExecuteStateTransition(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(block))
assert.ErrorContains(t, want, err)
}
@@ -86,7 +87,7 @@ func TestExecuteStateTransition_FullProcess(t *testing.T) {
block.Block.Body.RandaoReveal = randaoReveal
block.Block.Body.Eth1Data = eth1Data
stateRoot, err := state.CalculateStateRoot(context.Background(), beaconState, block)
stateRoot, err := state.CalculateStateRoot(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(block))
require.NoError(t, err)
block.Block.StateRoot = stateRoot[:]
@@ -95,7 +96,7 @@ func TestExecuteStateTransition_FullProcess(t *testing.T) {
require.NoError(t, err)
block.Signature = sig.Marshal()
beaconState, err = state.ExecuteStateTransition(context.Background(), beaconState, block)
beaconState, err = state.ExecuteStateTransition(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(block))
require.NoError(t, err)
assert.Equal(t, params.BeaconConfig().SlotsPerEpoch, beaconState.Slot(), "Unexpected Slot number")
@@ -134,7 +135,7 @@ func TestProcessBlock_IncorrectProposerSlashing(t *testing.T) {
beaconState, err = state.ProcessSlots(context.Background(), beaconState, 1)
require.NoError(t, err)
want := "could not verify proposer slashing"
_, err = state.ProcessBlock(context.Background(), beaconState, block)
_, err = state.ProcessBlock(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(block))
assert.ErrorContains(t, want, err)
}
@@ -161,7 +162,7 @@ func TestProcessBlock_IncorrectProcessBlockAttestations(t *testing.T) {
require.NoError(t, err)
want := "could not verify attestation"
_, err = state.ProcessBlock(context.Background(), beaconState, block)
_, err = state.ProcessBlock(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(block))
assert.ErrorContains(t, want, err)
}
@@ -242,7 +243,7 @@ func TestProcessBlock_IncorrectProcessExits(t *testing.T) {
cp.Root = []byte("hello-world")
require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cp))
require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
_, err = state.VerifyOperationLengths(context.Background(), beaconState, block)
_, err = state.VerifyOperationLengths(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(block))
wanted := "number of voluntary exits (17) in block body exceeds allowed threshold of 16"
assert.ErrorContains(t, wanted, err)
}
@@ -423,7 +424,7 @@ func TestProcessBlock_PassesProcessingConditions(t *testing.T) {
beaconState, block, _, proposerSlashings, exits := createFullBlockWithOperations(t)
exit := exits[0]
beaconState, err := state.ProcessBlock(context.Background(), beaconState, block)
beaconState, err := state.ProcessBlock(context.Background(), beaconState, interfaces.NewWrappedSignedBeaconBlock(block))
require.NoError(t, err, "Expected block to pass processing conditions")
v, err := beaconState.ValidatorAtIndex(proposerSlashings[0].Header_1.Header.ProposerIndex)
@@ -615,7 +616,7 @@ func BenchmarkProcessBlk_65536Validators_FullBlock(b *testing.B) {
b.ResetTimer()
for n := 0; n < b.N; n++ {
_, err := state.ProcessBlock(context.Background(), s, blk)
_, err := state.ProcessBlock(context.Background(), s, interfaces.NewWrappedSignedBeaconBlock(blk))
require.NoError(b, err)
// Reset state fields to process block again
v := s.Validators()
@@ -699,7 +700,7 @@ func TestProcessBlk_AttsBasedOnValidatorCount(t *testing.T) {
params.OverrideBeaconConfig(config)
require.NoError(t, s.SetSlot(s.Slot()+1))
_, err = state.ProcessBlock(context.Background(), s, blk)
_, err = state.ProcessBlock(context.Background(), s, interfaces.NewWrappedSignedBeaconBlock(blk))
require.NoError(t, err)
}
@@ -746,7 +747,7 @@ func TestProcessBlock_OverMaxProposerSlashings(t *testing.T) {
}
want := fmt.Sprintf("number of proposer slashings (%d) in block body exceeds allowed threshold of %d",
len(b.Block.Body.ProposerSlashings), params.BeaconConfig().MaxProposerSlashings)
_, err := state.VerifyOperationLengths(context.Background(), &stateV0.BeaconState{}, b)
_, err := state.VerifyOperationLengths(context.Background(), &stateV0.BeaconState{}, interfaces.NewWrappedSignedBeaconBlock(b))
assert.ErrorContains(t, want, err)
}
@@ -761,7 +762,7 @@ func TestProcessBlock_OverMaxAttesterSlashings(t *testing.T) {
}
want := fmt.Sprintf("number of attester slashings (%d) in block body exceeds allowed threshold of %d",
len(b.Block.Body.AttesterSlashings), params.BeaconConfig().MaxAttesterSlashings)
_, err := state.VerifyOperationLengths(context.Background(), &stateV0.BeaconState{}, b)
_, err := state.VerifyOperationLengths(context.Background(), &stateV0.BeaconState{}, interfaces.NewWrappedSignedBeaconBlock(b))
assert.ErrorContains(t, want, err)
}
@@ -775,7 +776,7 @@ func TestProcessBlock_OverMaxAttestations(t *testing.T) {
}
want := fmt.Sprintf("number of attestations (%d) in block body exceeds allowed threshold of %d",
len(b.Block.Body.Attestations), params.BeaconConfig().MaxAttestations)
_, err := state.VerifyOperationLengths(context.Background(), &stateV0.BeaconState{}, b)
_, err := state.VerifyOperationLengths(context.Background(), &stateV0.BeaconState{}, interfaces.NewWrappedSignedBeaconBlock(b))
assert.ErrorContains(t, want, err)
}
@@ -790,7 +791,7 @@ func TestProcessBlock_OverMaxVoluntaryExits(t *testing.T) {
}
want := fmt.Sprintf("number of voluntary exits (%d) in block body exceeds allowed threshold of %d",
len(b.Block.Body.VoluntaryExits), maxExits)
_, err := state.VerifyOperationLengths(context.Background(), &stateV0.BeaconState{}, b)
_, err := state.VerifyOperationLengths(context.Background(), &stateV0.BeaconState{}, interfaces.NewWrappedSignedBeaconBlock(b))
assert.ErrorContains(t, want, err)
}
@@ -810,7 +811,7 @@ func TestProcessBlock_IncorrectDeposits(t *testing.T) {
}
want := fmt.Sprintf("incorrect outstanding deposits in block body, wanted: %d, got: %d",
s.Eth1Data().DepositCount-s.Eth1DepositIndex(), len(b.Block.Body.Deposits))
_, err = state.VerifyOperationLengths(context.Background(), s, b)
_, err = state.VerifyOperationLengths(context.Background(), s, interfaces.NewWrappedSignedBeaconBlock(b))
assert.ErrorContains(t, want, err)
}

View File

@@ -60,6 +60,7 @@ go_test(
deps = [
"//beacon-chain/db/kv:go_default_library",
"//shared/cmd:go_default_library",
"//shared/interfaces:go_default_library",
"//shared/testutil:go_default_library",
"//shared/testutil/assert:go_default_library",
"//shared/testutil/require:go_default_library",

View File

@@ -6,7 +6,6 @@ import (
"context"
"github.com/prysmaticlabs/prysm/beacon-chain/db/kv"
"github.com/prysmaticlabs/prysm/beacon-chain/db/slasherkv"
)
// NewDB initializes a new DB.
@@ -20,8 +19,3 @@ func NewDB(ctx context.Context, dirPath string, config *kv.Config) (Database, er
func NewDBFilename(dirPath string) string {
return kv.KVStoreDatafilePath(dirPath)
}
// NewSlasherDB initializes a new DB for slasher.
func NewSlasherDB(ctx context.Context, dirPath string, config *slasherkv.Config) (SlasherDatabase, error) {
return slasherkv.NewKVStore(ctx, dirPath, config)
}

View File

@@ -16,6 +16,7 @@ go_library(
"//proto/beacon/db:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/backuputil:go_default_library",
"//shared/interfaces:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",

View File

@@ -16,21 +16,22 @@ import (
"github.com/prysmaticlabs/prysm/proto/beacon/db"
ethereum_beacon_p2p_v1 "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/backuputil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
)
// ReadOnlyDatabase defines a struct which only has read access to database methods.
type ReadOnlyDatabase interface {
// Block related methods.
Block(ctx context.Context, blockRoot [32]byte) (*eth.SignedBeaconBlock, error)
Blocks(ctx context.Context, f *filters.QueryFilter) ([]*eth.SignedBeaconBlock, [][32]byte, error)
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, []*eth.SignedBeaconBlock, error)
BlocksBySlot(ctx context.Context, slot types.Slot) (bool, []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) (*eth.SignedBeaconBlock, error)
GenesisBlock(ctx context.Context) (interfaces.SignedBeaconBlock, error)
IsFinalizedBlock(ctx context.Context, blockRoot [32]byte) bool
FinalizedChildBlock(ctx context.Context, blockRoot [32]byte) (*eth.SignedBeaconBlock, error)
HighestSlotBlocksBelow(ctx context.Context, slot types.Slot) ([]*eth.SignedBeaconBlock, error)
FinalizedChildBlock(ctx context.Context, blockRoot [32]byte) (interfaces.SignedBeaconBlock, error)
HighestSlotBlocksBelow(ctx context.Context, slot types.Slot) ([]interfaces.SignedBeaconBlock, error)
// State related methods.
State(ctx context.Context, blockRoot [32]byte) (iface.BeaconState, error)
GenesisState(ctx context.Context) (iface.BeaconState, error)
@@ -64,8 +65,8 @@ type NoHeadAccessDatabase interface {
ReadOnlyDatabase
// Block related methods.
SaveBlock(ctx context.Context, block *eth.SignedBeaconBlock) error
SaveBlocks(ctx context.Context, blocks []*eth.SignedBeaconBlock) error
SaveBlock(ctx context.Context, block interfaces.SignedBeaconBlock) error
SaveBlocks(ctx context.Context, blocks []interfaces.SignedBeaconBlock) error
SaveGenesisBlockRoot(ctx context.Context, blockRoot [32]byte) error
// State related methods.
SaveState(ctx context.Context, state iface.ReadOnlyBeaconState, blockRoot [32]byte) error
@@ -97,7 +98,7 @@ type HeadAccessDatabase interface {
NoHeadAccessDatabase
// Block related methods.
HeadBlock(ctx context.Context) (*eth.SignedBeaconBlock, error)
HeadBlock(ctx context.Context) (interfaces.SignedBeaconBlock, error)
SaveHeadBlockRoot(ctx context.Context, blockRoot [32]byte) error
// Genesis operations.

View File

@@ -17,11 +17,10 @@ go_library(
"//proto/beacon/db:go_default_library",
"//proto/beacon/p2p/v1:go_default_library",
"//shared/featureconfig:go_default_library",
"//shared/interfaces:go_default_library",
"//shared/traceutil:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_ferranbt_fastssz//:go_default_library",
"@com_github_golang_protobuf//jsonpb:go_default_library_gen",
"@com_github_golang_protobuf//proto:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
@@ -29,5 +28,6 @@ go_library(
"@in_gopkg_confluentinc_confluent_kafka_go_v1//kafka/librdkafka:go_default_library",
"@in_gopkg_errgo_v2//fmt/errors:go_default_library",
"@io_opencensus_go//trace:go_default_library",
"@org_golang_google_protobuf//encoding/protojson:go_default_library",
],
)

View File

@@ -3,24 +3,22 @@
package kafka
import (
"bytes"
"context"
fssz "github.com/ferranbt/fastssz"
"github.com/golang/protobuf/jsonpb"
"github.com/golang/protobuf/proto"
eth "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/db/iface"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/traceutil"
"go.opencensus.io/trace"
jsonpb "google.golang.org/protobuf/encoding/protojson"
"gopkg.in/confluentinc/confluent-kafka-go.v1/kafka"
_ "gopkg.in/confluentinc/confluent-kafka-go.v1/kafka/librdkafka" // Required for c++ kafka library.
"gopkg.in/errgo.v2/fmt/errors"
)
var _ iface.Database = (*Exporter)(nil)
var marshaler = &jsonpb.Marshaler{}
var marshaler = jsonpb.MarshalOptions{}
// Exporter wraps a database interface and exports certain objects to kafka topics.
type Exporter struct {
@@ -35,7 +33,6 @@ func Wrap(db iface.Database) (iface.Database, error) {
log.Debug("Empty Kafka bootstrap servers list, database was not wrapped with Kafka exporter")
return db, nil
}
p, err := kafka.NewProducer(&kafka.ConfigMap{"bootstrap.servers": featureconfig.Get().KafkaBootstrapServers})
if err != nil {
return nil, err
@@ -44,18 +41,18 @@ func Wrap(db iface.Database) (iface.Database, error) {
return &Exporter{db: db, p: p}, nil
}
func (e Exporter) publish(ctx context.Context, topic string, msg proto.Message) error {
func (e Exporter) publish(ctx context.Context, topic string, msg interfaces.SignedBeaconBlock) error {
ctx, span := trace.StartSpan(ctx, "kafka.publish")
defer span.End()
buf := bytes.NewBuffer(nil)
if err := marshaler.Marshal(buf, msg); err != nil {
var err error
var buf []byte
if buf, err = marshaler.Marshal(msg.Proto()); err != nil {
traceutil.AnnotateError(span, err)
return err
}
var key [32]byte
var err error
if v, ok := msg.(fssz.HashRoot); ok {
key, err = v.HashTreeRoot()
} else {
@@ -70,7 +67,7 @@ func (e Exporter) publish(ctx context.Context, topic string, msg proto.Message)
TopicPartition: kafka.TopicPartition{
Topic: &topic,
},
Value: buf.Bytes(),
Value: buf,
Key: key[:],
}, nil); err != nil {
traceutil.AnnotateError(span, err)
@@ -86,7 +83,7 @@ func (e Exporter) Close() error {
}
// SaveBlock publishes to the kafka topic for beacon blocks.
func (e Exporter) SaveBlock(ctx context.Context, block *eth.SignedBeaconBlock) error {
func (e Exporter) SaveBlock(ctx context.Context, block interfaces.SignedBeaconBlock) error {
go func() {
if err := e.publish(ctx, "beacon_block", block); err != nil {
log.WithError(err).Error("Failed to publish block")
@@ -97,7 +94,7 @@ func (e Exporter) SaveBlock(ctx context.Context, block *eth.SignedBeaconBlock) e
}
// SaveBlocks publishes to the kafka topic for beacon blocks.
func (e Exporter) SaveBlocks(ctx context.Context, blocks []*eth.SignedBeaconBlock) error {
func (e Exporter) SaveBlocks(ctx context.Context, blocks []interfaces.SignedBeaconBlock) error {
go func() {
for _, block := range blocks {
if err := e.publish(ctx, "beacon_block", block); err != nil {

View File

@@ -11,6 +11,7 @@ import (
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/proto/beacon/db"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/interfaces"
)
// DatabasePath -- passthrough.
@@ -29,17 +30,17 @@ func (e Exporter) Backup(ctx context.Context, outputDir string) error {
}
// Block -- passthrough.
func (e Exporter) Block(ctx context.Context, blockRoot [32]byte) (*eth.SignedBeaconBlock, error) {
func (e Exporter) Block(ctx context.Context, blockRoot [32]byte) (interfaces.SignedBeaconBlock, error) {
return e.db.Block(ctx, blockRoot)
}
// HeadBlock -- passthrough.
func (e Exporter) HeadBlock(ctx context.Context) (*eth.SignedBeaconBlock, error) {
func (e Exporter) HeadBlock(ctx context.Context) (interfaces.SignedBeaconBlock, error) {
return e.db.HeadBlock(ctx)
}
// Blocks -- passthrough.
func (e Exporter) Blocks(ctx context.Context, f *filters.QueryFilter) ([]*eth.SignedBeaconBlock, [][32]byte, error) {
func (e Exporter) Blocks(ctx context.Context, f *filters.QueryFilter) ([]interfaces.SignedBeaconBlock, [][32]byte, error) {
return e.db.Blocks(ctx, f)
}
@@ -49,7 +50,7 @@ func (e Exporter) BlockRoots(ctx context.Context, f *filters.QueryFilter) ([][32
}
// BlocksBySlot -- passthrough.
func (e Exporter) BlocksBySlot(ctx context.Context, slot types.Slot) (bool, []*eth.SignedBeaconBlock, error) {
func (e Exporter) BlocksBySlot(ctx context.Context, slot types.Slot) (bool, []interfaces.SignedBeaconBlock, error) {
return e.db.BlocksBySlot(ctx, slot)
}
@@ -129,7 +130,7 @@ func (e Exporter) SaveHeadBlockRoot(ctx context.Context, blockRoot [32]byte) err
}
// GenesisBlock -- passthrough.
func (e Exporter) GenesisBlock(ctx context.Context) (*eth.SignedBeaconBlock, error) {
func (e Exporter) GenesisBlock(ctx context.Context) (interfaces.SignedBeaconBlock, error) {
return e.db.GenesisBlock(ctx)
}
@@ -214,7 +215,7 @@ func (e Exporter) IsFinalizedBlock(ctx context.Context, blockRoot [32]byte) bool
}
// FinalizedChildBlock -- passthrough.
func (e Exporter) FinalizedChildBlock(ctx context.Context, blockRoot [32]byte) (*eth.SignedBeaconBlock, error) {
func (e Exporter) FinalizedChildBlock(ctx context.Context, blockRoot [32]byte) (interfaces.SignedBeaconBlock, error) {
return e.db.FinalizedChildBlock(ctx, blockRoot)
}
@@ -244,7 +245,7 @@ func (e Exporter) LastArchivedRoot(ctx context.Context) [32]byte {
}
// HighestSlotBlocksBelow -- passthrough
func (e Exporter) HighestSlotBlocksBelow(ctx context.Context, slot types.Slot) ([]*eth.SignedBeaconBlock, error) {
func (e Exporter) HighestSlotBlocksBelow(ctx context.Context, slot types.Slot) ([]interfaces.SignedBeaconBlock, error) {
return e.db.HighestSlotBlocksBelow(ctx, slot)
}

View File

@@ -44,6 +44,7 @@ go_library(
"//proto/beacon/p2p/v1:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/fileutil:go_default_library",
"//shared/interfaces:go_default_library",
"//shared/params:go_default_library",
"//shared/sliceutil:go_default_library",
"//shared/traceutil:go_default_library",
@@ -95,6 +96,7 @@ go_test(
"//proto/beacon/p2p/v1:go_default_library",
"//proto/testing:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/interfaces:go_default_library",
"//shared/params:go_default_library",
"//shared/testutil:go_default_library",
"//shared/testutil/assert:go_default_library",

View File

@@ -34,14 +34,14 @@ func (s *Store) Backup(ctx context.Context, outputDir string) error {
if err != nil {
return err
}
if head == nil {
if head == nil || head.IsNil() {
return errors.New("no head block")
}
// Ensure the backups directory exists.
if err := fileutil.MkdirAll(backupsDir); err != nil {
return err
}
backupPath := path.Join(backupsDir, fmt.Sprintf("prysm_beacondb_at_slot_%07d.backup", head.Block.Slot))
backupPath := path.Join(backupsDir, fmt.Sprintf("prysm_beacondb_at_slot_%07d.backup", head.Block().Slot()))
log.WithField("backup", backupPath).Info("Writing backup database.")
copyDB, err := bolt.Open(

View File

@@ -8,6 +8,7 @@ import (
"testing"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
@@ -20,7 +21,7 @@ func TestStore_Backup(t *testing.T) {
head := testutil.NewBeaconBlock()
head.Block.Slot = 5000
require.NoError(t, db.SaveBlock(ctx, head))
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(head)))
root, err := head.Block.HashTreeRoot()
require.NoError(t, err)
st, err := testutil.NewBeaconState()
@@ -60,7 +61,7 @@ func TestStore_BackupMultipleBuckets(t *testing.T) {
for i := startSlot; i < 5200; i++ {
head := testutil.NewBeaconBlock()
head.Block.Slot = i
require.NoError(t, db.SaveBlock(ctx, head))
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(head)))
root, err := head.Block.HashTreeRoot()
require.NoError(t, err)
st, err := testutil.NewBeaconState()
@@ -97,7 +98,7 @@ func TestStore_BackupMultipleBuckets(t *testing.T) {
nBlock, err := backedDB.Block(ctx, root)
require.NoError(t, err)
require.NotNil(t, nBlock)
require.Equal(t, nBlock.Block.Slot, i)
require.Equal(t, nBlock.Block().Slot(), i)
nState, err := backedDB.State(ctx, root)
require.NoError(t, err)
require.NotNil(t, nState)

View File

@@ -11,6 +11,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/db/filters"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/sliceutil"
bolt "go.etcd.io/bbolt"
@@ -21,12 +22,12 @@ import (
var errInvalidSlotRange = errors.New("invalid end slot and start slot provided")
// Block retrieval by root.
func (s *Store) Block(ctx context.Context, blockRoot [32]byte) (*ethpb.SignedBeaconBlock, error) {
func (s *Store) Block(ctx context.Context, blockRoot [32]byte) (interfaces.SignedBeaconBlock, error) {
ctx, span := trace.StartSpan(ctx, "BeaconDB.Block")
defer span.End()
// Return block from cache if it exists.
if v, ok := s.blockCache.Get(string(blockRoot[:])); v != nil && ok {
return v.(*ethpb.SignedBeaconBlock), nil
return v.(interfaces.SignedBeaconBlock), nil
}
var block *ethpb.SignedBeaconBlock
err := s.db.View(func(tx *bolt.Tx) error {
@@ -38,11 +39,11 @@ func (s *Store) Block(ctx context.Context, blockRoot [32]byte) (*ethpb.SignedBea
block = &ethpb.SignedBeaconBlock{}
return decode(ctx, enc, block)
})
return block, err
return interfaces.NewWrappedSignedBeaconBlock(block), err
}
// HeadBlock returns the latest canonical block in eth2.
func (s *Store) HeadBlock(ctx context.Context) (*ethpb.SignedBeaconBlock, error) {
func (s *Store) HeadBlock(ctx context.Context) (interfaces.SignedBeaconBlock, error) {
ctx, span := trace.StartSpan(ctx, "BeaconDB.HeadBlock")
defer span.End()
var headBlock *ethpb.SignedBeaconBlock
@@ -59,14 +60,14 @@ func (s *Store) HeadBlock(ctx context.Context) (*ethpb.SignedBeaconBlock, error)
headBlock = &ethpb.SignedBeaconBlock{}
return decode(ctx, enc, headBlock)
})
return headBlock, err
return interfaces.NewWrappedSignedBeaconBlock(headBlock), err
}
// Blocks retrieves a list of beacon blocks and its respective roots by filter criteria.
func (s *Store) Blocks(ctx context.Context, f *filters.QueryFilter) ([]*ethpb.SignedBeaconBlock, [][32]byte, error) {
func (s *Store) Blocks(ctx context.Context, f *filters.QueryFilter) ([]interfaces.SignedBeaconBlock, [][32]byte, error) {
ctx, span := trace.StartSpan(ctx, "BeaconDB.Blocks")
defer span.End()
blocks := make([]*ethpb.SignedBeaconBlock, 0)
blocks := make([]interfaces.SignedBeaconBlock, 0)
blockRoots := make([][32]byte, 0)
err := s.db.View(func(tx *bolt.Tx) error {
@@ -83,7 +84,7 @@ func (s *Store) Blocks(ctx context.Context, f *filters.QueryFilter) ([]*ethpb.Si
if err := decode(ctx, encoded, block); err != nil {
return err
}
blocks = append(blocks, block)
blocks = append(blocks, interfaces.NewWrappedSignedBeaconBlock(block))
blockRoots = append(blockRoots, bytesutil.ToBytes32(keys[i]))
}
return nil
@@ -136,10 +137,10 @@ 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, []*ethpb.SignedBeaconBlock, error) {
func (s *Store) BlocksBySlot(ctx context.Context, slot types.Slot) (bool, []interfaces.SignedBeaconBlock, error) {
ctx, span := trace.StartSpan(ctx, "BeaconDB.BlocksBySlot")
defer span.End()
blocks := make([]*ethpb.SignedBeaconBlock, 0)
blocks := make([]interfaces.SignedBeaconBlock, 0)
err := s.db.View(func(tx *bolt.Tx) error {
bkt := tx.Bucket(blocksBucket)
@@ -155,7 +156,7 @@ func (s *Store) BlocksBySlot(ctx context.Context, slot types.Slot) (bool, []*eth
if err := decode(ctx, encoded, block); err != nil {
return err
}
blocks = append(blocks, block)
blocks = append(blocks, interfaces.NewWrappedSignedBeaconBlock(block))
}
return nil
})
@@ -198,7 +199,7 @@ func (s *Store) deleteBlock(ctx context.Context, blockRoot [32]byte) error {
if err := decode(ctx, enc, block); err != nil {
return err
}
indicesByBucket := createBlockIndicesFromBlock(ctx, block.Block)
indicesByBucket := createBlockIndicesFromBlock(ctx, interfaces.NewWrappedBeaconBlock(block.Block))
if err := deleteValueForIndices(ctx, indicesByBucket, blockRoot[:], tx); err != nil {
return errors.Wrap(err, "could not delete root for DB indices")
}
@@ -223,7 +224,7 @@ func (s *Store) deleteBlocks(ctx context.Context, blockRoots [][32]byte) error {
if err := decode(ctx, enc, block); err != nil {
return err
}
indicesByBucket := createBlockIndicesFromBlock(ctx, block.Block)
indicesByBucket := createBlockIndicesFromBlock(ctx, interfaces.NewWrappedBeaconBlock(block.Block))
if err := deleteValueForIndices(ctx, indicesByBucket, blockRoot[:], tx); err != nil {
return errors.Wrap(err, "could not delete root for DB indices")
}
@@ -237,10 +238,10 @@ func (s *Store) deleteBlocks(ctx context.Context, blockRoots [][32]byte) error {
}
// SaveBlock to the db.
func (s *Store) SaveBlock(ctx context.Context, signed *ethpb.SignedBeaconBlock) error {
func (s *Store) SaveBlock(ctx context.Context, signed interfaces.SignedBeaconBlock) error {
ctx, span := trace.StartSpan(ctx, "BeaconDB.SaveBlock")
defer span.End()
blockRoot, err := signed.Block.HashTreeRoot()
blockRoot, err := signed.Block().HashTreeRoot()
if err != nil {
return err
}
@@ -248,18 +249,18 @@ func (s *Store) SaveBlock(ctx context.Context, signed *ethpb.SignedBeaconBlock)
return nil
}
return s.SaveBlocks(ctx, []*ethpb.SignedBeaconBlock{signed})
return s.SaveBlocks(ctx, []interfaces.SignedBeaconBlock{signed})
}
// SaveBlocks via bulk updates to the db.
func (s *Store) SaveBlocks(ctx context.Context, blocks []*ethpb.SignedBeaconBlock) error {
func (s *Store) SaveBlocks(ctx context.Context, blocks []interfaces.SignedBeaconBlock) error {
ctx, span := trace.StartSpan(ctx, "BeaconDB.SaveBlocks")
defer span.End()
return s.db.Update(func(tx *bolt.Tx) error {
bkt := tx.Bucket(blocksBucket)
for _, block := range blocks {
blockRoot, err := block.Block.HashTreeRoot()
blockRoot, err := block.Block().HashTreeRoot()
if err != nil {
return err
}
@@ -267,11 +268,11 @@ func (s *Store) SaveBlocks(ctx context.Context, blocks []*ethpb.SignedBeaconBloc
if existingBlock := bkt.Get(blockRoot[:]); existingBlock != nil {
continue
}
enc, err := encode(ctx, block)
enc, err := encode(ctx, block.Proto())
if err != nil {
return err
}
indicesByBucket := createBlockIndicesFromBlock(ctx, block.Block)
indicesByBucket := createBlockIndicesFromBlock(ctx, block.Block())
if err := updateValueForIndices(ctx, indicesByBucket, blockRoot[:], tx); err != nil {
return errors.Wrap(err, "could not update DB indices")
}
@@ -302,7 +303,7 @@ func (s *Store) SaveHeadBlockRoot(ctx context.Context, blockRoot [32]byte) error
}
// GenesisBlock retrieves the genesis block of the beacon chain.
func (s *Store) GenesisBlock(ctx context.Context) (*ethpb.SignedBeaconBlock, error) {
func (s *Store) GenesisBlock(ctx context.Context) (interfaces.SignedBeaconBlock, error) {
ctx, span := trace.StartSpan(ctx, "BeaconDB.GenesisBlock")
defer span.End()
var block *ethpb.SignedBeaconBlock
@@ -316,7 +317,7 @@ func (s *Store) GenesisBlock(ctx context.Context) (*ethpb.SignedBeaconBlock, err
block = &ethpb.SignedBeaconBlock{}
return decode(ctx, enc, block)
})
return block, err
return interfaces.NewWrappedSignedBeaconBlock(block), err
}
// SaveGenesisBlockRoot to the db.
@@ -330,7 +331,7 @@ func (s *Store) SaveGenesisBlockRoot(ctx context.Context, blockRoot [32]byte) er
}
// 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) ([]*ethpb.SignedBeaconBlock, error) {
func (s *Store) HighestSlotBlocksBelow(ctx context.Context, slot types.Slot) ([]interfaces.SignedBeaconBlock, error) {
ctx, span := trace.StartSpan(ctx, "BeaconDB.HighestSlotBlocksBelow")
defer span.End()
@@ -357,7 +358,7 @@ func (s *Store) HighestSlotBlocksBelow(ctx context.Context, slot types.Slot) ([]
return nil, err
}
var blk *ethpb.SignedBeaconBlock
var blk interfaces.SignedBeaconBlock
var err error
if best != nil {
blk, err = s.Block(ctx, bytesutil.ToBytes32(best))
@@ -365,14 +366,14 @@ func (s *Store) HighestSlotBlocksBelow(ctx context.Context, slot types.Slot) ([]
return nil, err
}
}
if blk == nil {
if blk == nil || blk.IsNil() {
blk, err = s.GenesisBlock(ctx)
if err != nil {
return nil, err
}
}
return []*ethpb.SignedBeaconBlock{blk}, nil
return []interfaces.SignedBeaconBlock{blk}, nil
}
// blockRootsByFilter retrieves the block roots given the filter criteria.
@@ -524,7 +525,7 @@ func blockRootsBySlot(ctx context.Context, tx *bolt.Tx, slot types.Slot) ([][]by
// createBlockIndicesFromBlock takes in a beacon block and returns
// a map of bolt DB index buckets corresponding to each particular key for indices for
// data, such as (shard indices bucket -> shard 5).
func createBlockIndicesFromBlock(ctx context.Context, block *ethpb.BeaconBlock) map[string][]byte {
func createBlockIndicesFromBlock(ctx context.Context, block interfaces.BeaconBlock) map[string][]byte {
ctx, span := trace.StartSpan(ctx, "BeaconDB.createBlockIndicesFromBlock")
defer span.End()
indicesByBucket := make(map[string][]byte)
@@ -534,11 +535,11 @@ func createBlockIndicesFromBlock(ctx context.Context, block *ethpb.BeaconBlock)
blockSlotIndicesBucket,
}
indices := [][]byte{
bytesutil.SlotToBytesBigEndian(block.Slot),
bytesutil.SlotToBytesBigEndian(block.Slot()),
}
if block.ParentRoot != nil && len(block.ParentRoot) > 0 {
if block.ParentRoot() != nil && len(block.ParentRoot()) > 0 {
buckets = append(buckets, blockParentRootIndicesBucket)
indices = append(indices, block.ParentRoot)
indices = append(indices, block.ParentRoot())
}
for i := 0; i < len(buckets); i++ {
indicesByBucket[string(buckets[i])] = indices[i]

View File

@@ -9,6 +9,7 @@ import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/db/filters"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -25,7 +26,7 @@ func TestStore_SaveBlock_NoDuplicates(t *testing.T) {
prevBlock := testutil.NewBeaconBlock()
prevBlock.Block.Slot = slot - 1
prevBlock.Block.ParentRoot = bytesutil.PadTo([]byte{1, 2, 3}, 32)
require.NoError(t, db.SaveBlock(ctx, prevBlock))
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(prevBlock)))
block := testutil.NewBeaconBlock()
block.Block.Slot = slot
@@ -33,7 +34,7 @@ func TestStore_SaveBlock_NoDuplicates(t *testing.T) {
// Even with a full cache, saving new blocks should not cause
// duplicated blocks in the DB.
for i := 0; i < 100; i++ {
require.NoError(t, db.SaveBlock(ctx, block))
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(block)))
}
f := filters.NewFilter().SetStartSlot(slot).SetEndSlot(slot)
retrieved, _, err := db.Blocks(ctx, f)
@@ -55,12 +56,12 @@ func TestStore_BlocksCRUD(t *testing.T) {
require.NoError(t, err)
retrievedBlock, err := db.Block(ctx, blockRoot)
require.NoError(t, err)
assert.Equal(t, (*ethpb.SignedBeaconBlock)(nil), retrievedBlock, "Expected nil block")
require.NoError(t, db.SaveBlock(ctx, block))
assert.DeepEqual(t, (*ethpb.SignedBeaconBlock)(nil), retrievedBlock.Proto(), "Expected nil block")
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(block)))
assert.Equal(t, true, db.HasBlock(ctx, blockRoot), "Expected block to exist in the db")
retrievedBlock, err = db.Block(ctx, blockRoot)
require.NoError(t, err)
assert.Equal(t, true, proto.Equal(block, retrievedBlock), "Wanted: %v, received: %v", block, retrievedBlock)
assert.Equal(t, true, proto.Equal(block, retrievedBlock.Proto()), "Wanted: %v, received: %v", block, retrievedBlock)
require.NoError(t, db.deleteBlock(ctx, blockRoot))
assert.Equal(t, false, db.HasBlock(ctx, blockRoot), "Expected block to have been deleted from the db")
}
@@ -69,16 +70,16 @@ func TestStore_BlocksBatchDelete(t *testing.T) {
db := setupDB(t)
ctx := context.Background()
numBlocks := 10
totalBlocks := make([]*ethpb.SignedBeaconBlock, numBlocks)
totalBlocks := make([]interfaces.SignedBeaconBlock, numBlocks)
blockRoots := make([][32]byte, 0)
oddBlocks := make([]*ethpb.SignedBeaconBlock, 0)
oddBlocks := make([]interfaces.SignedBeaconBlock, 0)
for i := 0; i < len(totalBlocks); i++ {
b := testutil.NewBeaconBlock()
b.Block.Slot = types.Slot(i)
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
totalBlocks[i] = b
totalBlocks[i] = interfaces.NewWrappedSignedBeaconBlock(b)
if i%2 == 0 {
r, err := totalBlocks[i].Block.HashTreeRoot()
r, err := totalBlocks[i].Block().HashTreeRoot()
require.NoError(t, err)
blockRoots = append(blockRoots, r)
} else {
@@ -95,10 +96,10 @@ func TestStore_BlocksBatchDelete(t *testing.T) {
retrieved, _, err = db.Blocks(ctx, filters.NewFilter().SetParentRoot(bytesutil.PadTo([]byte("parent"), 32)))
require.NoError(t, err)
sort.Slice(retrieved, func(i, j int) bool {
return retrieved[i].Block.Slot < retrieved[j].Block.Slot
return retrieved[i].Block().Slot() < retrieved[j].Block().Slot()
})
for i, block := range retrieved {
assert.Equal(t, true, proto.Equal(block, oddBlocks[i]), "Wanted: %v, received: %v", block, oddBlocks[i])
assert.Equal(t, true, proto.Equal(block.Proto(), oddBlocks[i].Proto()), "Wanted: %v, received: %v", block, oddBlocks[i])
}
}
@@ -106,13 +107,13 @@ func TestStore_BlocksHandleZeroCase(t *testing.T) {
db := setupDB(t)
ctx := context.Background()
numBlocks := 10
totalBlocks := make([]*ethpb.SignedBeaconBlock, numBlocks)
totalBlocks := make([]interfaces.SignedBeaconBlock, numBlocks)
for i := 0; i < len(totalBlocks); i++ {
b := testutil.NewBeaconBlock()
b.Block.Slot = types.Slot(i)
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
totalBlocks[i] = b
_, err := totalBlocks[i].Block.HashTreeRoot()
totalBlocks[i] = interfaces.NewWrappedSignedBeaconBlock(b)
_, err := totalBlocks[i].Block().HashTreeRoot()
require.NoError(t, err)
}
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
@@ -126,14 +127,14 @@ func TestStore_BlocksHandleInvalidEndSlot(t *testing.T) {
db := setupDB(t)
ctx := context.Background()
numBlocks := 10
totalBlocks := make([]*ethpb.SignedBeaconBlock, numBlocks)
totalBlocks := make([]interfaces.SignedBeaconBlock, numBlocks)
// Save blocks from slot 1 onwards.
for i := 0; i < len(totalBlocks); i++ {
b := testutil.NewBeaconBlock()
b.Block.Slot = types.Slot(i) + 1
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
totalBlocks[i] = b
_, err := totalBlocks[i].Block.HashTreeRoot()
totalBlocks[i] = interfaces.NewWrappedSignedBeaconBlock(b)
_, err := totalBlocks[i].Block().HashTreeRoot()
require.NoError(t, err)
}
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
@@ -155,10 +156,10 @@ func TestStore_GenesisBlock(t *testing.T) {
blockRoot, err := genesisBlock.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveGenesisBlockRoot(ctx, blockRoot))
require.NoError(t, db.SaveBlock(ctx, genesisBlock))
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(genesisBlock)))
retrievedBlock, err := db.GenesisBlock(ctx)
require.NoError(t, err)
assert.Equal(t, true, proto.Equal(genesisBlock, retrievedBlock), "Wanted: %v, received: %v", genesisBlock, retrievedBlock)
assert.Equal(t, true, proto.Equal(genesisBlock, retrievedBlock.Proto()), "Wanted: %v, received: %v", genesisBlock, retrievedBlock)
}
func TestStore_BlocksCRUD_NoCache(t *testing.T) {
@@ -171,13 +172,13 @@ func TestStore_BlocksCRUD_NoCache(t *testing.T) {
require.NoError(t, err)
retrievedBlock, err := db.Block(ctx, blockRoot)
require.NoError(t, err)
require.Equal(t, (*ethpb.SignedBeaconBlock)(nil), retrievedBlock, "Expected nil block")
require.NoError(t, db.SaveBlock(ctx, block))
require.DeepEqual(t, (*ethpb.SignedBeaconBlock)(nil), retrievedBlock.Proto(), "Expected nil block")
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(block)))
db.blockCache.Del(string(blockRoot[:]))
assert.Equal(t, true, db.HasBlock(ctx, blockRoot), "Expected block to exist in the db")
retrievedBlock, err = db.Block(ctx, blockRoot)
require.NoError(t, err)
assert.Equal(t, true, proto.Equal(block, retrievedBlock), "Wanted: %v, received: %v", block, retrievedBlock)
assert.Equal(t, true, proto.Equal(block, retrievedBlock.Proto()), "Wanted: %v, received: %v", block, retrievedBlock)
require.NoError(t, db.deleteBlock(ctx, blockRoot))
assert.Equal(t, false, db.HasBlock(ctx, blockRoot), "Expected block to have been deleted from the db")
}
@@ -199,7 +200,13 @@ func TestStore_Blocks_FiltersCorrectly(t *testing.T) {
b8 := testutil.NewBeaconBlock()
b8.Block.Slot = 8
b8.Block.ParentRoot = bytesutil.PadTo([]byte("parent4"), 32)
blocks := []*ethpb.SignedBeaconBlock{b4, b5, b6, b7, b8}
blocks := []interfaces.SignedBeaconBlock{
interfaces.NewWrappedSignedBeaconBlock(b4),
interfaces.NewWrappedSignedBeaconBlock(b5),
interfaces.NewWrappedSignedBeaconBlock(b6),
interfaces.NewWrappedSignedBeaconBlock(b7),
interfaces.NewWrappedSignedBeaconBlock(b8),
}
ctx := context.Background()
require.NoError(t, db.SaveBlocks(ctx, blocks))
@@ -277,8 +284,8 @@ func TestStore_Blocks_VerifyBlockRoots(t *testing.T) {
r2, err := b2.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(ctx, b1))
require.NoError(t, db.SaveBlock(ctx, b2))
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b1)))
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b2)))
filter := filters.NewFilter().SetStartSlot(b1.Block.Slot).SetEndSlot(b2.Block.Slot)
roots, err := db.BlockRoots(ctx, filter)
@@ -289,12 +296,12 @@ func TestStore_Blocks_VerifyBlockRoots(t *testing.T) {
func TestStore_Blocks_Retrieve_SlotRange(t *testing.T) {
db := setupDB(t)
totalBlocks := make([]*ethpb.SignedBeaconBlock, 500)
totalBlocks := make([]interfaces.SignedBeaconBlock, 500)
for i := 0; i < 500; i++ {
b := testutil.NewBeaconBlock()
b.Block.Slot = types.Slot(i)
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
totalBlocks[i] = b
totalBlocks[i] = interfaces.NewWrappedSignedBeaconBlock(b)
}
ctx := context.Background()
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
@@ -306,12 +313,12 @@ func TestStore_Blocks_Retrieve_SlotRange(t *testing.T) {
func TestStore_Blocks_Retrieve_Epoch(t *testing.T) {
db := setupDB(t)
slots := params.BeaconConfig().SlotsPerEpoch.Mul(7)
totalBlocks := make([]*ethpb.SignedBeaconBlock, slots)
totalBlocks := make([]interfaces.SignedBeaconBlock, slots)
for i := types.Slot(0); i < slots; i++ {
b := testutil.NewBeaconBlock()
b.Block.Slot = i
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
totalBlocks[i] = b
totalBlocks[i] = interfaces.NewWrappedSignedBeaconBlock(b)
}
ctx := context.Background()
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
@@ -327,12 +334,12 @@ func TestStore_Blocks_Retrieve_Epoch(t *testing.T) {
func TestStore_Blocks_Retrieve_SlotRangeWithStep(t *testing.T) {
db := setupDB(t)
totalBlocks := make([]*ethpb.SignedBeaconBlock, 500)
totalBlocks := make([]interfaces.SignedBeaconBlock, 500)
for i := 0; i < 500; i++ {
b := testutil.NewBeaconBlock()
b.Block.Slot = types.Slot(i)
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
totalBlocks[i] = b
totalBlocks[i] = interfaces.NewWrappedSignedBeaconBlock(b)
}
const step = 2
ctx := context.Background()
@@ -341,7 +348,7 @@ func TestStore_Blocks_Retrieve_SlotRangeWithStep(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, 150, len(retrieved))
for _, b := range retrieved {
assert.Equal(t, types.Slot(0), (b.Block.Slot-100)%step, "Unexpect block slot %d", b.Block.Slot)
assert.Equal(t, types.Slot(0), (b.Block().Slot()-100)%step, "Unexpect block slot %d", b.Block().Slot())
}
}
@@ -351,26 +358,26 @@ func TestStore_SaveBlock_CanGetHighestAt(t *testing.T) {
block1 := testutil.NewBeaconBlock()
block1.Block.Slot = 1
require.NoError(t, db.SaveBlock(ctx, block1))
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(block1)))
block2 := testutil.NewBeaconBlock()
block2.Block.Slot = 10
require.NoError(t, db.SaveBlock(ctx, block2))
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(block2)))
block3 := testutil.NewBeaconBlock()
block3.Block.Slot = 100
require.NoError(t, db.SaveBlock(ctx, block3))
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(block3)))
highestAt, err := db.HighestSlotBlocksBelow(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, highestAt[0]), "Wanted: %v, received: %v", block1, highestAt[0])
assert.Equal(t, true, proto.Equal(block1, highestAt[0].Proto()), "Wanted: %v, received: %v", block1, highestAt[0])
highestAt, err = db.HighestSlotBlocksBelow(ctx, 11)
require.NoError(t, err)
assert.Equal(t, false, len(highestAt) <= 0, "Got empty highest at slice")
assert.Equal(t, true, proto.Equal(block2, highestAt[0]), "Wanted: %v, received: %v", block2, highestAt[0])
assert.Equal(t, true, proto.Equal(block2, highestAt[0].Proto()), "Wanted: %v, received: %v", block2, highestAt[0])
highestAt, err = db.HighestSlotBlocksBelow(ctx, 101)
require.NoError(t, err)
assert.Equal(t, false, len(highestAt) <= 0, "Got empty highest at slice")
assert.Equal(t, true, proto.Equal(block3, highestAt[0]), "Wanted: %v, received: %v", block3, highestAt[0])
assert.Equal(t, true, proto.Equal(block3, highestAt[0].Proto()), "Wanted: %v, received: %v", block3, highestAt[0])
r3, err := block3.Block.HashTreeRoot()
require.NoError(t, err)
@@ -378,7 +385,7 @@ func TestStore_SaveBlock_CanGetHighestAt(t *testing.T) {
highestAt, err = db.HighestSlotBlocksBelow(ctx, 101)
require.NoError(t, err)
assert.Equal(t, true, proto.Equal(block2, highestAt[0]), "Wanted: %v, received: %v", block2, highestAt[0])
assert.Equal(t, true, proto.Equal(block2, highestAt[0].Proto()), "Wanted: %v, received: %v", block2, highestAt[0])
}
func TestStore_GenesisBlock_CanGetHighestAt(t *testing.T) {
@@ -389,32 +396,32 @@ func TestStore_GenesisBlock_CanGetHighestAt(t *testing.T) {
genesisRoot, err := genesisBlock.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveGenesisBlockRoot(ctx, genesisRoot))
require.NoError(t, db.SaveBlock(ctx, genesisBlock))
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(genesisBlock)))
block1 := testutil.NewBeaconBlock()
block1.Block.Slot = 1
require.NoError(t, db.SaveBlock(ctx, block1))
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(block1)))
highestAt, err := db.HighestSlotBlocksBelow(ctx, 2)
require.NoError(t, err)
assert.Equal(t, true, proto.Equal(block1, highestAt[0]), "Wanted: %v, received: %v", block1, highestAt[0])
assert.Equal(t, true, proto.Equal(block1, highestAt[0].Proto()), "Wanted: %v, received: %v", block1, highestAt[0])
highestAt, err = db.HighestSlotBlocksBelow(ctx, 1)
require.NoError(t, err)
assert.Equal(t, true, proto.Equal(genesisBlock, highestAt[0]), "Wanted: %v, received: %v", genesisBlock, highestAt[0])
assert.Equal(t, true, proto.Equal(genesisBlock, highestAt[0].Proto()), "Wanted: %v, received: %v", genesisBlock, highestAt[0])
highestAt, err = db.HighestSlotBlocksBelow(ctx, 0)
require.NoError(t, err)
assert.Equal(t, true, proto.Equal(genesisBlock, highestAt[0]), "Wanted: %v, received: %v", genesisBlock, highestAt[0])
assert.Equal(t, true, proto.Equal(genesisBlock, highestAt[0].Proto()), "Wanted: %v, received: %v", genesisBlock, highestAt[0])
}
func TestStore_SaveBlocks_HasCachedBlocks(t *testing.T) {
db := setupDB(t)
ctx := context.Background()
b := make([]*ethpb.SignedBeaconBlock, 500)
b := make([]interfaces.SignedBeaconBlock, 500)
for i := 0; i < 500; i++ {
blk := testutil.NewBeaconBlock()
blk.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
blk.Block.Slot = types.Slot(i)
b[i] = blk
b[i] = interfaces.NewWrappedSignedBeaconBlock(blk)
}
require.NoError(t, db.SaveBlock(ctx, b[0]))
@@ -430,12 +437,12 @@ func TestStore_SaveBlocks_HasRootsMatched(t *testing.T) {
db := setupDB(t)
ctx := context.Background()
b := make([]*ethpb.SignedBeaconBlock, 500)
b := make([]interfaces.SignedBeaconBlock, 500)
for i := 0; i < 500; i++ {
blk := testutil.NewBeaconBlock()
blk.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
blk.Block.Slot = types.Slot(i)
b[i] = blk
b[i] = interfaces.NewWrappedSignedBeaconBlock(blk)
}
require.NoError(t, db.SaveBlocks(ctx, b))
@@ -446,7 +453,7 @@ func TestStore_SaveBlocks_HasRootsMatched(t *testing.T) {
assert.Equal(t, 500, len(blks), "Did not get wanted blocks")
for i, blk := range blks {
rt, err := blk.Block.HashTreeRoot()
rt, err := blk.Block().HashTreeRoot()
require.NoError(t, err)
assert.Equal(t, roots[i], rt, "mismatch of block roots")
}
@@ -458,15 +465,15 @@ func TestStore_BlocksBySlot_BlockRootsBySlot(t *testing.T) {
b1 := testutil.NewBeaconBlock()
b1.Block.Slot = 20
require.NoError(t, db.SaveBlock(ctx, b1))
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b1)))
b2 := testutil.NewBeaconBlock()
b2.Block.Slot = 100
b2.Block.ParentRoot = bytesutil.PadTo([]byte("parent1"), 32)
require.NoError(t, db.SaveBlock(ctx, b2))
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b2)))
b3 := testutil.NewBeaconBlock()
b3.Block.Slot = 100
b3.Block.ParentRoot = bytesutil.PadTo([]byte("parent2"), 32)
require.NoError(t, db.SaveBlock(ctx, b3))
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b3)))
r1, err := b1.Block.HashTreeRoot()
require.NoError(t, err)
@@ -481,12 +488,12 @@ func TestStore_BlocksBySlot_BlockRootsBySlot(t *testing.T) {
assert.Equal(t, false, hasBlocks, "Expected no blocks")
hasBlocks, retrievedBlocks, err = db.BlocksBySlot(ctx, 20)
require.NoError(t, err)
assert.Equal(t, true, proto.Equal(b1, retrievedBlocks[0]), "Wanted: %v, received: %v", b1, retrievedBlocks[0])
assert.Equal(t, true, proto.Equal(b1, 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)
require.NoError(t, err)
assert.Equal(t, true, proto.Equal(b2, retrievedBlocks[0]), "Wanted: %v, received: %v", b2, retrievedBlocks[0])
assert.Equal(t, true, proto.Equal(b3, retrievedBlocks[1]), "Wanted: %v, received: %v", b3, retrievedBlocks[1])
assert.Equal(t, true, proto.Equal(b2, retrievedBlocks[0].Proto()), "Wanted: %v, received: %v", b2, retrievedBlocks[0])
assert.Equal(t, true, proto.Equal(b3, retrievedBlocks[1].Proto()), "Wanted: %v, received: %v", b3, retrievedBlocks[1])
assert.Equal(t, true, hasBlocks, "Expected to have blocks")
hasBlockRoots, retrievedBlockRoots, err := db.BlockRootsBySlot(ctx, 1)

View File

@@ -6,6 +6,7 @@ import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -52,7 +53,7 @@ func TestStore_FinalizedCheckpoint_CanSaveRetrieve(t *testing.T) {
}
// a valid chain is required to save finalized checkpoint.
require.NoError(t, db.SaveBlock(ctx, blk))
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(blk)))
st, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, st.SetSlot(1))

View File

@@ -9,6 +9,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/db/filters"
dbpb "github.com/prysmaticlabs/prysm/proto/beacon/db"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/traceutil"
bolt "go.etcd.io/bbolt"
"go.opencensus.io/trace"
@@ -83,15 +84,15 @@ func (s *Store) updateFinalizedBlockRoots(ctx context.Context, tx *bolt.Tx, chec
traceutil.AnnotateError(span, err)
return err
}
if signedBlock == nil || signedBlock.Block == nil {
if signedBlock == nil || signedBlock.IsNil() || signedBlock.Block().IsNil() {
err := fmt.Errorf("missing block in database: block root=%#x", root)
traceutil.AnnotateError(span, err)
return err
}
block := signedBlock.Block
block := signedBlock.Block()
container := &dbpb.FinalizedBlockRootContainer{
ParentRoot: block.ParentRoot,
ParentRoot: block.ParentRoot(),
ChildRoot: previousRoot,
}
@@ -106,7 +107,7 @@ func (s *Store) updateFinalizedBlockRoots(ctx context.Context, tx *bolt.Tx, chec
}
// Found parent, loop exit condition.
if parentBytes := bkt.Get(block.ParentRoot); parentBytes != nil {
if parentBytes := bkt.Get(block.ParentRoot()); parentBytes != nil {
parent := &dbpb.FinalizedBlockRootContainer{}
if err := decode(ctx, parentBytes, parent); err != nil {
traceutil.AnnotateError(span, err)
@@ -118,14 +119,14 @@ func (s *Store) updateFinalizedBlockRoots(ctx context.Context, tx *bolt.Tx, chec
traceutil.AnnotateError(span, err)
return err
}
if err := bkt.Put(block.ParentRoot, enc); err != nil {
if err := bkt.Put(block.ParentRoot(), enc); err != nil {
traceutil.AnnotateError(span, err)
return err
}
break
}
previousRoot = root
root = block.ParentRoot
root = block.ParentRoot()
}
// Upsert blocks from the current finalized epoch.
@@ -182,7 +183,7 @@ func (s *Store) IsFinalizedBlock(ctx context.Context, blockRoot [32]byte) bool {
// FinalizedChildBlock returns the child block of a provided finalized block. If
// no finalized block or its respective child block exists we return with a nil
// block.
func (s *Store) FinalizedChildBlock(ctx context.Context, blockRoot [32]byte) (*ethpb.SignedBeaconBlock, error) {
func (s *Store) FinalizedChildBlock(ctx context.Context, blockRoot [32]byte) (interfaces.SignedBeaconBlock, error) {
ctx, span := trace.StartSpan(ctx, "BeaconDB.FinalizedChildBlock")
defer span.End()
@@ -208,5 +209,5 @@ func (s *Store) FinalizedChildBlock(ctx context.Context, blockRoot [32]byte) (*e
return decode(ctx, enc, blk)
})
traceutil.AnnotateError(span, err)
return blk, err
return interfaces.NewWrappedSignedBeaconBlock(blk), err
}

View File

@@ -7,6 +7,7 @@ import (
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -25,7 +26,7 @@ func TestStore_IsFinalizedBlock(t *testing.T) {
blks := makeBlocks(t, 0, slotsPerEpoch*3, genesisBlockRoot)
require.NoError(t, db.SaveBlocks(ctx, blks))
root, err := blks[slotsPerEpoch].Block.HashTreeRoot()
root, err := blks[slotsPerEpoch].Block().HashTreeRoot()
require.NoError(t, err)
cp := &ethpb.Checkpoint{
@@ -41,12 +42,12 @@ func TestStore_IsFinalizedBlock(t *testing.T) {
// All blocks up to slotsPerEpoch*2 should be in the finalized index.
for i := uint64(0); i < slotsPerEpoch*2; i++ {
root, err := blks[i].Block.HashTreeRoot()
root, err := blks[i].Block().HashTreeRoot()
require.NoError(t, err)
assert.Equal(t, true, db.IsFinalizedBlock(ctx, root), "Block at index %d was not considered finalized in the index", i)
}
for i := slotsPerEpoch * 3; i < uint64(len(blks)); i++ {
root, err := blks[i].Block.HashTreeRoot()
root, err := blks[i].Block().HashTreeRoot()
require.NoError(t, err)
assert.Equal(t, false, db.IsFinalizedBlock(ctx, root), "Block at index %d was considered finalized in the index, but should not have", i)
}
@@ -60,7 +61,7 @@ func TestStore_IsFinalizedBlockGenesis(t *testing.T) {
blk.Block.Slot = 0
root, err := blk.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(ctx, blk))
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(blk)))
require.NoError(t, db.SaveGenesisBlockRoot(ctx, root))
assert.Equal(t, true, db.IsFinalizedBlock(ctx, root), "Finalized genesis block doesn't exist in db")
}
@@ -141,7 +142,7 @@ func TestStore_IsFinalizedChildBlock(t *testing.T) {
blks := makeBlocks(t, 0, slotsPerEpoch*3, genesisBlockRoot)
require.NoError(t, db.SaveBlocks(ctx, blks))
root, err := blks[slotsPerEpoch].Block.HashTreeRoot()
root, err := blks[slotsPerEpoch].Block().HashTreeRoot()
require.NoError(t, err)
cp := &ethpb.Checkpoint{
@@ -157,7 +158,7 @@ func TestStore_IsFinalizedChildBlock(t *testing.T) {
// All blocks up to slotsPerEpoch should have a finalized child block.
for i := uint64(0); i < slotsPerEpoch; i++ {
root, err := blks[i].Block.HashTreeRoot()
root, err := blks[i].Block().HashTreeRoot()
require.NoError(t, err)
assert.Equal(t, true, db.IsFinalizedBlock(ctx, root), "Block at index %d was not considered finalized in the index", i)
blk, err := db.FinalizedChildBlock(ctx, root)
@@ -168,14 +169,15 @@ func TestStore_IsFinalizedChildBlock(t *testing.T) {
}
}
func sszRootOrDie(t *testing.T, block *ethpb.SignedBeaconBlock) []byte {
root, err := block.Block.HashTreeRoot()
func sszRootOrDie(t *testing.T, block interfaces.SignedBeaconBlock) []byte {
root, err := block.Block().HashTreeRoot()
require.NoError(t, err)
return root[:]
}
func makeBlocks(t *testing.T, i, n uint64, previousRoot [32]byte) []*ethpb.SignedBeaconBlock {
func makeBlocks(t *testing.T, i, n uint64, previousRoot [32]byte) []interfaces.SignedBeaconBlock {
blocks := make([]*ethpb.SignedBeaconBlock, n)
ifaceBlocks := make([]interfaces.SignedBeaconBlock, n)
for j := i; j < n+i; j++ {
parentRoot := make([]byte, 32)
copy(parentRoot, previousRoot[:])
@@ -185,6 +187,7 @@ func makeBlocks(t *testing.T, i, n uint64, previousRoot [32]byte) []*ethpb.Signe
var err error
previousRoot, err = blocks[j-i].Block.HashTreeRoot()
require.NoError(t, err)
ifaceBlocks[j-i] = interfaces.NewWrappedSignedBeaconBlock(blocks[j-i])
}
return blocks
return ifaceBlocks
}

View File

@@ -13,6 +13,7 @@ import (
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
state "github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
)
@@ -27,7 +28,7 @@ func (s *Store) SaveGenesisData(ctx context.Context, genesisState iface.BeaconSt
if err != nil {
return errors.Wrap(err, "could not get genesis block root")
}
if err := s.SaveBlock(ctx, genesisBlk); err != nil {
if err := s.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(genesisBlk)); err != nil {
return errors.Wrap(err, "could not save genesis block")
}
if err := s.SaveState(ctx, genesisState, genesisBlkRoot); err != nil {
@@ -70,7 +71,7 @@ func (s *Store) LoadGenesis(ctx context.Context, r io.Reader) error {
}
// If some different genesis state existed already, return an error. The same genesis state is
// considered a no-op.
if existing != nil {
if existing != nil && !existing.IsNil() {
a, err := existing.HashTreeRoot(ctx)
if err != nil {
return err
@@ -101,14 +102,14 @@ func (s *Store) EnsureEmbeddedGenesis(ctx context.Context) error {
if err != nil {
return err
}
if gb != nil {
if gb != nil && !gb.IsNil() {
return nil
}
gs, err := s.GenesisState(ctx)
if err != nil {
return err
}
if gs != nil {
if gs != nil && !gs.IsNil() {
return s.SaveGenesisData(ctx, gs)
}
return nil

View File

@@ -31,7 +31,7 @@ func testGenesisDataSaved(t *testing.T, db iface.Database) {
assert.NoError(t, err)
assert.NotNil(t, gb)
gbHTR, err := gb.Block.HashTreeRoot()
gbHTR, err := gb.Block().HashTreeRoot()
assert.NoError(t, err)
gss, err := db.StateSummary(ctx, gbHTR)
@@ -42,7 +42,7 @@ func testGenesisDataSaved(t *testing.T, db iface.Database) {
assert.NoError(t, err)
assert.NotNil(t, head)
headHTR, err := head.Block.HashTreeRoot()
headHTR, err := head.Block().HashTreeRoot()
assert.NoError(t, err)
assert.Equal(t, gbHTR, headHTR, "head block does not match genesis block")
}
@@ -99,7 +99,7 @@ func TestEnsureEmbeddedGenesis(t *testing.T) {
gb, err := db.GenesisBlock(ctx)
assert.NoError(t, err)
if gb != nil {
if gb != nil && !gb.IsNil() {
t.Fatal("Genesis block exists already")
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/traceutil"
bolt "go.etcd.io/bbolt"
@@ -128,11 +129,19 @@ func (s *Store) SaveStates(ctx context.Context, states []iface.ReadOnlyBeaconSta
func (s *Store) HasState(ctx context.Context, blockRoot [32]byte) bool {
ctx, span := trace.StartSpan(ctx, "BeaconDB.HasState")
defer span.End()
enc, err := s.stateBytes(ctx, blockRoot)
hasState := false
err := s.db.View(func(tx *bolt.Tx) error {
bkt := tx.Bucket(stateBucket)
stBytes := bkt.Get(blockRoot[:])
if len(stBytes) > 0 {
hasState = true
}
return nil
})
if err != nil {
panic(err)
}
return len(enc) > 0
return hasState
}
// DeleteState by block root.
@@ -204,7 +213,16 @@ func (s *Store) stateBytes(ctx context.Context, blockRoot [32]byte) ([]byte, err
var dst []byte
err := s.db.View(func(tx *bolt.Tx) error {
bkt := tx.Bucket(stateBucket)
dst = bkt.Get(blockRoot[:])
stBytes := bkt.Get(blockRoot[:])
if len(stBytes) == 0 {
return nil
}
// Due to https://github.com/boltdb/bolt/issues/204, we need to
// allocate a byte slice separately in the transaction or there
// is the possibility of a panic when accessing that particular
// area of memory.
dst = make([]byte, len(stBytes))
copy(dst, stBytes)
return nil
})
return dst, err
@@ -244,7 +262,7 @@ func slotByBlockRoot(ctx context.Context, tx *bolt.Tx, blockRoot []byte) (types.
if err != nil {
return 0, err
}
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
if err := helpers.VerifyNilBeaconBlock(interfaces.NewWrappedSignedBeaconBlock(b)); err != nil {
return 0, err
}
return b.Block.Slot, nil
@@ -294,7 +312,7 @@ func (s *Store) HighestSlotStatesBelow(ctx context.Context, slot types.Slot) ([]
return nil, err
}
}
if st == nil {
if st == nil || st.IsNil() {
st, err = s.GenesisState(ctx)
if err != nil {
return nil, err

View File

@@ -9,6 +9,7 @@ import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -64,14 +65,14 @@ func TestStore_StatesBatchDelete(t *testing.T) {
db := setupDB(t)
ctx := context.Background()
numBlocks := 100
totalBlocks := make([]*ethpb.SignedBeaconBlock, numBlocks)
totalBlocks := make([]interfaces.SignedBeaconBlock, numBlocks)
blockRoots := make([][32]byte, 0)
evenBlockRoots := make([][32]byte, 0)
for i := 0; i < len(totalBlocks); i++ {
b := testutil.NewBeaconBlock()
b.Block.Slot = types.Slot(i)
totalBlocks[i] = b
r, err := totalBlocks[i].Block.HashTreeRoot()
totalBlocks[i] = interfaces.NewWrappedSignedBeaconBlock(b)
r, err := totalBlocks[i].Block().HashTreeRoot()
require.NoError(t, err)
st, err := testutil.NewBeaconState()
require.NoError(t, err)
@@ -121,7 +122,7 @@ func TestStore_DeleteFinalizedState(t *testing.T) {
blk.Block.ParentRoot = genesis[:]
blk.Block.Slot = 100
require.NoError(t, db.SaveBlock(ctx, blk))
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(blk)))
finalizedBlockRoot, err := blk.Block.HashTreeRoot()
require.NoError(t, err)
@@ -146,7 +147,7 @@ func TestStore_DeleteHeadState(t *testing.T) {
blk := testutil.NewBeaconBlock()
blk.Block.ParentRoot = genesis[:]
blk.Block.Slot = 100
require.NoError(t, db.SaveBlock(ctx, blk))
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(blk)))
headBlockRoot, err := blk.Block.HashTreeRoot()
require.NoError(t, err)
@@ -166,7 +167,7 @@ func TestStore_SaveDeleteState_CanGetHighestBelow(t *testing.T) {
b.Block.Slot = 1
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(context.Background(), b))
require.NoError(t, db.SaveBlock(context.Background(), interfaces.NewWrappedSignedBeaconBlock(b)))
st, err := testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, st.SetSlot(1))
@@ -176,7 +177,7 @@ func TestStore_SaveDeleteState_CanGetHighestBelow(t *testing.T) {
b.Block.Slot = 100
r1, err := b.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(context.Background(), b))
require.NoError(t, db.SaveBlock(context.Background(), interfaces.NewWrappedSignedBeaconBlock(b)))
st, err = testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, st.SetSlot(100))
@@ -186,7 +187,7 @@ func TestStore_SaveDeleteState_CanGetHighestBelow(t *testing.T) {
b.Block.Slot = 1000
r2, err := b.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(context.Background(), b))
require.NoError(t, db.SaveBlock(context.Background(), interfaces.NewWrappedSignedBeaconBlock(b)))
st, err = testutil.NewBeaconState()
require.NoError(t, err)
require.NoError(t, st.SetSlot(1000))
@@ -220,7 +221,7 @@ func TestStore_GenesisState_CanGetHighestBelow(t *testing.T) {
b.Block.Slot = 1
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(context.Background(), b))
require.NoError(t, db.SaveBlock(context.Background(), interfaces.NewWrappedSignedBeaconBlock(b)))
st, err := testutil.NewBeaconState()
require.NoError(t, err)
@@ -257,7 +258,7 @@ func TestStore_CleanUpDirtyStates_AboveThreshold(t *testing.T) {
b.Block.ParentRoot = prevRoot[:]
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(context.Background(), b))
require.NoError(t, db.SaveBlock(context.Background(), interfaces.NewWrappedSignedBeaconBlock(b)))
bRoots = append(bRoots, r)
prevRoot = r
@@ -296,7 +297,7 @@ func TestStore_CleanUpDirtyStates_Finalized(t *testing.T) {
b.Block.Slot = i
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(context.Background(), b))
require.NoError(t, db.SaveBlock(context.Background(), interfaces.NewWrappedSignedBeaconBlock(b)))
st, err := testutil.NewBeaconState()
require.NoError(t, err)
@@ -324,7 +325,7 @@ func TestStore_CleanUpDirtyStates_DontDeleteNonFinalized(t *testing.T) {
b.Block.Slot = i
r, err := b.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveBlock(context.Background(), b))
require.NoError(t, db.SaveBlock(context.Background(), interfaces.NewWrappedSignedBeaconBlock(b)))
unfinalizedRoots = append(unfinalizedRoots, r)
st, err := testutil.NewBeaconState()

View File

@@ -11,6 +11,7 @@ import (
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/db/kv"
"github.com/prysmaticlabs/prysm/shared/cmd"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
@@ -26,7 +27,7 @@ func TestRestore(t *testing.T) {
require.NoError(t, err)
head := testutil.NewBeaconBlock()
head.Block.Slot = 5000
require.NoError(t, backupDb.SaveBlock(ctx, head))
require.NoError(t, backupDb.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(head)))
root, err := head.Block.HashTreeRoot()
require.NoError(t, err)
st, err := testutil.NewBeaconState()
@@ -63,7 +64,7 @@ func TestRestore(t *testing.T) {
require.NoError(t, err)
headBlock, err := restoredDb.HeadBlock(ctx)
require.NoError(t, err)
assert.Equal(t, types.Slot(5000), headBlock.Block.Slot, "Restored database has incorrect data")
assert.Equal(t, types.Slot(5000), headBlock.Block().Slot(), "Restored database has incorrect data")
assert.LogsContain(t, logHook, "Restore completed successfully")
}

View File

@@ -20,7 +20,6 @@ go_library(
"//proto/beacon/rpc/v1:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/fileutil:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/params:go_default_library",
"@com_github_ferranbt_fastssz//:go_default_library",
"@com_github_golang_snappy//:go_default_library",
@@ -32,6 +31,7 @@ go_library(
"@com_github_sirupsen_logrus//:go_default_library",
"@io_etcd_go_bbolt//:go_default_library",
"@io_opencensus_go//trace:go_default_library",
"@org_golang_x_sync//errgroup:go_default_library",
],
)

View File

@@ -76,7 +76,6 @@ func NewKVStore(ctx context.Context, dirPath string, config *Config) (*Store, er
tx,
// Slasher buckets.
attestedEpochsByValidator,
attestationRecordsBucket,
attestationDataRootsBucket,
proposalRecordsBucket,
slasherChunksBucket,

View File

@@ -149,12 +149,11 @@ func (s *Store) PruneAttestations(
log.Debugf("Pruned %d/%d epochs worth of attestations", epochAtCursor, endPruneEpoch-1)
if err := s.db.Update(func(tx *bolt.Tx) error {
rootsBkt := tx.Bucket(attestationDataRootsBucket)
attsBkt := tx.Bucket(attestationRecordsBucket)
c := rootsBkt.Cursor()
var lastPrunedEpoch, epochsPruned types.Epoch
// We begin a pruning iteration at starting from the first item in the bucket.
for k, v := c.First(); k != nil; k, v = c.Next() {
for k, _ := c.First(); k != nil; k, _ = c.Next() {
// We check the epoch from the current key in the database.
// If we have hit an epoch that is greater than the end epoch of the pruning process,
// we then completely exit the process as we are done.
@@ -174,9 +173,6 @@ func (s *Store) PruneAttestations(
if err := rootsBkt.Delete(k); err != nil {
return err
}
if err := attsBkt.Delete(v); err != nil {
return err
}
if epochAtCursor == 0 {
epochsPruned = 1
} else if epochAtCursor > lastPrunedEpoch {

View File

@@ -9,7 +9,6 @@ package slasherkv
var (
// Slasher buckets.
attestedEpochsByValidator = []byte("attested-epochs-by-validator")
attestationRecordsBucket = []byte("attestation-records")
attestationDataRootsBucket = []byte("attestation-data-roots")
proposalRecordsBucket = []byte("proposal-records")
slasherChunksBucket = []byte("slasher-chunks")

View File

@@ -6,6 +6,7 @@ import (
"encoding/binary"
"fmt"
"sort"
"sync"
ssz "github.com/ferranbt/fastssz"
"github.com/golang/snappy"
@@ -15,9 +16,9 @@ import (
slashertypes "github.com/prysmaticlabs/prysm/beacon-chain/slasher/types"
slashpb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/hashutil"
bolt "go.etcd.io/bbolt"
"go.opencensus.io/trace"
"golang.org/x/sync/errgroup"
)
const (
@@ -92,43 +93,58 @@ func (s *Store) CheckAttesterDoubleVotes(
ctx, span := trace.StartSpan(ctx, "BeaconDB.CheckAttesterDoubleVotes")
defer span.End()
doubleVotes := make([]*slashertypes.AttesterDoubleVote, 0)
err := s.db.View(func(tx *bolt.Tx) error {
signingRootsBkt := tx.Bucket(attestationDataRootsBucket)
attRecordsBkt := tx.Bucket(attestationRecordsBucket)
for _, att := range attestations {
encEpoch := encodeTargetEpoch(att.IndexedAttestation.Data.Target.Epoch)
for _, valIdx := range att.IndexedAttestation.AttestingIndices {
encIdx := encodeValidatorIndex(types.ValidatorIndex(valIdx))
validatorEpochKey := append(encEpoch, encIdx...)
attRecordsKey := signingRootsBkt.Get(validatorEpochKey)
// An attestation record key is comprised of a signing root (32 bytes)
// and a fast sum hash of the attesting indices (8 bytes).
if len(attRecordsKey) < attestationRecordKeySize {
continue
}
encExistingAttRecord := attRecordsBkt.Get(attRecordsKey)
if encExistingAttRecord == nil {
continue
}
existingSigningRoot := bytesutil.ToBytes32(attRecordsKey[:signingRootSize])
if existingSigningRoot != att.SigningRoot {
existingAttRecord, err := decodeAttestationRecord(encExistingAttRecord)
if err != nil {
return err
doubleVotesMu := sync.Mutex{}
eg, egctx := errgroup.WithContext(ctx)
for _, att := range attestations {
// Copy the iteration instance to a local variable to give each go-routine its own copy to play with.
// See https://golang.org/doc/faq#closures_and_goroutines for more details.
attToProcess := att
// process every attestation parallelly.
eg.Go(func() error {
err := s.db.View(func(tx *bolt.Tx) error {
signingRootsBkt := tx.Bucket(attestationDataRootsBucket)
encEpoch := encodeTargetEpoch(attToProcess.IndexedAttestation.Data.Target.Epoch)
localDoubleVotes := make([]*slashertypes.AttesterDoubleVote, 0)
for _, valIdx := range attToProcess.IndexedAttestation.AttestingIndices {
encIdx := encodeValidatorIndex(types.ValidatorIndex(valIdx))
validatorEpochKey := append(encEpoch, encIdx...)
encExistingAttRecord := signingRootsBkt.Get(validatorEpochKey)
if encExistingAttRecord == nil {
continue
}
existingSigningRoot := bytesutil.ToBytes32(encExistingAttRecord[:signingRootSize])
if existingSigningRoot != attToProcess.SigningRoot {
existingAttRecord, err := decodeAttestationRecord(encExistingAttRecord[signingRootSize:])
if err != nil {
return err
}
slashAtt := &slashertypes.AttesterDoubleVote{
ValidatorIndex: types.ValidatorIndex(valIdx),
Target: attToProcess.IndexedAttestation.Data.Target.Epoch,
PrevAttestationWrapper: existingAttRecord,
AttestationWrapper: attToProcess,
}
localDoubleVotes = append(localDoubleVotes, slashAtt)
}
doubleVotes = append(doubleVotes, &slashertypes.AttesterDoubleVote{
ValidatorIndex: types.ValidatorIndex(valIdx),
Target: att.IndexedAttestation.Data.Target.Epoch,
PrevAttestationWrapper: existingAttRecord,
AttestationWrapper: att,
})
}
}
}
return nil
})
return doubleVotes, err
// if any routine is cancelled, then cancel this routine too
select {
case <-egctx.Done():
return egctx.Err()
default:
}
// if there are any doible votes in this attestation, add it to the global double votes
if len(localDoubleVotes) > 0 {
doubleVotesMu.Lock()
defer doubleVotesMu.Unlock()
doubleVotes = append(doubleVotes, localDoubleVotes...)
}
return nil
})
return err
})
}
return doubleVotes, eg.Wait()
}
// AttestationRecordForValidator given a validator index and a target epoch,
@@ -144,16 +160,11 @@ func (s *Store) AttestationRecordForValidator(
key := append(encEpoch, encIdx...)
err := s.db.View(func(tx *bolt.Tx) error {
signingRootsBkt := tx.Bucket(attestationDataRootsBucket)
attRecordKey := signingRootsBkt.Get(key)
if attRecordKey == nil {
return nil
}
attRecordsBkt := tx.Bucket(attestationRecordsBucket)
indexedAttBytes := attRecordsBkt.Get(attRecordKey)
indexedAttBytes := signingRootsBkt.Get(key)
if indexedAttBytes == nil {
return nil
}
decoded, err := decodeAttestationRecord(indexedAttBytes)
decoded, err := decodeAttestationRecord(indexedAttBytes[signingRootSize:])
if err != nil {
return err
}
@@ -189,23 +200,15 @@ func (s *Store) SaveAttestationRecordsForValidators(
encodedRecords[i] = value
}
return s.db.Update(func(tx *bolt.Tx) error {
attRecordsBkt := tx.Bucket(attestationRecordsBucket)
signingRootsBkt := tx.Bucket(attestationDataRootsBucket)
for i, att := range attestations {
// An attestation record key is comprised of the signing root (32 bytes)
// and a fastsum64 of the attesting indices (8 bytes). This is used
// to have a more optimal schema
attIndicesHash := hashutil.FastSum64(encodedIndices[i])
attRecordKey := append(
att.SigningRoot[:], ssz.MarshalUint64(make([]byte, 0), attIndicesHash)...,
)
if err := attRecordsBkt.Put(attRecordKey, encodedRecords[i]); err != nil {
return err
}
for _, valIdx := range att.IndexedAttestation.AttestingIndices {
encIdx := encodeValidatorIndex(types.ValidatorIndex(valIdx))
key := append(encodedTargetEpoch[i], encIdx...)
if err := signingRootsBkt.Put(key, attRecordKey); err != nil {
// signature is prefixed so that double votest can be checked without decoding attestations
// and save some cpu cycles
value := append(att.SigningRoot[:], encodedRecords[i]...)
if err := signingRootsBkt.Put(key, value); err != nil {
return err
}
}
@@ -361,18 +364,17 @@ func (s *Store) HighestAttestations(
history := make([]*slashpb.HighestAttestation, 0, len(encodedIndices))
err = s.db.View(func(tx *bolt.Tx) error {
signingRootsBkt := tx.Bucket(attestationDataRootsBucket)
attRecordsBkt := tx.Bucket(attestationRecordsBucket)
for i := 0; i < len(encodedIndices); i++ {
c := signingRootsBkt.Cursor()
for k, v := c.Last(); k != nil; k, v = c.Prev() {
if suffixForAttestationRecordsKey(k, encodedIndices[i]) {
encodedAttRecord := attRecordsBkt.Get(v)
encodedAttRecord := v[signingRootSize:]
if encodedAttRecord == nil {
continue
}
attWrapper, err := decodeAttestationRecord(encodedAttRecord)
if err != nil {
return err
attWrapper, decodeErr := decodeAttestationRecord(encodedAttRecord)
if decodeErr != nil {
return decodeErr
}
highestAtt := &slashpb.HighestAttestation{
ValidatorIndex: uint64(indices[i]),

View File

@@ -3,8 +3,11 @@ package slasherkv
import (
"context"
"encoding/binary"
"math/rand"
"reflect"
"sort"
"testing"
"time"
ssz "github.com/ferranbt/fastssz"
types "github.com/prysmaticlabs/eth2-types"
@@ -110,6 +113,10 @@ func TestStore_CheckAttesterDoubleVotes(t *testing.T) {
}
doubleVotes, err := beaconDB.CheckAttesterDoubleVotes(ctx, slashableAtts)
require.NoError(t, err)
sort.SliceStable(doubleVotes, func(i, j int) bool {
return uint64(doubleVotes[i].ValidatorIndex) < uint64(doubleVotes[j].ValidatorIndex)
})
require.DeepEqual(t, wanted, doubleVotes)
}
@@ -442,6 +449,39 @@ func BenchmarkHighestAttestations(b *testing.B) {
}
}
func BenchmarkStore_CheckDoubleBlockProposals(b *testing.B) {
b.StopTimer()
count := 10000
valsPerAtt := 100
indicesPerAtt := make([][]uint64, count)
for i := 0; i < count; i++ {
indicesForAtt := make([]uint64, valsPerAtt)
for r := i * count; r < valsPerAtt*(i+1); r++ {
indicesForAtt[i] = uint64(r)
}
indicesPerAtt[i] = indicesForAtt
}
atts := make([]*slashertypes.IndexedAttestationWrapper, count)
for i := 0; i < count; i++ {
atts[i] = createAttestationWrapper(types.Epoch(i), types.Epoch(i+2), indicesPerAtt[i], []byte{})
}
ctx := context.Background()
beaconDB := setupDB(b)
require.NoError(b, beaconDB.SaveAttestationRecordsForValidators(ctx, atts))
// shuffle attestations
rand.Seed(time.Now().UnixNano())
rand.Shuffle(count, func(i, j int) { atts[i], atts[j] = atts[j], atts[i] })
b.ReportAllocs()
b.StartTimer()
for i := 0; i < b.N; i++ {
_, err := beaconDB.CheckAttesterDoubleVotes(ctx, atts)
require.NoError(b, err)
}
}
func createProposalWrapper(t *testing.T, slot types.Slot, proposerIndex types.ValidatorIndex, signingRoot []byte) *slashertypes.SignedBlockHeaderWrapper {
header := &ethpb.BeaconBlockHeader{
Slot: slot,

View File

@@ -19,8 +19,8 @@ go_library(
],
deps = [
"//beacon-chain/operations/attestations/kv:go_default_library",
"//beacon-chain/state/stateV0:go_default_library",
"//shared/aggregation/attestations:go_default_library",
"//shared/blockutil:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/params:go_default_library",
"//shared/slotutil:go_default_library",

View File

@@ -15,8 +15,8 @@ go_library(
visibility = ["//beacon-chain:__subpackages__"],
deps = [
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/state/stateV0:go_default_library",
"//shared/aggregation/attestations:go_default_library",
"//shared/blockutil:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/params:go_default_library",
"@com_github_patrickmn_go_cache//:go_default_library",

View File

@@ -3,11 +3,12 @@ package kv
import (
"context"
"github.com/prysmaticlabs/prysm/shared/blockutil"
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
attaggregation "github.com/prysmaticlabs/prysm/shared/aggregation/attestations"
log "github.com/sirupsen/logrus"
"go.opencensus.io/trace"
@@ -120,7 +121,7 @@ func (c *AttCaches) SaveAggregatedAttestation(att *ethpb.Attestation) error {
if err != nil {
return errors.Wrap(err, "could not tree hash attestation")
}
copiedAtt := stateV0.CopyAttestation(att)
copiedAtt := blockutil.CopyAttestation(att)
c.aggregatedAttLock.Lock()
defer c.aggregatedAttLock.Unlock()
atts, ok := c.aggregatedAtt[r]

View File

@@ -3,7 +3,7 @@ package kv
import (
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
"github.com/prysmaticlabs/prysm/shared/blockutil"
)
// SaveBlockAttestation saves an block attestation in cache.
@@ -30,7 +30,7 @@ func (c *AttCaches) SaveBlockAttestation(att *ethpb.Attestation) error {
}
}
c.blockAtt[r] = append(atts, stateV0.CopyAttestation(att))
c.blockAtt[r] = append(atts, blockutil.CopyAttestation(att))
return nil
}

View File

@@ -3,7 +3,7 @@ package kv
import (
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
"github.com/prysmaticlabs/prysm/shared/blockutil"
)
// SaveForkchoiceAttestation saves an forkchoice attestation in cache.
@@ -16,7 +16,7 @@ func (c *AttCaches) SaveForkchoiceAttestation(att *ethpb.Attestation) error {
return errors.Wrap(err, "could not tree hash attestation")
}
att = stateV0.CopyAttestation(att)
att = blockutil.CopyAttestation(att)
c.forkchoiceAttLock.Lock()
defer c.forkchoiceAttLock.Unlock()
c.forkchoiceAtt[r] = att
@@ -42,7 +42,7 @@ func (c *AttCaches) ForkchoiceAttestations() []*ethpb.Attestation {
atts := make([]*ethpb.Attestation, 0, len(c.forkchoiceAtt))
for _, att := range c.forkchoiceAtt {
atts = append(atts, stateV0.CopyAttestation(att) /* Copied */)
atts = append(atts, blockutil.CopyAttestation(att) /* Copied */)
}
return atts

View File

@@ -3,11 +3,12 @@ package kv
import (
"context"
"github.com/prysmaticlabs/prysm/shared/blockutil"
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
"go.opencensus.io/trace"
)
@@ -32,7 +33,7 @@ func (c *AttCaches) SaveUnaggregatedAttestation(att *ethpb.Attestation) error {
if err != nil {
return errors.Wrap(err, "could not tree hash attestation")
}
att = stateV0.CopyAttestation(att) // Copied.
att = blockutil.CopyAttestation(att) // Copied.
c.unAggregateAttLock.Lock()
defer c.unAggregateAttLock.Unlock()
c.unAggregatedAtt[r] = att
@@ -63,7 +64,7 @@ func (c *AttCaches) UnaggregatedAttestations() ([]*ethpb.Attestation, error) {
return nil, err
}
if !seen {
atts = append(atts, stateV0.CopyAttestation(att) /* Copied */)
atts = append(atts, blockutil.CopyAttestation(att) /* Copied */)
}
}
return atts, nil

View File

@@ -6,9 +6,10 @@ import (
"errors"
"time"
"github.com/prysmaticlabs/prysm/shared/blockutil"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-bitfield"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateV0"
attaggregation "github.com/prysmaticlabs/prysm/shared/aggregation/attestations"
"github.com/prysmaticlabs/prysm/shared/hashutil"
"github.com/prysmaticlabs/prysm/shared/slotutil"
@@ -88,7 +89,7 @@ func (s *Service) batchForkChoiceAtts(ctx context.Context) error {
func (s *Service) aggregateAndSaveForkChoiceAtts(atts []*ethpb.Attestation) error {
clonedAtts := make([]*ethpb.Attestation, len(atts))
for i, a := range atts {
clonedAtts[i] = stateV0.CopyAttestation(a)
clonedAtts[i] = blockutil.CopyAttestation(a)
}
aggregatedAtts, err := attaggregation.Aggregate(clonedAtts)
if err != nil {

View File

@@ -113,7 +113,7 @@ func (s *Service) retrieveActiveValidators() (uint64, error) {
if err != nil {
return 0, err
}
if genState == nil {
if genState == nil || genState.IsNil() {
return 0, errors.New("no genesis state exists")
}
activeVals, err := helpers.ActiveValidatorCount(genState, helpers.CurrentEpoch(genState))
@@ -128,7 +128,7 @@ func (s *Service) retrieveActiveValidators() (uint64, error) {
if err != nil {
return 0, err
}
if bState == nil {
if bState == nil || bState.IsNil() {
return 0, errors.Errorf("no state with root %#x exists", rt)
}
activeVals, err := helpers.ActiveValidatorCount(bState, helpers.CurrentEpoch(bState))

View File

@@ -13,7 +13,7 @@ go_library(
"@com_github_libp2p_go_libp2p_core//network:go_default_library",
"@com_github_libp2p_go_libp2p_core//peer:go_default_library",
"@com_github_multiformats_go_multiaddr//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
],
)

View File

@@ -10,7 +10,7 @@ import (
"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer"
ma "github.com/multiformats/go-multiaddr"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
pbrpc "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
)

View File

@@ -17,7 +17,7 @@ func (s *Service) processDeposit(ctx context.Context, eth1Data *ethpb.Eth1Data,
if err != nil {
return errors.Wrap(err, "could not process pre-genesis deposits")
}
if beaconState != nil {
if beaconState != nil && !beaconState.IsNil() {
s.preGenesisState = beaconState
}
return nil

View File

@@ -374,7 +374,7 @@ func (s *Service) processPastLogs(ctx context.Context) error {
if err != nil {
return err
}
if fState != nil && fState.Eth1DepositIndex() > 0 {
if fState != nil && !fState.IsNil() && fState.Eth1DepositIndex() > 0 {
s.cfg.DepositCache.PrunePendingDeposits(ctx, int64(fState.Eth1DepositIndex()))
}
return nil

View File

@@ -247,7 +247,7 @@ func (s *Service) Start() {
if err != nil {
log.Fatal(err)
}
if genState == nil {
if genState == nil || genState.IsNil() {
log.Fatal("cannot create genesis state: no eth1 http endpoint defined")
}
}
@@ -611,7 +611,7 @@ func (s *Service) initDepositCaches(ctx context.Context, ctrs []*protodb.Deposit
if err != nil {
return errors.Wrap(err, "could not get finalized state")
}
if fState == nil {
if fState == nil || fState.IsNil() {
return errors.Errorf("finalized state with root %#x does not exist in the db", rt)
}
// Set deposit index to the one in the current archived state.
@@ -1014,7 +1014,7 @@ func (s *Service) ensureValidPowchainData(ctx context.Context) error {
return err
}
// Exit early if no genesis state is saved.
if genState == nil {
if genState == nil || genState.IsNil() {
return nil
}
eth1Data, err := s.cfg.BeaconDB.PowchainData(ctx)

View File

@@ -45,6 +45,7 @@ go_library(
"//shared/cmd:go_default_library",
"//shared/event:go_default_library",
"//shared/featureconfig:go_default_library",
"//shared/interfaces:go_default_library",
"//shared/pagination:go_default_library",
"//shared/params:go_default_library",
"//shared/sliceutil:go_default_library",
@@ -101,6 +102,7 @@ go_test(
"//shared/bytesutil:go_default_library",
"//shared/cmd:go_default_library",
"//shared/featureconfig:go_default_library",
"//shared/interfaces:go_default_library",
"//shared/mock:go_default_library",
"//shared/params:go_default_library",
"//shared/testutil:go_default_library",

View File

@@ -14,6 +14,7 @@ import (
dbTest "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
"github.com/prysmaticlabs/prysm/shared/cmd"
"github.com/prysmaticlabs/prysm/shared/interfaces"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
@@ -50,7 +51,7 @@ func TestServer_ListAssignments_NoResults(t *testing.T) {
require.NoError(t, err)
b := testutil.NewBeaconBlock()
require.NoError(t, db.SaveBlock(ctx, b))
require.NoError(t, db.SaveBlock(ctx, interfaces.NewWrappedSignedBeaconBlock(b)))
gRoot, err := b.Block.HashTreeRoot()
require.NoError(t, err)
require.NoError(t, db.SaveGenesisBlockRoot(ctx, gRoot))

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