2019-11-12 17:01:27 +00:00
|
|
|
package beacon
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/gogo/protobuf/proto"
|
|
|
|
"github.com/prysmaticlabs/go-ssz"
|
|
|
|
dbTest "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
|
|
|
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
|
|
|
|
"github.com/prysmaticlabs/prysm/shared/params"
|
|
|
|
)
|
|
|
|
|
2019-11-18 23:24:33 +00:00
|
|
|
func TestServer_ListBlocks_NoResults(t *testing.T) {
|
|
|
|
db := dbTest.SetupDB(t)
|
|
|
|
defer dbTest.TeardownDB(t, db)
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
bs := &Server{
|
|
|
|
BeaconDB: db,
|
|
|
|
}
|
|
|
|
wanted := ðpb.ListBlocksResponse{
|
|
|
|
BlockContainers: make([]*ethpb.BeaconBlockContainer, 0),
|
|
|
|
TotalSize: int32(0),
|
|
|
|
NextPageToken: strconv.Itoa(0),
|
|
|
|
}
|
|
|
|
res, err := bs.ListBlocks(ctx, ðpb.ListBlocksRequest{
|
|
|
|
QueryFilter: ðpb.ListBlocksRequest_Epoch{
|
|
|
|
Epoch: 0,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if !proto.Equal(wanted, res) {
|
|
|
|
t.Errorf("Wanted %v, received %v", wanted, res)
|
|
|
|
}
|
|
|
|
res, err = bs.ListBlocks(ctx, ðpb.ListBlocksRequest{
|
|
|
|
QueryFilter: ðpb.ListBlocksRequest_Slot{
|
|
|
|
Slot: 0,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if !proto.Equal(wanted, res) {
|
|
|
|
t.Errorf("Wanted %v, received %v", wanted, res)
|
|
|
|
}
|
|
|
|
res, err = bs.ListBlocks(ctx, ðpb.ListBlocksRequest{
|
|
|
|
QueryFilter: ðpb.ListBlocksRequest_Root{
|
|
|
|
Root: make([]byte, 32),
|
|
|
|
},
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if !proto.Equal(wanted, res) {
|
|
|
|
t.Errorf("Wanted %v, received %v", wanted, res)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-12 17:01:27 +00:00
|
|
|
func TestServer_ListBlocks_Pagination(t *testing.T) {
|
|
|
|
db := dbTest.SetupDB(t)
|
|
|
|
defer dbTest.TeardownDB(t, db)
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
count := uint64(100)
|
|
|
|
blks := make([]*ethpb.BeaconBlock, count)
|
2019-11-18 16:15:45 +00:00
|
|
|
blkContainers := make([]*ethpb.BeaconBlockContainer, count)
|
2019-11-12 17:01:27 +00:00
|
|
|
for i := uint64(0); i < count; i++ {
|
|
|
|
b := ðpb.BeaconBlock{
|
|
|
|
Slot: i,
|
|
|
|
}
|
2019-11-18 16:15:45 +00:00
|
|
|
root, err := ssz.SigningRoot(b)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2019-11-12 17:01:27 +00:00
|
|
|
blks[i] = b
|
2019-11-18 16:15:45 +00:00
|
|
|
blkContainers[i] = ðpb.BeaconBlockContainer{Block: b, BlockRoot: root[:]}
|
2019-11-12 17:01:27 +00:00
|
|
|
}
|
|
|
|
if err := db.SaveBlocks(ctx, blks); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
root6, err := ssz.SigningRoot(ðpb.BeaconBlock{Slot: 6})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
bs := &Server{
|
|
|
|
BeaconDB: db,
|
|
|
|
}
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
req *ethpb.ListBlocksRequest
|
|
|
|
res *ethpb.ListBlocksResponse
|
|
|
|
}{
|
|
|
|
{req: ðpb.ListBlocksRequest{
|
|
|
|
PageToken: strconv.Itoa(0),
|
|
|
|
QueryFilter: ðpb.ListBlocksRequest_Slot{Slot: 5},
|
|
|
|
PageSize: 3},
|
|
|
|
res: ðpb.ListBlocksResponse{
|
2019-11-18 16:15:45 +00:00
|
|
|
BlockContainers: []*ethpb.BeaconBlockContainer{{Block: ðpb.BeaconBlock{Slot: 5}, BlockRoot: blkContainers[5].BlockRoot}},
|
|
|
|
NextPageToken: strconv.Itoa(1),
|
|
|
|
TotalSize: 1}},
|
2019-11-12 17:01:27 +00:00
|
|
|
{req: ðpb.ListBlocksRequest{
|
|
|
|
PageToken: strconv.Itoa(0),
|
|
|
|
QueryFilter: ðpb.ListBlocksRequest_Root{Root: root6[:]},
|
|
|
|
PageSize: 3},
|
|
|
|
res: ðpb.ListBlocksResponse{
|
2019-11-18 16:15:45 +00:00
|
|
|
BlockContainers: []*ethpb.BeaconBlockContainer{{Block: ðpb.BeaconBlock{Slot: 6}, BlockRoot: blkContainers[6].BlockRoot}},
|
|
|
|
TotalSize: 1}},
|
2019-11-12 17:01:27 +00:00
|
|
|
{req: ðpb.ListBlocksRequest{QueryFilter: ðpb.ListBlocksRequest_Root{Root: root6[:]}},
|
|
|
|
res: ðpb.ListBlocksResponse{
|
2019-11-18 16:15:45 +00:00
|
|
|
BlockContainers: []*ethpb.BeaconBlockContainer{{Block: ðpb.BeaconBlock{Slot: 6}, BlockRoot: blkContainers[6].BlockRoot}},
|
|
|
|
TotalSize: 1}},
|
2019-11-12 17:01:27 +00:00
|
|
|
{req: ðpb.ListBlocksRequest{
|
|
|
|
PageToken: strconv.Itoa(0),
|
|
|
|
QueryFilter: ðpb.ListBlocksRequest_Epoch{Epoch: 0},
|
|
|
|
PageSize: 100},
|
|
|
|
res: ðpb.ListBlocksResponse{
|
2019-11-18 16:15:45 +00:00
|
|
|
BlockContainers: blkContainers[0:params.BeaconConfig().SlotsPerEpoch],
|
|
|
|
NextPageToken: strconv.Itoa(1),
|
|
|
|
TotalSize: int32(params.BeaconConfig().SlotsPerEpoch)}},
|
2019-11-12 17:01:27 +00:00
|
|
|
{req: ðpb.ListBlocksRequest{
|
|
|
|
PageToken: strconv.Itoa(1),
|
|
|
|
QueryFilter: ðpb.ListBlocksRequest_Epoch{Epoch: 5},
|
|
|
|
PageSize: 3},
|
|
|
|
res: ðpb.ListBlocksResponse{
|
2019-11-18 16:15:45 +00:00
|
|
|
BlockContainers: blkContainers[43:46],
|
|
|
|
NextPageToken: strconv.Itoa(2),
|
|
|
|
TotalSize: int32(params.BeaconConfig().SlotsPerEpoch)}},
|
2019-11-12 17:01:27 +00:00
|
|
|
{req: ðpb.ListBlocksRequest{
|
|
|
|
PageToken: strconv.Itoa(1),
|
|
|
|
QueryFilter: ðpb.ListBlocksRequest_Epoch{Epoch: 11},
|
|
|
|
PageSize: 7},
|
|
|
|
res: ðpb.ListBlocksResponse{
|
2019-11-18 16:15:45 +00:00
|
|
|
BlockContainers: blkContainers[95:96],
|
|
|
|
NextPageToken: strconv.Itoa(2),
|
|
|
|
TotalSize: int32(params.BeaconConfig().SlotsPerEpoch)}},
|
2019-11-12 17:01:27 +00:00
|
|
|
{req: ðpb.ListBlocksRequest{
|
|
|
|
PageToken: strconv.Itoa(0),
|
|
|
|
QueryFilter: ðpb.ListBlocksRequest_Epoch{Epoch: 12},
|
|
|
|
PageSize: 4},
|
|
|
|
res: ðpb.ListBlocksResponse{
|
2019-11-18 16:15:45 +00:00
|
|
|
BlockContainers: blkContainers[96:100],
|
|
|
|
NextPageToken: strconv.Itoa(1),
|
|
|
|
TotalSize: int32(params.BeaconConfig().SlotsPerEpoch / 2)}},
|
2019-11-12 17:01:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
res, err := bs.ListBlocks(ctx, test.req)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if !proto.Equal(res, test.res) {
|
2019-11-18 16:15:45 +00:00
|
|
|
t.Errorf("Incorrect blocks response, wanted %d, received %d", len(test.res.BlockContainers), len(res.BlockContainers))
|
2019-11-12 17:01:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestServer_ListBlocks_Errors(t *testing.T) {
|
|
|
|
db := dbTest.SetupDB(t)
|
|
|
|
defer dbTest.TeardownDB(t, db)
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
bs := &Server{BeaconDB: db}
|
|
|
|
exceedsMax := int32(params.BeaconConfig().MaxPageSize + 1)
|
|
|
|
|
2019-11-13 21:03:12 +00:00
|
|
|
wanted := fmt.Sprintf("Requested page size %d can not be greater than max size %d", exceedsMax, params.BeaconConfig().MaxPageSize)
|
2019-11-12 17:01:27 +00:00
|
|
|
req := ðpb.ListBlocksRequest{PageToken: strconv.Itoa(0), PageSize: exceedsMax}
|
|
|
|
if _, err := bs.ListBlocks(ctx, req); !strings.Contains(err.Error(), wanted) {
|
|
|
|
t.Errorf("Expected error %v, received %v", wanted, err)
|
|
|
|
}
|
|
|
|
|
2019-11-18 23:24:33 +00:00
|
|
|
wanted = "Must specify a filter criteria for fetching"
|
2019-11-12 17:01:27 +00:00
|
|
|
req = ðpb.ListBlocksRequest{}
|
|
|
|
if _, err := bs.ListBlocks(ctx, req); !strings.Contains(err.Error(), wanted) {
|
|
|
|
t.Errorf("Expected error %v, received %v", wanted, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
req = ðpb.ListBlocksRequest{QueryFilter: ðpb.ListBlocksRequest_Epoch{}}
|
|
|
|
res, err := bs.ListBlocks(ctx, req)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2019-11-18 16:15:45 +00:00
|
|
|
if len(res.BlockContainers) != 0 {
|
|
|
|
t.Errorf("wanted empty list, got a list of %d", len(res.BlockContainers))
|
2019-11-12 17:01:27 +00:00
|
|
|
}
|
|
|
|
if res.TotalSize != 0 {
|
|
|
|
t.Errorf("wanted total size 0, got size %d", res.TotalSize)
|
|
|
|
}
|
|
|
|
|
|
|
|
req = ðpb.ListBlocksRequest{QueryFilter: ðpb.ListBlocksRequest_Slot{}}
|
|
|
|
res, err = bs.ListBlocks(ctx, req)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2019-11-18 16:15:45 +00:00
|
|
|
if len(res.BlockContainers) != 0 {
|
|
|
|
t.Errorf("wanted empty list, got a list of %d", len(res.BlockContainers))
|
2019-11-12 17:01:27 +00:00
|
|
|
}
|
|
|
|
if res.TotalSize != 0 {
|
|
|
|
t.Errorf("wanted total size 0, got size %d", res.TotalSize)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
req = ðpb.ListBlocksRequest{QueryFilter: ðpb.ListBlocksRequest_Root{Root: []byte{'A'}}}
|
|
|
|
res, err = bs.ListBlocks(ctx, req)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2019-11-18 16:15:45 +00:00
|
|
|
if len(res.BlockContainers) != 0 {
|
|
|
|
t.Errorf("wanted empty list, got a list of %d", len(res.BlockContainers))
|
2019-11-12 17:01:27 +00:00
|
|
|
}
|
|
|
|
if res.TotalSize != 0 {
|
|
|
|
t.Errorf("wanted total size 0, got size %d", res.TotalSize)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
req = ðpb.ListBlocksRequest{QueryFilter: ðpb.ListBlocksRequest_Root{Root: []byte{'A'}}}
|
|
|
|
res, err = bs.ListBlocks(ctx, req)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2019-11-18 16:15:45 +00:00
|
|
|
if len(res.BlockContainers) != 0 {
|
|
|
|
t.Errorf("wanted empty list, got a list of %d", len(res.BlockContainers))
|
2019-11-12 17:01:27 +00:00
|
|
|
}
|
|
|
|
if res.TotalSize != 0 {
|
|
|
|
t.Errorf("wanted total size 0, got size %d", res.TotalSize)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|