Method to retrieve block slot via block root (#5084)

* blockRootSlot

* Tests

* Gaz

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
terence tsao 2020-03-12 22:04:24 +01:00 committed by GitHub
parent 7fcc07fb45
commit ed7ad4525e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 95 additions and 8 deletions

View File

@ -12,10 +12,10 @@ import (
"github.com/prysmaticlabs/go-ssz"
mockChain "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
mockPOW "github.com/prysmaticlabs/prysm/beacon-chain/powchain/testing"
blk "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
dbutil "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
mockPOW "github.com/prysmaticlabs/prysm/beacon-chain/powchain/testing"
mockSync "github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync/testing"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/params"
@ -78,11 +78,11 @@ func TestGetDuties_NextEpoch_CantFindValidatorIdx(t *testing.T) {
}
vs := &Server{
BeaconDB: db,
HeadFetcher: &mockChain.ChainService{State: beaconState, Root: genesisRoot[:]},
SyncChecker: &mockSync.Sync{IsSyncing: false},
BeaconDB: db,
HeadFetcher: &mockChain.ChainService{State: beaconState, Root: genesisRoot[:]},
SyncChecker: &mockSync.Sync{IsSyncing: false},
Eth1InfoFetcher: p,
DepositFetcher: depositcache.NewDepositCache(),
DepositFetcher: depositcache.NewDepositCache(),
}
pubKey := pubKey(99999)

View File

@ -6,6 +6,7 @@ import (
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
@ -79,3 +80,36 @@ func (s *State) recoverArchivedPointByIndex(ctx context.Context, archiveIndex ui
return archivedState, nil
}
// Given a block root, this returns the slot of the block root using state summary look up in DB.
// If state summary does not exist in DB, it will recover the state summary and save it to the DB.
// This is used to cover corner cases where users toggle new state service's feature flag.
func (s *State) blockRootSlot(ctx context.Context, blockRoot [32]byte) (uint64, error) {
ctx, span := trace.StartSpan(ctx, "stateGen.blockRootSlot")
defer span.End()
if s.beaconDB.HasStateSummary(ctx, blockRoot) {
summary, err := s.beaconDB.StateSummary(ctx, blockRoot)
if err != nil {
return 0, nil
}
if summary == nil {
return 0, errUnknownStateSummary
}
return summary.Slot, nil
}
// Couldn't find state summary in DB. Retry with block bucket to get block slot.
b, err := s.beaconDB.Block(ctx, blockRoot)
if err != nil {
return 0, err
}
if b == nil || b.Block == nil {
return 0, errUnknownBlock
}
if err := s.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{Root: blockRoot[:], Slot: b.Block.Slot}); err != nil {
return 0, errors.Wrap(err, "could not save state summary")
}
return b.Block.Slot, nil
}

View File

@ -8,6 +8,7 @@ import (
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-ssz"
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/testutil"
)
@ -154,6 +155,58 @@ func TestRecoverArchivedPointByIndex_CanRecover(t *testing.T) {
t.Fatal(err)
}
if !proto.Equal(recoveredState.InnerStateUnsafe(), savedArchivedState.InnerStateUnsafe()) {
t.Error("Diff saved state")
t.Error("Diff savled state")
}
}
func TestBlockRootSlot_Exists(t *testing.T) {
ctx := context.Background()
db := testDB.SetupDB(t)
defer testDB.TeardownDB(t, db)
service := New(db)
bRoot := [32]byte{'A'}
bSlot := uint64(100)
if err := service.beaconDB.SaveStateSummary(ctx, &pb.StateSummary{
Slot: bSlot,
Root: bRoot[:],
}); err != nil {
t.Fatal(err)
}
slot, err := service.blockRootSlot(ctx, bRoot)
if err != nil {
t.Fatal(err)
}
if slot != bSlot {
t.Error("Did not get correct block root slot")
}
}
func TestBlockRootSlot_CanRecoverAndSave(t *testing.T) {
ctx := context.Background()
db := testDB.SetupDB(t)
defer testDB.TeardownDB(t, db)
service := New(db)
bSlot := uint64(100)
b := &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: bSlot}}
bRoot, _ := ssz.HashTreeRoot(b.Block)
if err := service.beaconDB.SaveBlock(ctx, b); err != nil {
t.Fatal(err)
}
slot, err := service.blockRootSlot(ctx, bRoot)
if err != nil {
t.Fatal(err)
}
if slot != bSlot {
t.Error("Did not get correct block root slot")
}
// Verify state summary is saved.
if !service.beaconDB.HasStateSummary(ctx, bRoot) {
t.Error("State summary not saved")
}
}

View File

@ -16,6 +16,8 @@ import (
"github.com/gogo/protobuf/proto"
ptypes "github.com/gogo/protobuf/types"
"github.com/pkg/errors"
"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/core/helpers"
pb "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
@ -28,8 +30,6 @@ import (
"github.com/prysmaticlabs/prysm/validator/keymanager"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
type validator struct {