Canonical Blocks for Batch Block Request (#2511)

* only reply canonical block for reg sync

* CanonicalBlock test

* lint
This commit is contained in:
terence tsao 2019-05-06 11:02:04 -07:00 committed by GitHub
parent e5a00fdca9
commit a818564b8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 76 additions and 3 deletions

View File

@ -27,6 +27,7 @@ type BlockReceiver interface {
CanonicalBlockFeed() *event.Feed
ReceiveBlock(ctx context.Context, block *pb.BeaconBlock) (*pb.BeaconState, error)
IsCanonical(slot uint64, hash []byte) bool
CanonicalBlock(slot uint64) (*pb.BeaconBlock, error)
InsertsCanonical(slot uint64, hash []byte)
RecentCanonicalRoots(count uint64) []*pbrpc.BlockRoot
}

View File

@ -18,6 +18,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
pbrpc "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/event"
"github.com/prysmaticlabs/prysm/shared/hashutil"
"github.com/prysmaticlabs/prysm/shared/p2p"
@ -238,6 +239,18 @@ func (c *ChainService) IsCanonical(slot uint64, hash []byte) bool {
return false
}
// CanonicalBlock returns canonical block of a given slot, it returns nil
// if there's no canonical block saved of a given slot.
func (c *ChainService) CanonicalBlock(slot uint64) (*pb.BeaconBlock, error) {
c.canonicalBlocksLock.RLock()
defer c.canonicalBlocksLock.RUnlock()
root, exists := c.canonicalBlocks[slot]
if !exists {
return nil, nil
}
return c.beaconDB.Block(bytesutil.ToBytes32(root))
}
// RecentCanonicalRoots returns the latest block slot and root of the canonical block chain,
// the block slots and roots are sorted and in descending order. Input count determines
// the number of block slots and roots to return.

View File

@ -374,3 +374,53 @@ func TestRecentCanonicalRoots_CanFilter(t *testing.T) {
}
}
func TestCanonicalBlock_CanGet(t *testing.T) {
db := internal.SetupDB(t)
defer internal.TeardownDB(t, db)
service := setupBeaconChain(t, db, nil)
blk1 := &pb.BeaconBlock{Slot: 500}
blk1Root, err := hashutil.HashBeaconBlock(blk1)
if err != nil {
t.Fatal(err)
}
if err := db.SaveBlock(blk1); err != nil {
t.Fatal(err)
}
blk2 := &pb.BeaconBlock{Slot: 600}
blk2Root, _ := hashutil.HashBeaconBlock(blk2)
if err != nil {
t.Fatal(err)
}
if err := db.SaveBlock(blk2); err != nil {
t.Fatal(err)
}
cMap := map[uint64][]byte{
blk1.Slot: blk1Root[:],
blk2.Slot: blk2Root[:],
700: {'A'},
}
service.canonicalBlocks = cMap
blk1Db, err := service.CanonicalBlock(blk1.Slot)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(blk1, blk1Db) {
t.Error("block 1 don't match")
}
blk2Db, err := service.CanonicalBlock(blk2.Slot)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(blk2, blk2Db) {
t.Error("block 2 don't match")
}
blk3Db, err := service.CanonicalBlock(999)
if err != nil {
t.Fatal(err)
}
if blk3Db != nil {
t.Error("block 3 is suppose to be nil")
}
}

View File

@ -117,6 +117,10 @@ func (m mockChainService) RecentCanonicalRoots(count uint64) []*pbrpc.BlockRoot
return nil
}
func (m *mockChainService) CanonicalBlock(slot uint64) (*pb.BeaconBlock, error) {
return nil, nil
}
func newMockChainService() *mockChainService {
return &mockChainService{
blockFeed: new(event.Feed),

View File

@ -557,13 +557,14 @@ func (rs *RegularSync) handleBatchedBlockRequest(msg p2p.Message) error {
response := make([]*pb.BeaconBlock, 0, blockRange)
for i := startSlot; i <= endSlot; i++ {
retBlock, err := rs.db.BlockBySlot(ctx, i)
retBlock, err := rs.chainService.CanonicalBlock(i)
if err != nil {
log.Errorf("Unable to retrieve block from db %v", err)
log.Errorf("Unable to retrieve canonical block %v", err)
continue
}
if retBlock == nil {
log.Debug("Block does not exist in db")
log.WithField("slot", i).
Debug("Canonical block does not exist")
continue
}
response = append(response, retBlock)

View File

@ -96,6 +96,10 @@ func (ms *mockChainService) IsCanonical(slot uint64, hash []byte) bool {
return true
}
func (ms *mockChainService) CanonicalBlock(slot uint64) (*pb.BeaconBlock, error) {
return nil, nil
}
func (ms *mockChainService) RecentCanonicalRoots(count uint64) []*pbrpc.BlockRoot {
return nil
}