Update Ethereum APIs, Allow Genesis Data Retrieval for Blocks + Attestations (#4150)

* update apis

* include block filter genesis

* genesis atts

* add in workspace file

* include proper diff targeting master of ethereum apis

* genesis block fetching fixes

* remove fmt

* tests for genesis list blocks passing

* fixed up container tests

* tests now passing

* fix up tests
This commit is contained in:
Raul Jordan
2019-11-30 22:30:48 -06:00
committed by GitHub
parent 646411b881
commit 3be4894b8a
7 changed files with 204 additions and 15 deletions

View File

@@ -1201,7 +1201,7 @@ go_repository(
go_repository(
name = "com_github_prysmaticlabs_ethereumapis",
commit = "12081efa4a35f9e8b5c44faf3215a4ef64e21516",
commit = "8a69b37df2264eb58b0b0cef5ba25ae9af2d8732",
importpath = "github.com/prysmaticlabs/ethereumapis",
patch_args = ["-p1"],
patches = [

View File

@@ -338,9 +338,6 @@ func fetchBlockRootsBySlotRange(bkt *bolt.Bucket, startSlotEncoded, endSlotEncod
if endSlot, ok = endSlotEncoded.(uint64); !ok {
endSlot = 0
}
if startSlot == endSlot && startSlot == 0 {
return nil
}
min := []byte(fmt.Sprintf("%07d", startSlot))
max := []byte(fmt.Sprintf("%07d", endSlot))
var conditional func(key, max []byte) bool

View File

@@ -7,6 +7,7 @@ import (
ptypes "github.com/gogo/protobuf/types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-ssz"
"github.com/prysmaticlabs/prysm/beacon-chain/db/filters"
"github.com/prysmaticlabs/prysm/shared/pagination"
"github.com/prysmaticlabs/prysm/shared/params"
@@ -40,6 +41,25 @@ func (bs *Server) ListAttestations(
var atts []*ethpb.Attestation
var err error
switch q := req.QueryFilter.(type) {
case *ethpb.ListAttestationsRequest_Genesis:
blks, err := bs.BeaconDB.Blocks(ctx, filters.NewFilter().SetStartSlot(0).SetEndSlot(0))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not genesis block: %v", err)
}
if len(blks) == 0 {
return nil, status.Error(codes.Internal, "Could not find genesis block")
}
if len(blks) != 1 {
return nil, status.Error(codes.Internal, "Found more than 1 genesis block")
}
genesisRoot, err := ssz.SigningRoot(blks[0])
if err != nil {
return nil, err
}
atts, err = bs.BeaconDB.Attestations(ctx, filters.NewFilter().SetHeadBlockRoot(genesisRoot[:]))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not fetch genesis attestations: %v", err)
}
case *ethpb.ListAttestationsRequest_HeadBlockRoot:
atts, err = bs.BeaconDB.Attestations(ctx, filters.NewFilter().SetHeadBlockRoot(q.HeadBlockRoot))
if err != nil {

View File

@@ -12,6 +12,7 @@ import (
ptypes "github.com/gogo/protobuf/types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-bitfield"
"github.com/prysmaticlabs/go-ssz"
mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
dbTest "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
mockOps "github.com/prysmaticlabs/prysm/beacon-chain/operations/testing"
@@ -46,6 +47,82 @@ func TestServer_ListAttestations_NoResults(t *testing.T) {
}
}
func TestServer_ListAttestations_Genesis(t *testing.T) {
db := dbTest.SetupDB(t)
defer dbTest.TeardownDB(t, db)
ctx := context.Background()
bs := &Server{
BeaconDB: db,
HeadFetcher: &mock.ChainService{
State: &pbp2p.BeaconState{Slot: 0},
},
}
// Should throw an error if no genesis data is found.
if _, err := bs.ListAttestations(ctx, &ethpb.ListAttestationsRequest{
QueryFilter: &ethpb.ListAttestationsRequest_Genesis{
Genesis: true,
},
}); err != nil && !strings.Contains(err.Error(), "Could not find genesis") {
t.Fatal(err)
}
parentRoot := [32]byte{1, 2, 3}
blk := &ethpb.BeaconBlock{
Slot: 0,
ParentRoot: parentRoot[:],
}
root, err := ssz.SigningRoot(blk)
if err != nil {
t.Fatal(err)
}
if err := db.SaveBlock(ctx, blk); err != nil {
t.Fatal(err)
}
att := &ethpb.Attestation{
AggregationBits: bitfield.Bitlist{0b11},
Data: &ethpb.AttestationData{
Slot: 0,
BeaconBlockRoot: root[:],
},
CustodyBits: bitfield.Bitlist{0b10},
}
if err := db.SaveAttestation(ctx, att); err != nil {
t.Fatal(err)
}
wanted := &ethpb.ListAttestationsResponse{
Attestations: []*ethpb.Attestation{att},
NextPageToken: "1",
TotalSize: 1,
}
res, err := bs.ListAttestations(ctx, &ethpb.ListAttestationsRequest{
QueryFilter: &ethpb.ListAttestationsRequest_Genesis{
Genesis: true,
},
})
if err != nil {
t.Fatal(err)
}
if !proto.Equal(wanted, res) {
t.Errorf("Wanted %v, received %v", wanted, res)
}
// Should throw an error if there is more than 1 block
// for the genesis slot.
if err := db.SaveBlock(ctx, blk); err != nil {
t.Fatal(err)
}
if _, err := bs.ListAttestations(ctx, &ethpb.ListAttestationsRequest{
QueryFilter: &ethpb.ListAttestationsRequest_Genesis{
Genesis: true,
},
}); err != nil && !strings.Contains(err.Error(), "Found more than 1") {
t.Fatal(err)
}
}
func TestServer_ListAttestations_NoPagination(t *testing.T) {
db := dbTest.SetupDB(t)
defer dbTest.TeardownDB(t, db)

View File

@@ -136,6 +136,34 @@ func (bs *Server) ListBlocks(
TotalSize: int32(numBlks),
NextPageToken: nextPageToken,
}, nil
case *ethpb.ListBlocksRequest_Genesis:
blks, err := bs.BeaconDB.Blocks(ctx, filters.NewFilter().SetStartSlot(0).SetEndSlot(0))
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not retrieve blocks for genesis slot: %v", err)
}
numBlks := len(blks)
if numBlks == 0 {
return nil, status.Error(codes.Internal, "Could not find genesis block")
}
if numBlks != 1 {
return nil, status.Error(codes.Internal, "Found more than 1 genesis block")
}
root, err := ssz.SigningRoot(blks[0])
if err != nil {
return nil, err
}
containers := []*ethpb.BeaconBlockContainer{
{
Block: blks[0],
BlockRoot: root[:],
},
}
return &ethpb.ListBlocksResponse{
BlockContainers: containers,
TotalSize: int32(1),
NextPageToken: strconv.Itoa(0),
}, nil
}
return nil, status.Error(codes.InvalidArgument, "Must specify a filter criteria for fetching blocks")

View File

@@ -65,6 +65,73 @@ func TestServer_ListBlocks_NoResults(t *testing.T) {
}
}
func TestServer_ListBlocks_Genesis(t *testing.T) {
db := dbTest.SetupDB(t)
defer dbTest.TeardownDB(t, db)
ctx := context.Background()
bs := &Server{
BeaconDB: db,
}
// Should throw an error if no genesis block is found.
if _, err := bs.ListBlocks(ctx, &ethpb.ListBlocksRequest{
QueryFilter: &ethpb.ListBlocksRequest_Genesis{
Genesis: true,
},
}); err != nil && !strings.Contains(err.Error(), "Could not find genesis") {
t.Fatal(err)
}
// Should return the proper genesis block if it exists.
parentRoot := [32]byte{1, 2, 3}
blk := &ethpb.BeaconBlock{
Slot: 0,
ParentRoot: parentRoot[:],
}
root, err := ssz.SigningRoot(blk)
if err != nil {
t.Fatal(err)
}
if err := db.SaveBlock(ctx, blk); err != nil {
t.Fatal(err)
}
wanted := &ethpb.ListBlocksResponse{
BlockContainers: []*ethpb.BeaconBlockContainer{
{
Block: blk,
BlockRoot: root[:],
},
},
NextPageToken: "0",
TotalSize: 1,
}
res, err := bs.ListBlocks(ctx, &ethpb.ListBlocksRequest{
QueryFilter: &ethpb.ListBlocksRequest_Genesis{
Genesis: true,
},
})
if err != nil {
t.Fatal(err)
}
if !proto.Equal(wanted, res) {
t.Errorf("Wanted %v, received %v", wanted, res)
}
// Should throw an error if there is more than 1 block
// for the genesis slot.
if err := db.SaveBlock(ctx, blk); err != nil {
t.Fatal(err)
}
if _, err := bs.ListBlocks(ctx, &ethpb.ListBlocksRequest{
QueryFilter: &ethpb.ListBlocksRequest_Genesis{
Genesis: true,
},
}); err != nil && !strings.Contains(err.Error(), "Found more than 1") {
t.Fatal(err)
}
}
func TestServer_ListBlocks_Pagination(t *testing.T) {
db := dbTest.SetupDB(t)
defer dbTest.TeardownDB(t, db)

View File

@@ -255,7 +255,7 @@ index 69a148a..1b6ac18 100644
+ bytes signature = 4 [(gogoproto.moretags) = "ssz-size:\"96\""];
}
diff --git a/eth/v1alpha1/beacon_chain.proto b/eth/v1alpha1/beacon_chain.proto
index 00db5f3..8c4c74d 100644
index 0f490c1..592b169 100644
--- a/eth/v1alpha1/beacon_chain.proto
+++ b/eth/v1alpha1/beacon_chain.proto
@@ -15,6 +15,7 @@ syntax = "proto3";
@@ -266,7 +266,7 @@ index 00db5f3..8c4c74d 100644
import "google/api/annotations.proto";
import "google/protobuf/empty.proto";
@@ -247,7 +248,7 @@ message BeaconBlockContainer {
@@ -261,7 +262,7 @@ message BeaconBlockContainer {
// Information about the head of the beacon chain.
message ChainHead {
// 32 byte merkle tree root of the canonical head block in the beacon node.
@@ -275,7 +275,7 @@ index 00db5f3..8c4c74d 100644
// Slot of the head block.
uint64 head_block_slot = 2;
@@ -262,7 +263,7 @@ message ChainHead {
@@ -276,7 +277,7 @@ message ChainHead {
uint64 finalized_epoch = 5;
// Most recent 32 byte finalized block root.
@@ -284,7 +284,7 @@ index 00db5f3..8c4c74d 100644
// Most recent slot that contains the justified block.
uint64 justified_block_slot = 7;
@@ -271,7 +272,7 @@ message ChainHead {
@@ -285,7 +286,7 @@ message ChainHead {
uint64 justified_epoch = 8;
// Most recent 32 byte justified block root.
@@ -293,7 +293,7 @@ index 00db5f3..8c4c74d 100644
// Most recent slot that contains the previous justified block.
uint64 previous_justified_slot = 10;
@@ -280,7 +281,7 @@ message ChainHead {
@@ -294,7 +295,7 @@ message ChainHead {
uint64 previous_justified_epoch = 11;
// Previous 32 byte justified block root.
@@ -302,7 +302,7 @@ index 00db5f3..8c4c74d 100644
}
message ListCommitteesRequest {
@@ -338,7 +339,7 @@ message ListValidatorBalancesRequest {
@@ -352,7 +353,7 @@ message ListValidatorBalancesRequest {
// Validator 48 byte BLS public keys to filter validators for the given
// epoch.
@@ -311,7 +311,7 @@ index 00db5f3..8c4c74d 100644
// Validator indices to filter validators for the given epoch.
repeated uint64 indices = 4;
@@ -359,7 +360,7 @@ message ValidatorBalances {
@@ -373,7 +374,7 @@ message ValidatorBalances {
message Balance {
// Validator's 48 byte BLS public key.
@@ -320,7 +320,7 @@ index 00db5f3..8c4c74d 100644
// Validator's index in the validator set.
uint64 index = 2;
@@ -435,17 +436,17 @@ message ActiveSetChanges {
@@ -449,17 +450,17 @@ message ActiveSetChanges {
uint64 epoch = 1;
// 48 byte validator public keys that have been activated in this epoch.
@@ -342,7 +342,7 @@ index 00db5f3..8c4c74d 100644
}
message ValidatorQueue {
@@ -455,11 +456,11 @@ message ValidatorQueue {
@@ -469,11 +470,11 @@ message ValidatorQueue {
// Ordered list of 48 byte public keys awaiting activation. 0th index is the
// next key to be processed.
@@ -356,7 +356,7 @@ index 00db5f3..8c4c74d 100644
}
message ListValidatorAssignmentsRequest {
@@ -471,7 +472,7 @@ message ListValidatorAssignmentsRequest {
@@ -485,7 +486,7 @@ message ListValidatorAssignmentsRequest {
bool genesis = 2;
}
// 48 byte validator public keys to filter assignments for the given epoch.
@@ -365,7 +365,7 @@ index 00db5f3..8c4c74d 100644
// Validator indicies to filter assignments for the given epoch.
repeated uint64 indices = 4;
@@ -506,7 +507,7 @@ message ValidatorAssignments {
@@ -520,7 +521,7 @@ message ValidatorAssignments {
uint64 proposer_slot = 4;
// 48 byte BLS public key.