mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 21:08:10 -05:00
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:
@@ -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 = [
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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, ðpb.ListAttestationsRequest{
|
||||
QueryFilter: ðpb.ListAttestationsRequest_Genesis{
|
||||
Genesis: true,
|
||||
},
|
||||
}); err != nil && !strings.Contains(err.Error(), "Could not find genesis") {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
parentRoot := [32]byte{1, 2, 3}
|
||||
blk := ðpb.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 := ðpb.Attestation{
|
||||
AggregationBits: bitfield.Bitlist{0b11},
|
||||
Data: ðpb.AttestationData{
|
||||
Slot: 0,
|
||||
BeaconBlockRoot: root[:],
|
||||
},
|
||||
CustodyBits: bitfield.Bitlist{0b10},
|
||||
}
|
||||
if err := db.SaveAttestation(ctx, att); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
wanted := ðpb.ListAttestationsResponse{
|
||||
Attestations: []*ethpb.Attestation{att},
|
||||
NextPageToken: "1",
|
||||
TotalSize: 1,
|
||||
}
|
||||
|
||||
res, err := bs.ListAttestations(ctx, ðpb.ListAttestationsRequest{
|
||||
QueryFilter: ðpb.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, ðpb.ListAttestationsRequest{
|
||||
QueryFilter: ðpb.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)
|
||||
|
||||
@@ -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 ðpb.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")
|
||||
|
||||
@@ -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, ðpb.ListBlocksRequest{
|
||||
QueryFilter: ðpb.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 := ðpb.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 := ðpb.ListBlocksResponse{
|
||||
BlockContainers: []*ethpb.BeaconBlockContainer{
|
||||
{
|
||||
Block: blk,
|
||||
BlockRoot: root[:],
|
||||
},
|
||||
},
|
||||
NextPageToken: "0",
|
||||
TotalSize: 1,
|
||||
}
|
||||
res, err := bs.ListBlocks(ctx, ðpb.ListBlocksRequest{
|
||||
QueryFilter: ðpb.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, ðpb.ListBlocksRequest{
|
||||
QueryFilter: ðpb.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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user