mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 21:38:05 -05:00
refactoring: Deduplicate code (#10090)
* Deduplicate sync committee indices from state * Deduplicate code in listblocks RPC endpoints, which only differ in response object * Deduplicate test code in config/fieldparams * Delete stale benchmark target. This is already included in go_default_test * deduplicate test cases in TestIsSlashableValidator_OK and fix blst BUILD file * Deduplicate TestStore_IsFinalizedChildBlock * Revert crypto/bls/blst/BUILD.bazel * Deduplicate TestStore_SaveBlock_NoDuplicates * Use a generic wrapper for beacon blocks to streamline test * Deduplicate TestStore_BlocksCRUD * Deduplicate TestStore_BlocksHandleZeroCase * Deduplicate TestStore_BlocksBatchDelete * deduplicate TestStore_BlocksHandleInvalidEndSlot * Deduplicate TestStore_BlocksCRUD_NoCache * Deduplicate common block test setup. Make TestStore_Blocks_FiltersCorrectly support multiple forks in test * Deduplicate the rest of these tests * lint * Deprecation warning * Add test for WrappedSignedBeaconBlock * Test error path
This commit is contained in:
@@ -131,94 +131,19 @@ func TestIsSlashableValidator_OK(t *testing.T) {
|
|||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
slashableValidator := IsSlashableValidator(test.validator.ActivationEpoch,
|
t.Run("without trie", func(t *testing.T) {
|
||||||
test.validator.WithdrawableEpoch, test.validator.Slashed, test.epoch)
|
slashableValidator := IsSlashableValidator(test.validator.ActivationEpoch,
|
||||||
assert.Equal(t, test.slashable, slashableValidator, "Expected active validator slashable to be %t", test.slashable)
|
test.validator.WithdrawableEpoch, test.validator.Slashed, test.epoch)
|
||||||
})
|
assert.Equal(t, test.slashable, slashableValidator, "Expected active validator slashable to be %t", test.slashable)
|
||||||
}
|
})
|
||||||
}
|
t.Run("with trie", func(t *testing.T) {
|
||||||
|
beaconState, err := v1.InitializeFromProto(ðpb.BeaconState{Validators: []*ethpb.Validator{test.validator}})
|
||||||
func TestIsSlashableValidatorUsingTrie_OK(t *testing.T) {
|
require.NoError(t, err)
|
||||||
tests := []struct {
|
readOnlyVal, err := beaconState.ValidatorAtIndexReadOnly(0)
|
||||||
name string
|
require.NoError(t, err)
|
||||||
validator *ethpb.Validator
|
slashableValidator := IsSlashableValidatorUsingTrie(readOnlyVal, test.epoch)
|
||||||
epoch types.Epoch
|
assert.Equal(t, test.slashable, slashableValidator, "Expected active validator slashable to be %t", test.slashable)
|
||||||
slashable bool
|
})
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "Unset withdrawable, slashable",
|
|
||||||
validator: ðpb.Validator{
|
|
||||||
WithdrawableEpoch: params.BeaconConfig().FarFutureEpoch,
|
|
||||||
},
|
|
||||||
epoch: 0,
|
|
||||||
slashable: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "before withdrawable, slashable",
|
|
||||||
validator: ðpb.Validator{
|
|
||||||
WithdrawableEpoch: 5,
|
|
||||||
},
|
|
||||||
epoch: 3,
|
|
||||||
slashable: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "inactive, not slashable",
|
|
||||||
validator: ðpb.Validator{
|
|
||||||
ActivationEpoch: 5,
|
|
||||||
WithdrawableEpoch: params.BeaconConfig().FarFutureEpoch,
|
|
||||||
},
|
|
||||||
epoch: 2,
|
|
||||||
slashable: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "after withdrawable, not slashable",
|
|
||||||
validator: ðpb.Validator{
|
|
||||||
WithdrawableEpoch: 3,
|
|
||||||
},
|
|
||||||
epoch: 3,
|
|
||||||
slashable: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "slashed and withdrawable, not slashable",
|
|
||||||
validator: ðpb.Validator{
|
|
||||||
Slashed: true,
|
|
||||||
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
|
|
||||||
WithdrawableEpoch: 1,
|
|
||||||
},
|
|
||||||
epoch: 2,
|
|
||||||
slashable: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "slashed, not slashable",
|
|
||||||
validator: ðpb.Validator{
|
|
||||||
Slashed: true,
|
|
||||||
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
|
|
||||||
WithdrawableEpoch: params.BeaconConfig().FarFutureEpoch,
|
|
||||||
},
|
|
||||||
epoch: 2,
|
|
||||||
slashable: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "inactive and slashed, not slashable",
|
|
||||||
validator: ðpb.Validator{
|
|
||||||
Slashed: true,
|
|
||||||
ActivationEpoch: 4,
|
|
||||||
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
|
|
||||||
WithdrawableEpoch: params.BeaconConfig().FarFutureEpoch,
|
|
||||||
},
|
|
||||||
epoch: 2,
|
|
||||||
slashable: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range tests {
|
|
||||||
beaconState, err := v1.InitializeFromProto(ðpb.BeaconState{Validators: []*ethpb.Validator{test.validator}})
|
|
||||||
require.NoError(t, err)
|
|
||||||
readOnlyVal, err := beaconState.ValidatorAtIndexReadOnly(0)
|
|
||||||
require.NoError(t, err)
|
|
||||||
t.Run(test.name, func(t *testing.T) {
|
|
||||||
slashableValidator := IsSlashableValidatorUsingTrie(readOnlyVal, test.epoch)
|
|
||||||
assert.Equal(t, test.slashable, slashableValidator, "Expected active validator slashable to be %t", test.slashable)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
|
||||||
|
|
||||||
# gazelle:exclude testdata
|
|
||||||
|
|
||||||
go_library(
|
go_library(
|
||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = [
|
srcs = [
|
||||||
@@ -105,31 +103,3 @@ go_test(
|
|||||||
"@org_golang_google_protobuf//proto:go_default_library",
|
"@org_golang_google_protobuf//proto:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
go_test(
|
|
||||||
name = "go_benchmark_test",
|
|
||||||
size = "large",
|
|
||||||
srcs = ["benchmarks_test.go"],
|
|
||||||
args = [
|
|
||||||
"-test.bench=.",
|
|
||||||
"-test.benchmem",
|
|
||||||
"-test.v",
|
|
||||||
],
|
|
||||||
local = True,
|
|
||||||
tags = [
|
|
||||||
"benchmark",
|
|
||||||
"manual",
|
|
||||||
"no-cache",
|
|
||||||
],
|
|
||||||
deps = [
|
|
||||||
"//beacon-chain/core/blocks:go_default_library",
|
|
||||||
"//beacon-chain/core/helpers:go_default_library",
|
|
||||||
"//beacon-chain/core/transition:go_default_library",
|
|
||||||
"//beacon-chain/state/v1:go_default_library",
|
|
||||||
"//config/params:go_default_library",
|
|
||||||
"//proto/prysm/v1alpha1:go_default_library",
|
|
||||||
"//testing/benchmark:go_default_library",
|
|
||||||
"//testing/require:go_default_library",
|
|
||||||
"@org_golang_google_protobuf//proto:go_default_library",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -77,8 +77,6 @@ go_test(
|
|||||||
srcs = [
|
srcs = [
|
||||||
"archived_point_test.go",
|
"archived_point_test.go",
|
||||||
"backup_test.go",
|
"backup_test.go",
|
||||||
"block_altair_test.go",
|
|
||||||
"block_merge_test.go",
|
|
||||||
"blocks_test.go",
|
"blocks_test.go",
|
||||||
"checkpoint_test.go",
|
"checkpoint_test.go",
|
||||||
"deposit_contract_test.go",
|
"deposit_contract_test.go",
|
||||||
|
|||||||
@@ -1,534 +0,0 @@
|
|||||||
package kv
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"sort"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/db/filters"
|
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
|
||||||
v2 "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestStore_SaveAltairBlock_NoDuplicates(t *testing.T) {
|
|
||||||
BlockCacheSize = 1
|
|
||||||
db := setupDB(t)
|
|
||||||
slot := types.Slot(20)
|
|
||||||
ctx := context.Background()
|
|
||||||
// First we save a previous block to ensure the cache max size is reached.
|
|
||||||
prevBlock := util.NewBeaconBlockAltair()
|
|
||||||
prevBlock.Block.Slot = slot - 1
|
|
||||||
prevBlock.Block.ParentRoot = bytesutil.PadTo([]byte{1, 2, 3}, 32)
|
|
||||||
wsb, err := wrapper.WrappedAltairSignedBeaconBlock(prevBlock)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wsb))
|
|
||||||
|
|
||||||
block := util.NewBeaconBlockAltair()
|
|
||||||
block.Block.Slot = slot
|
|
||||||
block.Block.ParentRoot = bytesutil.PadTo([]byte{1, 2, 3}, 32)
|
|
||||||
// Even with a full cache, saving new blocks should not cause
|
|
||||||
// duplicated blocks in the DB.
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
wsb, err = wrapper.WrappedAltairSignedBeaconBlock(block)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wsb))
|
|
||||||
}
|
|
||||||
f := filters.NewFilter().SetStartSlot(slot).SetEndSlot(slot)
|
|
||||||
retrieved, _, err := db.Blocks(ctx, f)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 1, len(retrieved))
|
|
||||||
// We reset the block cache size.
|
|
||||||
BlockCacheSize = 256
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_AltairBlocksCRUD(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
block := util.NewBeaconBlockAltair()
|
|
||||||
block.Block.Slot = 20
|
|
||||||
block.Block.ParentRoot = bytesutil.PadTo([]byte{1, 2, 3}, 32)
|
|
||||||
|
|
||||||
blockRoot, err := block.Block.HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
retrievedBlock, err := db.Block(ctx, blockRoot)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.DeepEqual(t, nil, retrievedBlock, "Expected nil block")
|
|
||||||
wsb, err := wrapper.WrappedAltairSignedBeaconBlock(block)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wsb))
|
|
||||||
assert.Equal(t, true, db.HasBlock(ctx, blockRoot), "Expected block to exist in the db")
|
|
||||||
retrievedBlock, err = db.Block(ctx, blockRoot)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, true, proto.Equal(block, retrievedBlock.Proto()), "Wanted: %v, received: %v", block, retrievedBlock)
|
|
||||||
require.NoError(t, db.deleteBlock(ctx, blockRoot))
|
|
||||||
assert.Equal(t, false, db.HasBlock(ctx, blockRoot), "Expected block to have been deleted from the db")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_AltairBlocksBatchDelete(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
numBlocks := 10
|
|
||||||
totalBlocks := make([]block.SignedBeaconBlock, numBlocks)
|
|
||||||
blockRoots := make([][32]byte, 0)
|
|
||||||
oddBlocks := make([]block.SignedBeaconBlock, 0)
|
|
||||||
for i := 0; i < len(totalBlocks); i++ {
|
|
||||||
b := util.NewBeaconBlockAltair()
|
|
||||||
b.Block.Slot = types.Slot(i)
|
|
||||||
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
|
||||||
wb, err := wrapper.WrappedAltairSignedBeaconBlock(b)
|
|
||||||
require.NoError(t, err)
|
|
||||||
totalBlocks[i] = wb
|
|
||||||
if i%2 == 0 {
|
|
||||||
r, err := totalBlocks[i].Block().HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
blockRoots = append(blockRoots, r)
|
|
||||||
} else {
|
|
||||||
oddBlocks = append(oddBlocks, totalBlocks[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
|
||||||
retrieved, _, err := db.Blocks(ctx, filters.NewFilter().SetParentRoot(bytesutil.PadTo([]byte("parent"), 32)))
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, numBlocks, len(retrieved), "Unexpected number of blocks received")
|
|
||||||
// We delete all even indexed blocks.
|
|
||||||
require.NoError(t, db.deleteBlocks(ctx, blockRoots))
|
|
||||||
// When we retrieve the data, only the odd indexed blocks should remain.
|
|
||||||
retrieved, _, err = db.Blocks(ctx, filters.NewFilter().SetParentRoot(bytesutil.PadTo([]byte("parent"), 32)))
|
|
||||||
require.NoError(t, err)
|
|
||||||
sort.Slice(retrieved, func(i, j int) bool {
|
|
||||||
return retrieved[i].Block().Slot() < retrieved[j].Block().Slot()
|
|
||||||
})
|
|
||||||
for i, block := range retrieved {
|
|
||||||
assert.Equal(t, true, proto.Equal(block.Proto(), oddBlocks[i].Proto()), "Wanted: %v, received: %v", block, oddBlocks[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_AltairBlocksHandleZeroCase(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
numBlocks := 10
|
|
||||||
totalBlocks := make([]block.SignedBeaconBlock, numBlocks)
|
|
||||||
for i := 0; i < len(totalBlocks); i++ {
|
|
||||||
b := util.NewBeaconBlockAltair()
|
|
||||||
b.Block.Slot = types.Slot(i)
|
|
||||||
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
|
||||||
wb, err := wrapper.WrappedAltairSignedBeaconBlock(b)
|
|
||||||
require.NoError(t, err)
|
|
||||||
totalBlocks[i] = wb
|
|
||||||
_, err = totalBlocks[i].Block().HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
|
||||||
zeroFilter := filters.NewFilter().SetStartSlot(0).SetEndSlot(0)
|
|
||||||
retrieved, _, err := db.Blocks(ctx, zeroFilter)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 1, len(retrieved), "Unexpected number of blocks received, expected one")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_AltairBlocksHandleInvalidEndSlot(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
numBlocks := 10
|
|
||||||
totalBlocks := make([]block.SignedBeaconBlock, numBlocks)
|
|
||||||
// Save blocks from slot 1 onwards.
|
|
||||||
for i := 0; i < len(totalBlocks); i++ {
|
|
||||||
b := util.NewBeaconBlockAltair()
|
|
||||||
b.Block.Slot = types.Slot(i) + 1
|
|
||||||
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
|
||||||
wb, err := wrapper.WrappedAltairSignedBeaconBlock(b)
|
|
||||||
require.NoError(t, err)
|
|
||||||
totalBlocks[i] = wb
|
|
||||||
_, err = totalBlocks[i].Block().HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
|
||||||
badFilter := filters.NewFilter().SetStartSlot(5).SetEndSlot(1)
|
|
||||||
_, _, err := db.Blocks(ctx, badFilter)
|
|
||||||
require.ErrorContains(t, errInvalidSlotRange.Error(), err)
|
|
||||||
|
|
||||||
goodFilter := filters.NewFilter().SetStartSlot(0).SetEndSlot(1)
|
|
||||||
requested, _, err := db.Blocks(ctx, goodFilter)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 1, len(requested), "Unexpected number of blocks received, only expected two")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_AltairBlocksCRUD_NoCache(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
block := util.NewBeaconBlockAltair()
|
|
||||||
block.Block.Slot = 20
|
|
||||||
block.Block.ParentRoot = bytesutil.PadTo([]byte{1, 2, 3}, 32)
|
|
||||||
blockRoot, err := block.Block.HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
retrievedBlock, err := db.Block(ctx, blockRoot)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.DeepEqual(t, nil, retrievedBlock, "Expected nil block")
|
|
||||||
wsb, err := wrapper.WrappedAltairSignedBeaconBlock(block)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wsb))
|
|
||||||
db.blockCache.Del(string(blockRoot[:]))
|
|
||||||
assert.Equal(t, true, db.HasBlock(ctx, blockRoot), "Expected block to exist in the db")
|
|
||||||
retrievedBlock, err = db.Block(ctx, blockRoot)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, true, proto.Equal(block, retrievedBlock.Proto()), "Wanted: %v, received: %v", block, retrievedBlock)
|
|
||||||
require.NoError(t, db.deleteBlock(ctx, blockRoot))
|
|
||||||
assert.Equal(t, false, db.HasBlock(ctx, blockRoot), "Expected block to have been deleted from the db")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_AltairBlocks_FiltersCorrectly(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
b4 := util.NewBeaconBlockAltair()
|
|
||||||
b4.Block.Slot = 4
|
|
||||||
b4.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
|
||||||
b5 := util.NewBeaconBlockAltair()
|
|
||||||
b5.Block.Slot = 5
|
|
||||||
b5.Block.ParentRoot = bytesutil.PadTo([]byte("parent2"), 32)
|
|
||||||
b6 := util.NewBeaconBlockAltair()
|
|
||||||
b6.Block.Slot = 6
|
|
||||||
b6.Block.ParentRoot = bytesutil.PadTo([]byte("parent2"), 32)
|
|
||||||
b7 := util.NewBeaconBlockAltair()
|
|
||||||
b7.Block.Slot = 7
|
|
||||||
b7.Block.ParentRoot = bytesutil.PadTo([]byte("parent3"), 32)
|
|
||||||
b8 := util.NewBeaconBlockAltair()
|
|
||||||
b8.Block.Slot = 8
|
|
||||||
b8.Block.ParentRoot = bytesutil.PadTo([]byte("parent4"), 32)
|
|
||||||
blocks := make([]block.SignedBeaconBlock, 0)
|
|
||||||
for _, b := range []*v2.SignedBeaconBlockAltair{b4, b5, b6, b7, b8} {
|
|
||||||
blk, err := wrapper.WrappedAltairSignedBeaconBlock(b)
|
|
||||||
require.NoError(t, err)
|
|
||||||
blocks = append(blocks, blk)
|
|
||||||
}
|
|
||||||
ctx := context.Background()
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, blocks))
|
|
||||||
|
|
||||||
tests := []struct {
|
|
||||||
filter *filters.QueryFilter
|
|
||||||
expectedNumBlocks int
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
filter: filters.NewFilter().SetParentRoot(bytesutil.PadTo([]byte("parent2"), 32)),
|
|
||||||
expectedNumBlocks: 2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// No block meets the criteria below.
|
|
||||||
filter: filters.NewFilter().SetParentRoot(bytesutil.PadTo([]byte{3, 4, 5}, 32)),
|
|
||||||
expectedNumBlocks: 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// Block slot range filter criteria.
|
|
||||||
filter: filters.NewFilter().SetStartSlot(5).SetEndSlot(7),
|
|
||||||
expectedNumBlocks: 3,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filter: filters.NewFilter().SetStartSlot(7).SetEndSlot(7),
|
|
||||||
expectedNumBlocks: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filter: filters.NewFilter().SetStartSlot(4).SetEndSlot(8),
|
|
||||||
expectedNumBlocks: 5,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filter: filters.NewFilter().SetStartSlot(4).SetEndSlot(5),
|
|
||||||
expectedNumBlocks: 2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filter: filters.NewFilter().SetStartSlot(5).SetEndSlot(9),
|
|
||||||
expectedNumBlocks: 4,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filter: filters.NewFilter().SetEndSlot(7),
|
|
||||||
expectedNumBlocks: 4,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filter: filters.NewFilter().SetEndSlot(8),
|
|
||||||
expectedNumBlocks: 5,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filter: filters.NewFilter().SetStartSlot(5).SetEndSlot(10),
|
|
||||||
expectedNumBlocks: 4,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// Composite filter criteria.
|
|
||||||
filter: filters.NewFilter().
|
|
||||||
SetParentRoot(bytesutil.PadTo([]byte("parent2"), 32)).
|
|
||||||
SetStartSlot(6).
|
|
||||||
SetEndSlot(8),
|
|
||||||
expectedNumBlocks: 1,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
retrievedBlocks, _, err := db.Blocks(ctx, tt.filter)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, tt.expectedNumBlocks, len(retrievedBlocks), "Unexpected number of blocks")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_AltairBlocks_VerifyBlockRoots(t *testing.T) {
|
|
||||||
ctx := context.Background()
|
|
||||||
db := setupDB(t)
|
|
||||||
b1 := util.NewBeaconBlockAltair()
|
|
||||||
b1.Block.Slot = 1
|
|
||||||
r1, err := b1.Block.HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
b2 := util.NewBeaconBlockAltair()
|
|
||||||
b2.Block.Slot = 2
|
|
||||||
r2, err := b2.Block.HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
for _, b := range []*v2.SignedBeaconBlockAltair{b1, b2} {
|
|
||||||
wsb, err := wrapper.WrappedAltairSignedBeaconBlock(b)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wsb))
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := filters.NewFilter().SetStartSlot(b1.Block.Slot).SetEndSlot(b2.Block.Slot)
|
|
||||||
roots, err := db.BlockRoots(ctx, filter)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
assert.DeepEqual(t, [][32]byte{r1, r2}, roots)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_AltairBlocks_Retrieve_SlotRange(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
totalBlocks := make([]block.SignedBeaconBlock, 500)
|
|
||||||
for i := 0; i < 500; i++ {
|
|
||||||
b := util.NewBeaconBlockAltair()
|
|
||||||
b.Block.Slot = types.Slot(i)
|
|
||||||
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
|
||||||
wb, err := wrapper.WrappedAltairSignedBeaconBlock(b)
|
|
||||||
require.NoError(t, err)
|
|
||||||
totalBlocks[i] = wb
|
|
||||||
}
|
|
||||||
ctx := context.Background()
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
|
||||||
retrieved, _, err := db.Blocks(ctx, filters.NewFilter().SetStartSlot(100).SetEndSlot(399))
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 300, len(retrieved))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_AltairBlocks_Retrieve_Epoch(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
slots := params.BeaconConfig().SlotsPerEpoch.Mul(7)
|
|
||||||
totalBlocks := make([]block.SignedBeaconBlock, slots)
|
|
||||||
for i := types.Slot(0); i < slots; i++ {
|
|
||||||
b := util.NewBeaconBlockAltair()
|
|
||||||
b.Block.Slot = i
|
|
||||||
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
|
||||||
wb, err := wrapper.WrappedAltairSignedBeaconBlock(b)
|
|
||||||
require.NoError(t, err)
|
|
||||||
totalBlocks[i] = wb
|
|
||||||
}
|
|
||||||
ctx := context.Background()
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
|
||||||
retrieved, _, err := db.Blocks(ctx, filters.NewFilter().SetStartEpoch(5).SetEndEpoch(6))
|
|
||||||
require.NoError(t, err)
|
|
||||||
want := params.BeaconConfig().SlotsPerEpoch.Mul(2)
|
|
||||||
assert.Equal(t, uint64(want), uint64(len(retrieved)))
|
|
||||||
retrieved, _, err = db.Blocks(ctx, filters.NewFilter().SetStartEpoch(0).SetEndEpoch(0))
|
|
||||||
require.NoError(t, err)
|
|
||||||
want = params.BeaconConfig().SlotsPerEpoch
|
|
||||||
assert.Equal(t, uint64(want), uint64(len(retrieved)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_AltairBlocks_Retrieve_SlotRangeWithStep(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
totalBlocks := make([]block.SignedBeaconBlock, 500)
|
|
||||||
for i := 0; i < 500; i++ {
|
|
||||||
b := util.NewBeaconBlockAltair()
|
|
||||||
b.Block.Slot = types.Slot(i)
|
|
||||||
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
|
||||||
wb, err := wrapper.WrappedAltairSignedBeaconBlock(b)
|
|
||||||
require.NoError(t, err)
|
|
||||||
totalBlocks[i] = wb
|
|
||||||
}
|
|
||||||
const step = 2
|
|
||||||
ctx := context.Background()
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
|
||||||
retrieved, _, err := db.Blocks(ctx, filters.NewFilter().SetStartSlot(100).SetEndSlot(399).SetSlotStep(step))
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 150, len(retrieved))
|
|
||||||
for _, b := range retrieved {
|
|
||||||
assert.Equal(t, types.Slot(0), (b.Block().Slot()-100)%step, "Unexpect block slot %d", b.Block().Slot())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_SaveAltairBlock_CanGetHighestAt(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
block1 := util.NewBeaconBlockAltair()
|
|
||||||
block1.Block.Slot = 1
|
|
||||||
block2 := util.NewBeaconBlockAltair()
|
|
||||||
block2.Block.Slot = 10
|
|
||||||
block3 := util.NewBeaconBlockAltair()
|
|
||||||
block3.Block.Slot = 100
|
|
||||||
|
|
||||||
for _, b := range []*v2.SignedBeaconBlockAltair{block1, block2, block3} {
|
|
||||||
wsb, err := wrapper.WrappedAltairSignedBeaconBlock(b)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wsb))
|
|
||||||
}
|
|
||||||
|
|
||||||
highestAt, err := db.HighestSlotBlocksBelow(ctx, 2)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, false, len(highestAt) <= 0, "Got empty highest at slice")
|
|
||||||
assert.Equal(t, true, proto.Equal(block1, highestAt[0].Proto()), "Wanted: %v, received: %v", block1, highestAt[0])
|
|
||||||
highestAt, err = db.HighestSlotBlocksBelow(ctx, 11)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, false, len(highestAt) <= 0, "Got empty highest at slice")
|
|
||||||
assert.Equal(t, true, proto.Equal(block2, highestAt[0].Proto()), "Wanted: %v, received: %v", block2, highestAt[0])
|
|
||||||
highestAt, err = db.HighestSlotBlocksBelow(ctx, 101)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, false, len(highestAt) <= 0, "Got empty highest at slice")
|
|
||||||
assert.Equal(t, true, proto.Equal(block3, highestAt[0].Proto()), "Wanted: %v, received: %v", block3, highestAt[0])
|
|
||||||
|
|
||||||
r3, err := block3.Block.HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.deleteBlock(ctx, r3))
|
|
||||||
|
|
||||||
highestAt, err = db.HighestSlotBlocksBelow(ctx, 101)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, true, proto.Equal(block2, highestAt[0].Proto()), "Wanted: %v, received: %v", block2, highestAt[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_GenesisAltairBlock_CanGetHighestAt(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
genesisBlock := util.NewBeaconBlockAltair()
|
|
||||||
genesisRoot, err := genesisBlock.Block.HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.SaveGenesisBlockRoot(ctx, genesisRoot))
|
|
||||||
wsb, err := wrapper.WrappedAltairSignedBeaconBlock(genesisBlock)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wsb))
|
|
||||||
block1 := util.NewBeaconBlockAltair()
|
|
||||||
block1.Block.Slot = 1
|
|
||||||
wsb, err = wrapper.WrappedAltairSignedBeaconBlock(block1)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wsb))
|
|
||||||
|
|
||||||
highestAt, err := db.HighestSlotBlocksBelow(ctx, 2)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, true, proto.Equal(block1, highestAt[0].Proto()), "Wanted: %v, received: %v", block1, highestAt[0])
|
|
||||||
highestAt, err = db.HighestSlotBlocksBelow(ctx, 1)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, true, proto.Equal(genesisBlock, highestAt[0].Proto()), "Wanted: %v, received: %v", genesisBlock, highestAt[0])
|
|
||||||
highestAt, err = db.HighestSlotBlocksBelow(ctx, 0)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, true, proto.Equal(genesisBlock, highestAt[0].Proto()), "Wanted: %v, received: %v", genesisBlock, highestAt[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_SaveAltairBlocks_HasCachedBlocks(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
var err error
|
|
||||||
b := make([]block.SignedBeaconBlock, 500)
|
|
||||||
for i := 0; i < 500; i++ {
|
|
||||||
blk := util.NewBeaconBlockAltair()
|
|
||||||
blk.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
|
||||||
blk.Block.Slot = types.Slot(i)
|
|
||||||
b[i], err = wrapper.WrappedAltairSignedBeaconBlock(blk)
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, b[0]))
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, b))
|
|
||||||
f := filters.NewFilter().SetStartSlot(0).SetEndSlot(500)
|
|
||||||
|
|
||||||
blks, _, err := db.Blocks(ctx, f)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 500, len(blks), "Did not get wanted blocks")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_SaveAltairBlocks_HasRootsMatched(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
var err error
|
|
||||||
b := make([]block.SignedBeaconBlock, 500)
|
|
||||||
for i := 0; i < 500; i++ {
|
|
||||||
blk := util.NewBeaconBlockAltair()
|
|
||||||
blk.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
|
||||||
blk.Block.Slot = types.Slot(i)
|
|
||||||
b[i], err = wrapper.WrappedAltairSignedBeaconBlock(blk)
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, b))
|
|
||||||
f := filters.NewFilter().SetStartSlot(0).SetEndSlot(500)
|
|
||||||
|
|
||||||
blks, roots, err := db.Blocks(ctx, f)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 500, len(blks), "Did not get wanted blocks")
|
|
||||||
|
|
||||||
for i, blk := range blks {
|
|
||||||
rt, err := blk.Block().HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, roots[i], rt, "mismatch of block roots")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_AltairBlocksBySlot_BlockRootsBySlot(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
b1 := util.NewBeaconBlockAltair()
|
|
||||||
b1.Block.Slot = 20
|
|
||||||
b2 := util.NewBeaconBlockAltair()
|
|
||||||
b2.Block.Slot = 100
|
|
||||||
b2.Block.ParentRoot = bytesutil.PadTo([]byte("parent1"), 32)
|
|
||||||
b3 := util.NewBeaconBlockAltair()
|
|
||||||
b3.Block.Slot = 100
|
|
||||||
b3.Block.ParentRoot = bytesutil.PadTo([]byte("parent2"), 32)
|
|
||||||
|
|
||||||
for _, b := range []*v2.SignedBeaconBlockAltair{b1, b2, b3} {
|
|
||||||
wsb, err := wrapper.WrappedAltairSignedBeaconBlock(b)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wsb))
|
|
||||||
}
|
|
||||||
|
|
||||||
r1, err := b1.Block.HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
r2, err := b2.Block.HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
r3, err := b3.Block.HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
hasBlocks, retrievedBlocks, err := db.BlocksBySlot(ctx, 1)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 0, len(retrievedBlocks), "Unexpected number of blocks received, expected none")
|
|
||||||
assert.Equal(t, false, hasBlocks, "Expected no blocks")
|
|
||||||
hasBlocks, retrievedBlocks, err = db.BlocksBySlot(ctx, 20)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, true, proto.Equal(b1, retrievedBlocks[0].Proto()), "Wanted: %v, received: %v", b1, retrievedBlocks[0])
|
|
||||||
assert.Equal(t, true, hasBlocks, "Expected to have blocks")
|
|
||||||
hasBlocks, retrievedBlocks, err = db.BlocksBySlot(ctx, 100)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, true, proto.Equal(b2, retrievedBlocks[0].Proto()), "Wanted: %v, received: %v", b2, retrievedBlocks[0])
|
|
||||||
assert.Equal(t, true, proto.Equal(b3, retrievedBlocks[1].Proto()), "Wanted: %v, received: %v", b3, retrievedBlocks[1])
|
|
||||||
assert.Equal(t, true, hasBlocks, "Expected to have blocks")
|
|
||||||
|
|
||||||
hasBlockRoots, retrievedBlockRoots, err := db.BlockRootsBySlot(ctx, 1)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.DeepEqual(t, [][32]byte{}, retrievedBlockRoots)
|
|
||||||
assert.Equal(t, false, hasBlockRoots, "Expected no block roots")
|
|
||||||
hasBlockRoots, retrievedBlockRoots, err = db.BlockRootsBySlot(ctx, 20)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.DeepEqual(t, [][32]byte{r1}, retrievedBlockRoots)
|
|
||||||
assert.Equal(t, true, hasBlockRoots, "Expected no block roots")
|
|
||||||
hasBlockRoots, retrievedBlockRoots, err = db.BlockRootsBySlot(ctx, 100)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.DeepEqual(t, [][32]byte{r2, r3}, retrievedBlockRoots)
|
|
||||||
assert.Equal(t, true, hasBlockRoots, "Expected no block roots")
|
|
||||||
}
|
|
||||||
@@ -1,534 +0,0 @@
|
|||||||
package kv
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"sort"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
types "github.com/prysmaticlabs/eth2-types"
|
|
||||||
"github.com/prysmaticlabs/prysm/beacon-chain/db/filters"
|
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
|
||||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
|
||||||
v2 "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
|
|
||||||
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/wrapper"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/require"
|
|
||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestStore_SaveBellatrixBlock_NoDuplicates(t *testing.T) {
|
|
||||||
BlockCacheSize = 1
|
|
||||||
db := setupDB(t)
|
|
||||||
slot := types.Slot(20)
|
|
||||||
ctx := context.Background()
|
|
||||||
// First we save a previous block to ensure the cache max size is reached.
|
|
||||||
prevBlock := util.NewBeaconBlockMerge()
|
|
||||||
prevBlock.Block.Slot = slot - 1
|
|
||||||
prevBlock.Block.ParentRoot = bytesutil.PadTo([]byte{1, 2, 3}, 32)
|
|
||||||
wsb, err := wrapper.WrappedMergeSignedBeaconBlock(prevBlock)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wsb))
|
|
||||||
|
|
||||||
block := util.NewBeaconBlockMerge()
|
|
||||||
block.Block.Slot = slot
|
|
||||||
block.Block.ParentRoot = bytesutil.PadTo([]byte{1, 2, 3}, 32)
|
|
||||||
// Even with a full cache, saving new blocks should not cause
|
|
||||||
// duplicated blocks in the DB.
|
|
||||||
for i := 0; i < 100; i++ {
|
|
||||||
wsb, err = wrapper.WrappedMergeSignedBeaconBlock(block)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wsb))
|
|
||||||
}
|
|
||||||
f := filters.NewFilter().SetStartSlot(slot).SetEndSlot(slot)
|
|
||||||
retrieved, _, err := db.Blocks(ctx, f)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 1, len(retrieved))
|
|
||||||
// We reset the block cache size.
|
|
||||||
BlockCacheSize = 256
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_BellatrixBlocksCRUD(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
block := util.NewBeaconBlockMerge()
|
|
||||||
block.Block.Slot = 20
|
|
||||||
block.Block.ParentRoot = bytesutil.PadTo([]byte{1, 2, 3}, 32)
|
|
||||||
|
|
||||||
blockRoot, err := block.Block.HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
retrievedBlock, err := db.Block(ctx, blockRoot)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.DeepEqual(t, nil, retrievedBlock, "Expected nil block")
|
|
||||||
wsb, err := wrapper.WrappedMergeSignedBeaconBlock(block)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wsb))
|
|
||||||
assert.Equal(t, true, db.HasBlock(ctx, blockRoot), "Expected block to exist in the db")
|
|
||||||
retrievedBlock, err = db.Block(ctx, blockRoot)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, true, proto.Equal(block, retrievedBlock.Proto()), "Wanted: %v, received: %v", block, retrievedBlock)
|
|
||||||
require.NoError(t, db.deleteBlock(ctx, blockRoot))
|
|
||||||
assert.Equal(t, false, db.HasBlock(ctx, blockRoot), "Expected block to have been deleted from the db")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_BellatrixBlocksBatchDelete(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
numBlocks := 10
|
|
||||||
totalBlocks := make([]block.SignedBeaconBlock, numBlocks)
|
|
||||||
blockRoots := make([][32]byte, 0)
|
|
||||||
oddBlocks := make([]block.SignedBeaconBlock, 0)
|
|
||||||
for i := 0; i < len(totalBlocks); i++ {
|
|
||||||
b := util.NewBeaconBlockMerge()
|
|
||||||
b.Block.Slot = types.Slot(i)
|
|
||||||
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
|
||||||
wb, err := wrapper.WrappedMergeSignedBeaconBlock(b)
|
|
||||||
require.NoError(t, err)
|
|
||||||
totalBlocks[i] = wb
|
|
||||||
if i%2 == 0 {
|
|
||||||
r, err := totalBlocks[i].Block().HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
blockRoots = append(blockRoots, r)
|
|
||||||
} else {
|
|
||||||
oddBlocks = append(oddBlocks, totalBlocks[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
|
||||||
retrieved, _, err := db.Blocks(ctx, filters.NewFilter().SetParentRoot(bytesutil.PadTo([]byte("parent"), 32)))
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, numBlocks, len(retrieved), "Unexpected number of blocks received")
|
|
||||||
// We delete all even indexed blocks.
|
|
||||||
require.NoError(t, db.deleteBlocks(ctx, blockRoots))
|
|
||||||
// When we retrieve the data, only the odd indexed blocks should remain.
|
|
||||||
retrieved, _, err = db.Blocks(ctx, filters.NewFilter().SetParentRoot(bytesutil.PadTo([]byte("parent"), 32)))
|
|
||||||
require.NoError(t, err)
|
|
||||||
sort.Slice(retrieved, func(i, j int) bool {
|
|
||||||
return retrieved[i].Block().Slot() < retrieved[j].Block().Slot()
|
|
||||||
})
|
|
||||||
for i, block := range retrieved {
|
|
||||||
assert.Equal(t, true, proto.Equal(block.Proto(), oddBlocks[i].Proto()), "Wanted: %v, received: %v", block, oddBlocks[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_BellatrixBlocksHandleZeroCase(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
numBlocks := 10
|
|
||||||
totalBlocks := make([]block.SignedBeaconBlock, numBlocks)
|
|
||||||
for i := 0; i < len(totalBlocks); i++ {
|
|
||||||
b := util.NewBeaconBlockMerge()
|
|
||||||
b.Block.Slot = types.Slot(i)
|
|
||||||
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
|
||||||
wb, err := wrapper.WrappedMergeSignedBeaconBlock(b)
|
|
||||||
require.NoError(t, err)
|
|
||||||
totalBlocks[i] = wb
|
|
||||||
_, err = totalBlocks[i].Block().HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
|
||||||
zeroFilter := filters.NewFilter().SetStartSlot(0).SetEndSlot(0)
|
|
||||||
retrieved, _, err := db.Blocks(ctx, zeroFilter)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 1, len(retrieved), "Unexpected number of blocks received, expected one")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_BellatrixBlocksHandleInvalidEndSlot(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
numBlocks := 10
|
|
||||||
totalBlocks := make([]block.SignedBeaconBlock, numBlocks)
|
|
||||||
// Save blocks from slot 1 onwards.
|
|
||||||
for i := 0; i < len(totalBlocks); i++ {
|
|
||||||
b := util.NewBeaconBlockMerge()
|
|
||||||
b.Block.Slot = types.Slot(i) + 1
|
|
||||||
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
|
||||||
wb, err := wrapper.WrappedMergeSignedBeaconBlock(b)
|
|
||||||
require.NoError(t, err)
|
|
||||||
totalBlocks[i] = wb
|
|
||||||
_, err = totalBlocks[i].Block().HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
|
||||||
badFilter := filters.NewFilter().SetStartSlot(5).SetEndSlot(1)
|
|
||||||
_, _, err := db.Blocks(ctx, badFilter)
|
|
||||||
require.ErrorContains(t, errInvalidSlotRange.Error(), err)
|
|
||||||
|
|
||||||
goodFilter := filters.NewFilter().SetStartSlot(0).SetEndSlot(1)
|
|
||||||
requested, _, err := db.Blocks(ctx, goodFilter)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 1, len(requested), "Unexpected number of blocks received, only expected two")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_BellatrixBlocksCRUD_NoCache(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
block := util.NewBeaconBlockMerge()
|
|
||||||
block.Block.Slot = 20
|
|
||||||
block.Block.ParentRoot = bytesutil.PadTo([]byte{1, 2, 3}, 32)
|
|
||||||
blockRoot, err := block.Block.HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
retrievedBlock, err := db.Block(ctx, blockRoot)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.DeepEqual(t, nil, retrievedBlock, "Expected nil block")
|
|
||||||
wsb, err := wrapper.WrappedMergeSignedBeaconBlock(block)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wsb))
|
|
||||||
db.blockCache.Del(string(blockRoot[:]))
|
|
||||||
assert.Equal(t, true, db.HasBlock(ctx, blockRoot), "Expected block to exist in the db")
|
|
||||||
retrievedBlock, err = db.Block(ctx, blockRoot)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, true, proto.Equal(block, retrievedBlock.Proto()), "Wanted: %v, received: %v", block, retrievedBlock)
|
|
||||||
require.NoError(t, db.deleteBlock(ctx, blockRoot))
|
|
||||||
assert.Equal(t, false, db.HasBlock(ctx, blockRoot), "Expected block to have been deleted from the db")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_BellatrixBlocks_FiltersCorrectly(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
b4 := util.NewBeaconBlockMerge()
|
|
||||||
b4.Block.Slot = 4
|
|
||||||
b4.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
|
||||||
b5 := util.NewBeaconBlockMerge()
|
|
||||||
b5.Block.Slot = 5
|
|
||||||
b5.Block.ParentRoot = bytesutil.PadTo([]byte("parent2"), 32)
|
|
||||||
b6 := util.NewBeaconBlockMerge()
|
|
||||||
b6.Block.Slot = 6
|
|
||||||
b6.Block.ParentRoot = bytesutil.PadTo([]byte("parent2"), 32)
|
|
||||||
b7 := util.NewBeaconBlockMerge()
|
|
||||||
b7.Block.Slot = 7
|
|
||||||
b7.Block.ParentRoot = bytesutil.PadTo([]byte("parent3"), 32)
|
|
||||||
b8 := util.NewBeaconBlockMerge()
|
|
||||||
b8.Block.Slot = 8
|
|
||||||
b8.Block.ParentRoot = bytesutil.PadTo([]byte("parent4"), 32)
|
|
||||||
blocks := make([]block.SignedBeaconBlock, 0)
|
|
||||||
for _, b := range []*v2.SignedBeaconBlockMerge{b4, b5, b6, b7, b8} {
|
|
||||||
blk, err := wrapper.WrappedMergeSignedBeaconBlock(b)
|
|
||||||
require.NoError(t, err)
|
|
||||||
blocks = append(blocks, blk)
|
|
||||||
}
|
|
||||||
ctx := context.Background()
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, blocks))
|
|
||||||
|
|
||||||
tests := []struct {
|
|
||||||
filter *filters.QueryFilter
|
|
||||||
expectedNumBlocks int
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
filter: filters.NewFilter().SetParentRoot(bytesutil.PadTo([]byte("parent2"), 32)),
|
|
||||||
expectedNumBlocks: 2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// No block meets the criteria below.
|
|
||||||
filter: filters.NewFilter().SetParentRoot(bytesutil.PadTo([]byte{3, 4, 5}, 32)),
|
|
||||||
expectedNumBlocks: 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// Block slot range filter criteria.
|
|
||||||
filter: filters.NewFilter().SetStartSlot(5).SetEndSlot(7),
|
|
||||||
expectedNumBlocks: 3,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filter: filters.NewFilter().SetStartSlot(7).SetEndSlot(7),
|
|
||||||
expectedNumBlocks: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filter: filters.NewFilter().SetStartSlot(4).SetEndSlot(8),
|
|
||||||
expectedNumBlocks: 5,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filter: filters.NewFilter().SetStartSlot(4).SetEndSlot(5),
|
|
||||||
expectedNumBlocks: 2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filter: filters.NewFilter().SetStartSlot(5).SetEndSlot(9),
|
|
||||||
expectedNumBlocks: 4,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filter: filters.NewFilter().SetEndSlot(7),
|
|
||||||
expectedNumBlocks: 4,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filter: filters.NewFilter().SetEndSlot(8),
|
|
||||||
expectedNumBlocks: 5,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filter: filters.NewFilter().SetStartSlot(5).SetEndSlot(10),
|
|
||||||
expectedNumBlocks: 4,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// Composite filter criteria.
|
|
||||||
filter: filters.NewFilter().
|
|
||||||
SetParentRoot(bytesutil.PadTo([]byte("parent2"), 32)).
|
|
||||||
SetStartSlot(6).
|
|
||||||
SetEndSlot(8),
|
|
||||||
expectedNumBlocks: 1,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
retrievedBlocks, _, err := db.Blocks(ctx, tt.filter)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, tt.expectedNumBlocks, len(retrievedBlocks), "Unexpected number of blocks")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_BellatrixBlocks_VerifyBlockRoots(t *testing.T) {
|
|
||||||
ctx := context.Background()
|
|
||||||
db := setupDB(t)
|
|
||||||
b1 := util.NewBeaconBlockMerge()
|
|
||||||
b1.Block.Slot = 1
|
|
||||||
r1, err := b1.Block.HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
b2 := util.NewBeaconBlockMerge()
|
|
||||||
b2.Block.Slot = 2
|
|
||||||
r2, err := b2.Block.HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
for _, b := range []*v2.SignedBeaconBlockMerge{b1, b2} {
|
|
||||||
wsb, err := wrapper.WrappedMergeSignedBeaconBlock(b)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wsb))
|
|
||||||
}
|
|
||||||
|
|
||||||
filter := filters.NewFilter().SetStartSlot(b1.Block.Slot).SetEndSlot(b2.Block.Slot)
|
|
||||||
roots, err := db.BlockRoots(ctx, filter)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
assert.DeepEqual(t, [][32]byte{r1, r2}, roots)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_BellatrixBlocks_Retrieve_SlotRange(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
totalBlocks := make([]block.SignedBeaconBlock, 500)
|
|
||||||
for i := 0; i < 500; i++ {
|
|
||||||
b := util.NewBeaconBlockMerge()
|
|
||||||
b.Block.Slot = types.Slot(i)
|
|
||||||
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
|
||||||
wb, err := wrapper.WrappedMergeSignedBeaconBlock(b)
|
|
||||||
require.NoError(t, err)
|
|
||||||
totalBlocks[i] = wb
|
|
||||||
}
|
|
||||||
ctx := context.Background()
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
|
||||||
retrieved, _, err := db.Blocks(ctx, filters.NewFilter().SetStartSlot(100).SetEndSlot(399))
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 300, len(retrieved))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_BellatrixBlocks_Retrieve_Epoch(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
slots := params.BeaconConfig().SlotsPerEpoch.Mul(7)
|
|
||||||
totalBlocks := make([]block.SignedBeaconBlock, slots)
|
|
||||||
for i := types.Slot(0); i < slots; i++ {
|
|
||||||
b := util.NewBeaconBlockMerge()
|
|
||||||
b.Block.Slot = i
|
|
||||||
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
|
||||||
wb, err := wrapper.WrappedMergeSignedBeaconBlock(b)
|
|
||||||
require.NoError(t, err)
|
|
||||||
totalBlocks[i] = wb
|
|
||||||
}
|
|
||||||
ctx := context.Background()
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
|
||||||
retrieved, _, err := db.Blocks(ctx, filters.NewFilter().SetStartEpoch(5).SetEndEpoch(6))
|
|
||||||
require.NoError(t, err)
|
|
||||||
want := params.BeaconConfig().SlotsPerEpoch.Mul(2)
|
|
||||||
assert.Equal(t, uint64(want), uint64(len(retrieved)))
|
|
||||||
retrieved, _, err = db.Blocks(ctx, filters.NewFilter().SetStartEpoch(0).SetEndEpoch(0))
|
|
||||||
require.NoError(t, err)
|
|
||||||
want = params.BeaconConfig().SlotsPerEpoch
|
|
||||||
assert.Equal(t, uint64(want), uint64(len(retrieved)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_BellatrixBlocks_Retrieve_SlotRangeWithStep(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
totalBlocks := make([]block.SignedBeaconBlock, 500)
|
|
||||||
for i := 0; i < 500; i++ {
|
|
||||||
b := util.NewBeaconBlockMerge()
|
|
||||||
b.Block.Slot = types.Slot(i)
|
|
||||||
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
|
||||||
wb, err := wrapper.WrappedMergeSignedBeaconBlock(b)
|
|
||||||
require.NoError(t, err)
|
|
||||||
totalBlocks[i] = wb
|
|
||||||
}
|
|
||||||
const step = 2
|
|
||||||
ctx := context.Background()
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
|
||||||
retrieved, _, err := db.Blocks(ctx, filters.NewFilter().SetStartSlot(100).SetEndSlot(399).SetSlotStep(step))
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 150, len(retrieved))
|
|
||||||
for _, b := range retrieved {
|
|
||||||
assert.Equal(t, types.Slot(0), (b.Block().Slot()-100)%step, "Unexpect block slot %d", b.Block().Slot())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_SaveBellatrixBlock_CanGetHighestAt(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
block1 := util.NewBeaconBlockMerge()
|
|
||||||
block1.Block.Slot = 1
|
|
||||||
block2 := util.NewBeaconBlockMerge()
|
|
||||||
block2.Block.Slot = 10
|
|
||||||
block3 := util.NewBeaconBlockMerge()
|
|
||||||
block3.Block.Slot = 100
|
|
||||||
|
|
||||||
for _, b := range []*v2.SignedBeaconBlockMerge{block1, block2, block3} {
|
|
||||||
wsb, err := wrapper.WrappedMergeSignedBeaconBlock(b)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wsb))
|
|
||||||
}
|
|
||||||
|
|
||||||
highestAt, err := db.HighestSlotBlocksBelow(ctx, 2)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, false, len(highestAt) <= 0, "Got empty highest at slice")
|
|
||||||
assert.Equal(t, true, proto.Equal(block1, highestAt[0].Proto()), "Wanted: %v, received: %v", block1, highestAt[0])
|
|
||||||
highestAt, err = db.HighestSlotBlocksBelow(ctx, 11)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, false, len(highestAt) <= 0, "Got empty highest at slice")
|
|
||||||
assert.Equal(t, true, proto.Equal(block2, highestAt[0].Proto()), "Wanted: %v, received: %v", block2, highestAt[0])
|
|
||||||
highestAt, err = db.HighestSlotBlocksBelow(ctx, 101)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, false, len(highestAt) <= 0, "Got empty highest at slice")
|
|
||||||
assert.Equal(t, true, proto.Equal(block3, highestAt[0].Proto()), "Wanted: %v, received: %v", block3, highestAt[0])
|
|
||||||
|
|
||||||
r3, err := block3.Block.HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.deleteBlock(ctx, r3))
|
|
||||||
|
|
||||||
highestAt, err = db.HighestSlotBlocksBelow(ctx, 101)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, true, proto.Equal(block2, highestAt[0].Proto()), "Wanted: %v, received: %v", block2, highestAt[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_GenesisBellatrixBlock_CanGetHighestAt(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
genesisBlock := util.NewBeaconBlockMerge()
|
|
||||||
genesisRoot, err := genesisBlock.Block.HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.SaveGenesisBlockRoot(ctx, genesisRoot))
|
|
||||||
wsb, err := wrapper.WrappedMergeSignedBeaconBlock(genesisBlock)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wsb))
|
|
||||||
block1 := util.NewBeaconBlockMerge()
|
|
||||||
block1.Block.Slot = 1
|
|
||||||
wsb, err = wrapper.WrappedMergeSignedBeaconBlock(block1)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wsb))
|
|
||||||
|
|
||||||
highestAt, err := db.HighestSlotBlocksBelow(ctx, 2)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, true, proto.Equal(block1, highestAt[0].Proto()), "Wanted: %v, received: %v", block1, highestAt[0])
|
|
||||||
highestAt, err = db.HighestSlotBlocksBelow(ctx, 1)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, true, proto.Equal(genesisBlock, highestAt[0].Proto()), "Wanted: %v, received: %v", genesisBlock, highestAt[0])
|
|
||||||
highestAt, err = db.HighestSlotBlocksBelow(ctx, 0)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, true, proto.Equal(genesisBlock, highestAt[0].Proto()), "Wanted: %v, received: %v", genesisBlock, highestAt[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_SaveBellatrixBlocks_HasCachedBlocks(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
var err error
|
|
||||||
b := make([]block.SignedBeaconBlock, 500)
|
|
||||||
for i := 0; i < 500; i++ {
|
|
||||||
blk := util.NewBeaconBlockMerge()
|
|
||||||
blk.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
|
||||||
blk.Block.Slot = types.Slot(i)
|
|
||||||
b[i], err = wrapper.WrappedMergeSignedBeaconBlock(blk)
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, b[0]))
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, b))
|
|
||||||
f := filters.NewFilter().SetStartSlot(0).SetEndSlot(500)
|
|
||||||
|
|
||||||
blks, _, err := db.Blocks(ctx, f)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 500, len(blks), "Did not get wanted blocks")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_SaveBellatrixBlocks_HasRootsMatched(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
var err error
|
|
||||||
b := make([]block.SignedBeaconBlock, 500)
|
|
||||||
for i := 0; i < 500; i++ {
|
|
||||||
blk := util.NewBeaconBlockMerge()
|
|
||||||
blk.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
|
||||||
blk.Block.Slot = types.Slot(i)
|
|
||||||
b[i], err = wrapper.WrappedMergeSignedBeaconBlock(blk)
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, b))
|
|
||||||
f := filters.NewFilter().SetStartSlot(0).SetEndSlot(500)
|
|
||||||
|
|
||||||
blks, roots, err := db.Blocks(ctx, f)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 500, len(blks), "Did not get wanted blocks")
|
|
||||||
|
|
||||||
for i, blk := range blks {
|
|
||||||
rt, err := blk.Block().HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, roots[i], rt, "mismatch of block roots")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_BellatrixBlocksBySlot_BlockRootsBySlot(t *testing.T) {
|
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
b1 := util.NewBeaconBlockMerge()
|
|
||||||
b1.Block.Slot = 20
|
|
||||||
b2 := util.NewBeaconBlockMerge()
|
|
||||||
b2.Block.Slot = 100
|
|
||||||
b2.Block.ParentRoot = bytesutil.PadTo([]byte("parent1"), 32)
|
|
||||||
b3 := util.NewBeaconBlockMerge()
|
|
||||||
b3.Block.Slot = 100
|
|
||||||
b3.Block.ParentRoot = bytesutil.PadTo([]byte("parent2"), 32)
|
|
||||||
|
|
||||||
for _, b := range []*v2.SignedBeaconBlockMerge{b1, b2, b3} {
|
|
||||||
wsb, err := wrapper.WrappedMergeSignedBeaconBlock(b)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wsb))
|
|
||||||
}
|
|
||||||
|
|
||||||
r1, err := b1.Block.HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
r2, err := b2.Block.HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
r3, err := b3.Block.HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
hasBlocks, retrievedBlocks, err := db.BlocksBySlot(ctx, 1)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 0, len(retrievedBlocks), "Unexpected number of blocks received, expected none")
|
|
||||||
assert.Equal(t, false, hasBlocks, "Expected no blocks")
|
|
||||||
hasBlocks, retrievedBlocks, err = db.BlocksBySlot(ctx, 20)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, true, proto.Equal(b1, retrievedBlocks[0].Proto()), "Wanted: %v, received: %v", b1, retrievedBlocks[0])
|
|
||||||
assert.Equal(t, true, hasBlocks, "Expected to have blocks")
|
|
||||||
hasBlocks, retrievedBlocks, err = db.BlocksBySlot(ctx, 100)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, true, proto.Equal(b2, retrievedBlocks[0].Proto()), "Wanted: %v, received: %v", b2, retrievedBlocks[0])
|
|
||||||
assert.Equal(t, true, proto.Equal(b3, retrievedBlocks[1].Proto()), "Wanted: %v, received: %v", b3, retrievedBlocks[1])
|
|
||||||
assert.Equal(t, true, hasBlocks, "Expected to have blocks")
|
|
||||||
|
|
||||||
hasBlockRoots, retrievedBlockRoots, err := db.BlockRootsBySlot(ctx, 1)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.DeepEqual(t, [][32]byte{}, retrievedBlockRoots)
|
|
||||||
assert.Equal(t, false, hasBlockRoots, "Expected no block roots")
|
|
||||||
hasBlockRoots, retrievedBlockRoots, err = db.BlockRootsBySlot(ctx, 20)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.DeepEqual(t, [][32]byte{r1}, retrievedBlockRoots)
|
|
||||||
assert.Equal(t, true, hasBlockRoots, "Expected no block roots")
|
|
||||||
hasBlockRoots, retrievedBlockRoots, err = db.BlockRootsBySlot(ctx, 100)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.DeepEqual(t, [][32]byte{r2, r3}, retrievedBlockRoots)
|
|
||||||
assert.Equal(t, true, hasBlockRoots, "Expected no block roots")
|
|
||||||
}
|
|
||||||
@@ -17,135 +17,193 @@ import (
|
|||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var blockTests = []struct {
|
||||||
|
name string
|
||||||
|
newBlock func(types.Slot, []byte) (block.SignedBeaconBlock, error)
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "phase0",
|
||||||
|
newBlock: func(slot types.Slot, root []byte) (block.SignedBeaconBlock, error) {
|
||||||
|
b := util.NewBeaconBlock()
|
||||||
|
b.Block.Slot = slot
|
||||||
|
if root != nil {
|
||||||
|
b.Block.ParentRoot = root
|
||||||
|
}
|
||||||
|
return wrapper.WrappedPhase0SignedBeaconBlock(b), nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "altair",
|
||||||
|
newBlock: func(slot types.Slot, root []byte) (block.SignedBeaconBlock, error) {
|
||||||
|
b := util.NewBeaconBlockAltair()
|
||||||
|
b.Block.Slot = slot
|
||||||
|
if root != nil {
|
||||||
|
b.Block.ParentRoot = root
|
||||||
|
}
|
||||||
|
return wrapper.WrappedAltairSignedBeaconBlock(b)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "bellatrix",
|
||||||
|
newBlock: func(slot types.Slot, root []byte) (block.SignedBeaconBlock, error) {
|
||||||
|
b := util.NewBeaconBlockMerge()
|
||||||
|
b.Block.Slot = slot
|
||||||
|
if root != nil {
|
||||||
|
b.Block.ParentRoot = root
|
||||||
|
}
|
||||||
|
return wrapper.WrappedMergeSignedBeaconBlock(b)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
func TestStore_SaveBlock_NoDuplicates(t *testing.T) {
|
func TestStore_SaveBlock_NoDuplicates(t *testing.T) {
|
||||||
BlockCacheSize = 1
|
BlockCacheSize = 1
|
||||||
db := setupDB(t)
|
|
||||||
slot := types.Slot(20)
|
slot := types.Slot(20)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
// First we save a previous block to ensure the cache max size is reached.
|
|
||||||
prevBlock := util.NewBeaconBlock()
|
|
||||||
prevBlock.Block.Slot = slot - 1
|
|
||||||
prevBlock.Block.ParentRoot = bytesutil.PadTo([]byte{1, 2, 3}, 32)
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(prevBlock)))
|
|
||||||
|
|
||||||
block := util.NewBeaconBlock()
|
for _, tt := range blockTests {
|
||||||
block.Block.Slot = slot
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
block.Block.ParentRoot = bytesutil.PadTo([]byte{1, 2, 3}, 32)
|
db := setupDB(t)
|
||||||
// Even with a full cache, saving new blocks should not cause
|
|
||||||
// duplicated blocks in the DB.
|
// First we save a previous block to ensure the cache max size is reached.
|
||||||
for i := 0; i < 100; i++ {
|
prevBlock, err := tt.newBlock(slot-1, bytesutil.PadTo([]byte{1, 2, 3}, 32))
|
||||||
require.NoError(t, db.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(block)))
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, db.SaveBlock(ctx, prevBlock))
|
||||||
|
|
||||||
|
blk, err := tt.newBlock(slot, bytesutil.PadTo([]byte{1, 2, 3}, 32))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Even with a full cache, saving new blocks should not cause
|
||||||
|
// duplicated blocks in the DB.
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
require.NoError(t, db.SaveBlock(ctx, blk))
|
||||||
|
}
|
||||||
|
|
||||||
|
f := filters.NewFilter().SetStartSlot(slot).SetEndSlot(slot)
|
||||||
|
retrieved, _, err := db.Blocks(ctx, f)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, 1, len(retrieved))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
f := filters.NewFilter().SetStartSlot(slot).SetEndSlot(slot)
|
|
||||||
retrieved, _, err := db.Blocks(ctx, f)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 1, len(retrieved))
|
|
||||||
// We reset the block cache size.
|
// We reset the block cache size.
|
||||||
BlockCacheSize = 256
|
BlockCacheSize = 256
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStore_BlocksCRUD(t *testing.T) {
|
func TestStore_BlocksCRUD(t *testing.T) {
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
block := util.NewBeaconBlock()
|
for _, tt := range blockTests {
|
||||||
block.Block.Slot = 20
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
block.Block.ParentRoot = bytesutil.PadTo([]byte{1, 2, 3}, 32)
|
db := setupDB(t)
|
||||||
|
|
||||||
blockRoot, err := block.Block.HashTreeRoot()
|
blk, err := tt.newBlock(types.Slot(20), bytesutil.PadTo([]byte{1, 2, 3}, 32))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
retrievedBlock, err := db.Block(ctx, blockRoot)
|
blockRoot, err := blk.Block().HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.DeepEqual(t, nil, retrievedBlock, "Expected nil block")
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(block)))
|
retrievedBlock, err := db.Block(ctx, blockRoot)
|
||||||
assert.Equal(t, true, db.HasBlock(ctx, blockRoot), "Expected block to exist in the db")
|
require.NoError(t, err)
|
||||||
retrievedBlock, err = db.Block(ctx, blockRoot)
|
assert.DeepEqual(t, nil, retrievedBlock, "Expected nil block")
|
||||||
require.NoError(t, err)
|
require.NoError(t, db.SaveBlock(ctx, blk))
|
||||||
assert.Equal(t, true, proto.Equal(block, retrievedBlock.Proto()), "Wanted: %v, received: %v", block, retrievedBlock)
|
assert.Equal(t, true, db.HasBlock(ctx, blockRoot), "Expected block to exist in the db")
|
||||||
require.NoError(t, db.deleteBlock(ctx, blockRoot))
|
retrievedBlock, err = db.Block(ctx, blockRoot)
|
||||||
assert.Equal(t, false, db.HasBlock(ctx, blockRoot), "Expected block to have been deleted from the db")
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, true, proto.Equal(blk.Proto(), retrievedBlock.Proto()), "Wanted: %v, received: %v", blk, retrievedBlock)
|
||||||
|
require.NoError(t, db.deleteBlock(ctx, blockRoot))
|
||||||
|
assert.Equal(t, false, db.HasBlock(ctx, blockRoot), "Expected block to have been deleted from the db")
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStore_BlocksBatchDelete(t *testing.T) {
|
func TestStore_BlocksBatchDelete(t *testing.T) {
|
||||||
db := setupDB(t)
|
for _, tt := range blockTests {
|
||||||
ctx := context.Background()
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
numBlocks := 10
|
db := setupDB(t)
|
||||||
totalBlocks := make([]block.SignedBeaconBlock, numBlocks)
|
ctx := context.Background()
|
||||||
blockRoots := make([][32]byte, 0)
|
numBlocks := 10
|
||||||
oddBlocks := make([]block.SignedBeaconBlock, 0)
|
totalBlocks := make([]block.SignedBeaconBlock, numBlocks)
|
||||||
for i := 0; i < len(totalBlocks); i++ {
|
blockRoots := make([][32]byte, 0)
|
||||||
b := util.NewBeaconBlock()
|
oddBlocks := make([]block.SignedBeaconBlock, 0)
|
||||||
b.Block.Slot = types.Slot(i)
|
for i := 0; i < len(totalBlocks); i++ {
|
||||||
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
b, err := tt.newBlock(types.Slot(i), bytesutil.PadTo([]byte("parent"), 32))
|
||||||
totalBlocks[i] = wrapper.WrappedPhase0SignedBeaconBlock(b)
|
require.NoError(t, err)
|
||||||
if i%2 == 0 {
|
totalBlocks[i] = b
|
||||||
r, err := totalBlocks[i].Block().HashTreeRoot()
|
if i%2 == 0 {
|
||||||
|
r, err := totalBlocks[i].Block().HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
blockRoots = append(blockRoots, r)
|
||||||
|
} else {
|
||||||
|
oddBlocks = append(oddBlocks, totalBlocks[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
||||||
|
retrieved, _, err := db.Blocks(ctx, filters.NewFilter().SetParentRoot(bytesutil.PadTo([]byte("parent"), 32)))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
blockRoots = append(blockRoots, r)
|
assert.Equal(t, numBlocks, len(retrieved), "Unexpected number of blocks received")
|
||||||
} else {
|
// We delete all even indexed blocks.
|
||||||
oddBlocks = append(oddBlocks, totalBlocks[i])
|
require.NoError(t, db.deleteBlocks(ctx, blockRoots))
|
||||||
}
|
// When we retrieve the data, only the odd indexed blocks should remain.
|
||||||
}
|
retrieved, _, err = db.Blocks(ctx, filters.NewFilter().SetParentRoot(bytesutil.PadTo([]byte("parent"), 32)))
|
||||||
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
require.NoError(t, err)
|
||||||
retrieved, _, err := db.Blocks(ctx, filters.NewFilter().SetParentRoot(bytesutil.PadTo([]byte("parent"), 32)))
|
sort.Slice(retrieved, func(i, j int) bool {
|
||||||
require.NoError(t, err)
|
return retrieved[i].Block().Slot() < retrieved[j].Block().Slot()
|
||||||
assert.Equal(t, numBlocks, len(retrieved), "Unexpected number of blocks received")
|
})
|
||||||
// We delete all even indexed blocks.
|
for i, blk := range retrieved {
|
||||||
require.NoError(t, db.deleteBlocks(ctx, blockRoots))
|
assert.Equal(t, true, proto.Equal(blk.Proto(), oddBlocks[i].Proto()), "Wanted: %v, received: %v", blk, oddBlocks[i])
|
||||||
// When we retrieve the data, only the odd indexed blocks should remain.
|
}
|
||||||
retrieved, _, err = db.Blocks(ctx, filters.NewFilter().SetParentRoot(bytesutil.PadTo([]byte("parent"), 32)))
|
})
|
||||||
require.NoError(t, err)
|
|
||||||
sort.Slice(retrieved, func(i, j int) bool {
|
|
||||||
return retrieved[i].Block().Slot() < retrieved[j].Block().Slot()
|
|
||||||
})
|
|
||||||
for i, block := range retrieved {
|
|
||||||
assert.Equal(t, true, proto.Equal(block.Proto(), oddBlocks[i].Proto()), "Wanted: %v, received: %v", block, oddBlocks[i])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStore_BlocksHandleZeroCase(t *testing.T) {
|
func TestStore_BlocksHandleZeroCase(t *testing.T) {
|
||||||
db := setupDB(t)
|
for _, tt := range blockTests {
|
||||||
ctx := context.Background()
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
numBlocks := 10
|
db := setupDB(t)
|
||||||
totalBlocks := make([]block.SignedBeaconBlock, numBlocks)
|
ctx := context.Background()
|
||||||
for i := 0; i < len(totalBlocks); i++ {
|
numBlocks := 10
|
||||||
b := util.NewBeaconBlock()
|
totalBlocks := make([]block.SignedBeaconBlock, numBlocks)
|
||||||
b.Block.Slot = types.Slot(i)
|
for i := 0; i < len(totalBlocks); i++ {
|
||||||
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
b, err := tt.newBlock(types.Slot(i), bytesutil.PadTo([]byte("parent"), 32))
|
||||||
totalBlocks[i] = wrapper.WrappedPhase0SignedBeaconBlock(b)
|
require.NoError(t, err)
|
||||||
_, err := totalBlocks[i].Block().HashTreeRoot()
|
totalBlocks[i] = b
|
||||||
require.NoError(t, err)
|
_, err = totalBlocks[i].Block().HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
||||||
|
zeroFilter := filters.NewFilter().SetStartSlot(0).SetEndSlot(0)
|
||||||
|
retrieved, _, err := db.Blocks(ctx, zeroFilter)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, 1, len(retrieved), "Unexpected number of blocks received, expected one")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
|
||||||
zeroFilter := filters.NewFilter().SetStartSlot(0).SetEndSlot(0)
|
|
||||||
retrieved, _, err := db.Blocks(ctx, zeroFilter)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 1, len(retrieved), "Unexpected number of blocks received, expected one")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStore_BlocksHandleInvalidEndSlot(t *testing.T) {
|
func TestStore_BlocksHandleInvalidEndSlot(t *testing.T) {
|
||||||
db := setupDB(t)
|
for _, tt := range blockTests {
|
||||||
ctx := context.Background()
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
numBlocks := 10
|
db := setupDB(t)
|
||||||
totalBlocks := make([]block.SignedBeaconBlock, numBlocks)
|
ctx := context.Background()
|
||||||
// Save blocks from slot 1 onwards.
|
numBlocks := 10
|
||||||
for i := 0; i < len(totalBlocks); i++ {
|
totalBlocks := make([]block.SignedBeaconBlock, numBlocks)
|
||||||
b := util.NewBeaconBlock()
|
// Save blocks from slot 1 onwards.
|
||||||
b.Block.Slot = types.Slot(i) + 1
|
for i := 0; i < len(totalBlocks); i++ {
|
||||||
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
b, err := tt.newBlock(types.Slot(i+1), bytesutil.PadTo([]byte("parent"), 32))
|
||||||
totalBlocks[i] = wrapper.WrappedPhase0SignedBeaconBlock(b)
|
require.NoError(t, err)
|
||||||
_, err := totalBlocks[i].Block().HashTreeRoot()
|
totalBlocks[i] = b
|
||||||
require.NoError(t, err)
|
_, err = totalBlocks[i].Block().HashTreeRoot()
|
||||||
}
|
require.NoError(t, err)
|
||||||
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
}
|
||||||
badFilter := filters.NewFilter().SetStartSlot(5).SetEndSlot(1)
|
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
||||||
_, _, err := db.Blocks(ctx, badFilter)
|
badFilter := filters.NewFilter().SetStartSlot(5).SetEndSlot(1)
|
||||||
require.ErrorContains(t, errInvalidSlotRange.Error(), err)
|
_, _, err := db.Blocks(ctx, badFilter)
|
||||||
|
require.ErrorContains(t, errInvalidSlotRange.Error(), err)
|
||||||
|
|
||||||
goodFilter := filters.NewFilter().SetStartSlot(0).SetEndSlot(1)
|
goodFilter := filters.NewFilter().SetStartSlot(0).SetEndSlot(1)
|
||||||
requested, _, err := db.Blocks(ctx, goodFilter)
|
requested, _, err := db.Blocks(ctx, goodFilter)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, 1, len(requested), "Unexpected number of blocks received, only expected two")
|
assert.Equal(t, 1, len(requested), "Unexpected number of blocks received, only expected two")
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStore_GenesisBlock(t *testing.T) {
|
func TestStore_GenesisBlock(t *testing.T) {
|
||||||
@@ -163,349 +221,385 @@ func TestStore_GenesisBlock(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStore_BlocksCRUD_NoCache(t *testing.T) {
|
func TestStore_BlocksCRUD_NoCache(t *testing.T) {
|
||||||
db := setupDB(t)
|
for _, tt := range blockTests {
|
||||||
ctx := context.Background()
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
block := util.NewBeaconBlock()
|
db := setupDB(t)
|
||||||
block.Block.Slot = 20
|
ctx := context.Background()
|
||||||
block.Block.ParentRoot = bytesutil.PadTo([]byte{1, 2, 3}, 32)
|
blk, err := tt.newBlock(types.Slot(20), bytesutil.PadTo([]byte{1, 2, 3}, 32))
|
||||||
blockRoot, err := block.Block.HashTreeRoot()
|
require.NoError(t, err)
|
||||||
require.NoError(t, err)
|
blockRoot, err := blk.Block().HashTreeRoot()
|
||||||
retrievedBlock, err := db.Block(ctx, blockRoot)
|
require.NoError(t, err)
|
||||||
require.NoError(t, err)
|
retrievedBlock, err := db.Block(ctx, blockRoot)
|
||||||
require.DeepEqual(t, nil, retrievedBlock, "Expected nil block")
|
require.NoError(t, err)
|
||||||
require.NoError(t, db.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(block)))
|
require.DeepEqual(t, nil, retrievedBlock, "Expected nil block")
|
||||||
db.blockCache.Del(string(blockRoot[:]))
|
require.NoError(t, db.SaveBlock(ctx, blk))
|
||||||
assert.Equal(t, true, db.HasBlock(ctx, blockRoot), "Expected block to exist in the db")
|
db.blockCache.Del(string(blockRoot[:]))
|
||||||
retrievedBlock, err = db.Block(ctx, blockRoot)
|
assert.Equal(t, true, db.HasBlock(ctx, blockRoot), "Expected block to exist in the db")
|
||||||
require.NoError(t, err)
|
retrievedBlock, err = db.Block(ctx, blockRoot)
|
||||||
assert.Equal(t, true, proto.Equal(block, retrievedBlock.Proto()), "Wanted: %v, received: %v", block, retrievedBlock)
|
require.NoError(t, err)
|
||||||
require.NoError(t, db.deleteBlock(ctx, blockRoot))
|
assert.Equal(t, true, proto.Equal(blk.Proto(), retrievedBlock.Proto()), "Wanted: %v, received: %v", blk, retrievedBlock)
|
||||||
assert.Equal(t, false, db.HasBlock(ctx, blockRoot), "Expected block to have been deleted from the db")
|
require.NoError(t, db.deleteBlock(ctx, blockRoot))
|
||||||
|
assert.Equal(t, false, db.HasBlock(ctx, blockRoot), "Expected block to have been deleted from the db")
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStore_Blocks_FiltersCorrectly(t *testing.T) {
|
func TestStore_Blocks_FiltersCorrectly(t *testing.T) {
|
||||||
db := setupDB(t)
|
for _, tt := range blockTests {
|
||||||
b4 := util.NewBeaconBlock()
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
b4.Block.Slot = 4
|
db := setupDB(t)
|
||||||
b4.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
b4, err := tt.newBlock(types.Slot(4), bytesutil.PadTo([]byte("parent"), 32))
|
||||||
b5 := util.NewBeaconBlock()
|
require.NoError(t, err)
|
||||||
b5.Block.Slot = 5
|
b5, err := tt.newBlock(types.Slot(5), bytesutil.PadTo([]byte("parent2"), 32))
|
||||||
b5.Block.ParentRoot = bytesutil.PadTo([]byte("parent2"), 32)
|
require.NoError(t, err)
|
||||||
b6 := util.NewBeaconBlock()
|
b6, err := tt.newBlock(types.Slot(6), bytesutil.PadTo([]byte("parent2"), 32))
|
||||||
b6.Block.Slot = 6
|
require.NoError(t, err)
|
||||||
b6.Block.ParentRoot = bytesutil.PadTo([]byte("parent2"), 32)
|
b7, err := tt.newBlock(types.Slot(7), bytesutil.PadTo([]byte("parent3"), 32))
|
||||||
b7 := util.NewBeaconBlock()
|
require.NoError(t, err)
|
||||||
b7.Block.Slot = 7
|
b8, err := tt.newBlock(types.Slot(8), bytesutil.PadTo([]byte("parent4"), 32))
|
||||||
b7.Block.ParentRoot = bytesutil.PadTo([]byte("parent3"), 32)
|
require.NoError(t, err)
|
||||||
b8 := util.NewBeaconBlock()
|
blocks := []block.SignedBeaconBlock{
|
||||||
b8.Block.Slot = 8
|
b4,
|
||||||
b8.Block.ParentRoot = bytesutil.PadTo([]byte("parent4"), 32)
|
b5,
|
||||||
blocks := []block.SignedBeaconBlock{
|
b6,
|
||||||
wrapper.WrappedPhase0SignedBeaconBlock(b4),
|
b7,
|
||||||
wrapper.WrappedPhase0SignedBeaconBlock(b5),
|
b8,
|
||||||
wrapper.WrappedPhase0SignedBeaconBlock(b6),
|
}
|
||||||
wrapper.WrappedPhase0SignedBeaconBlock(b7),
|
ctx := context.Background()
|
||||||
wrapper.WrappedPhase0SignedBeaconBlock(b8),
|
require.NoError(t, db.SaveBlocks(ctx, blocks))
|
||||||
}
|
|
||||||
ctx := context.Background()
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, blocks))
|
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
filter *filters.QueryFilter
|
filter *filters.QueryFilter
|
||||||
expectedNumBlocks int
|
expectedNumBlocks int
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
filter: filters.NewFilter().SetParentRoot(bytesutil.PadTo([]byte("parent2"), 32)),
|
filter: filters.NewFilter().SetParentRoot(bytesutil.PadTo([]byte("parent2"), 32)),
|
||||||
expectedNumBlocks: 2,
|
expectedNumBlocks: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// No block meets the criteria below.
|
// No block meets the criteria below.
|
||||||
filter: filters.NewFilter().SetParentRoot(bytesutil.PadTo([]byte{3, 4, 5}, 32)),
|
filter: filters.NewFilter().SetParentRoot(bytesutil.PadTo([]byte{3, 4, 5}, 32)),
|
||||||
expectedNumBlocks: 0,
|
expectedNumBlocks: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Block slot range filter criteria.
|
// Block slot range filter criteria.
|
||||||
filter: filters.NewFilter().SetStartSlot(5).SetEndSlot(7),
|
filter: filters.NewFilter().SetStartSlot(5).SetEndSlot(7),
|
||||||
expectedNumBlocks: 3,
|
expectedNumBlocks: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filter: filters.NewFilter().SetStartSlot(7).SetEndSlot(7),
|
filter: filters.NewFilter().SetStartSlot(7).SetEndSlot(7),
|
||||||
expectedNumBlocks: 1,
|
expectedNumBlocks: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filter: filters.NewFilter().SetStartSlot(4).SetEndSlot(8),
|
filter: filters.NewFilter().SetStartSlot(4).SetEndSlot(8),
|
||||||
expectedNumBlocks: 5,
|
expectedNumBlocks: 5,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filter: filters.NewFilter().SetStartSlot(4).SetEndSlot(5),
|
filter: filters.NewFilter().SetStartSlot(4).SetEndSlot(5),
|
||||||
expectedNumBlocks: 2,
|
expectedNumBlocks: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filter: filters.NewFilter().SetStartSlot(5).SetEndSlot(9),
|
filter: filters.NewFilter().SetStartSlot(5).SetEndSlot(9),
|
||||||
expectedNumBlocks: 4,
|
expectedNumBlocks: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filter: filters.NewFilter().SetEndSlot(7),
|
filter: filters.NewFilter().SetEndSlot(7),
|
||||||
expectedNumBlocks: 4,
|
expectedNumBlocks: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filter: filters.NewFilter().SetEndSlot(8),
|
filter: filters.NewFilter().SetEndSlot(8),
|
||||||
expectedNumBlocks: 5,
|
expectedNumBlocks: 5,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
filter: filters.NewFilter().SetStartSlot(5).SetEndSlot(10),
|
filter: filters.NewFilter().SetStartSlot(5).SetEndSlot(10),
|
||||||
expectedNumBlocks: 4,
|
expectedNumBlocks: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Composite filter criteria.
|
// Composite filter criteria.
|
||||||
filter: filters.NewFilter().
|
filter: filters.NewFilter().
|
||||||
SetParentRoot(bytesutil.PadTo([]byte("parent2"), 32)).
|
SetParentRoot(bytesutil.PadTo([]byte("parent2"), 32)).
|
||||||
SetStartSlot(6).
|
SetStartSlot(6).
|
||||||
SetEndSlot(8),
|
SetEndSlot(8),
|
||||||
expectedNumBlocks: 1,
|
expectedNumBlocks: 1,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt2 := range tests {
|
||||||
retrievedBlocks, _, err := db.Blocks(ctx, tt.filter)
|
retrievedBlocks, _, err := db.Blocks(ctx, tt2.filter)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, tt.expectedNumBlocks, len(retrievedBlocks), "Unexpected number of blocks")
|
assert.Equal(t, tt2.expectedNumBlocks, len(retrievedBlocks), "Unexpected number of blocks")
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStore_Blocks_VerifyBlockRoots(t *testing.T) {
|
func TestStore_Blocks_VerifyBlockRoots(t *testing.T) {
|
||||||
ctx := context.Background()
|
for _, tt := range blockTests {
|
||||||
db := setupDB(t)
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
b1 := util.NewBeaconBlock()
|
ctx := context.Background()
|
||||||
b1.Block.Slot = 1
|
db := setupDB(t)
|
||||||
r1, err := b1.Block.HashTreeRoot()
|
b1, err := tt.newBlock(types.Slot(1), nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
b2 := util.NewBeaconBlock()
|
r1, err := b1.Block().HashTreeRoot()
|
||||||
b2.Block.Slot = 2
|
require.NoError(t, err)
|
||||||
r2, err := b2.Block.HashTreeRoot()
|
b2, err := tt.newBlock(types.Slot(2), nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
r2, err := b2.Block().HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b1)))
|
require.NoError(t, db.SaveBlock(ctx, b1))
|
||||||
require.NoError(t, db.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b2)))
|
require.NoError(t, db.SaveBlock(ctx, b2))
|
||||||
|
|
||||||
filter := filters.NewFilter().SetStartSlot(b1.Block.Slot).SetEndSlot(b2.Block.Slot)
|
filter := filters.NewFilter().SetStartSlot(b1.Block().Slot()).SetEndSlot(b2.Block().Slot())
|
||||||
roots, err := db.BlockRoots(ctx, filter)
|
roots, err := db.BlockRoots(ctx, filter)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.DeepEqual(t, [][32]byte{r1, r2}, roots)
|
assert.DeepEqual(t, [][32]byte{r1, r2}, roots)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStore_Blocks_Retrieve_SlotRange(t *testing.T) {
|
func TestStore_Blocks_Retrieve_SlotRange(t *testing.T) {
|
||||||
db := setupDB(t)
|
for _, tt := range blockTests {
|
||||||
totalBlocks := make([]block.SignedBeaconBlock, 500)
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
for i := 0; i < 500; i++ {
|
db := setupDB(t)
|
||||||
b := util.NewBeaconBlock()
|
totalBlocks := make([]block.SignedBeaconBlock, 500)
|
||||||
b.Block.Slot = types.Slot(i)
|
for i := 0; i < 500; i++ {
|
||||||
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
b, err := tt.newBlock(types.Slot(i), bytesutil.PadTo([]byte("parent"), 32))
|
||||||
totalBlocks[i] = wrapper.WrappedPhase0SignedBeaconBlock(b)
|
require.NoError(t, err)
|
||||||
|
totalBlocks[i] = b
|
||||||
|
}
|
||||||
|
ctx := context.Background()
|
||||||
|
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
||||||
|
retrieved, _, err := db.Blocks(ctx, filters.NewFilter().SetStartSlot(100).SetEndSlot(399))
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, 300, len(retrieved))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
ctx := context.Background()
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
|
||||||
retrieved, _, err := db.Blocks(ctx, filters.NewFilter().SetStartSlot(100).SetEndSlot(399))
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 300, len(retrieved))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStore_Blocks_Retrieve_Epoch(t *testing.T) {
|
func TestStore_Blocks_Retrieve_Epoch(t *testing.T) {
|
||||||
db := setupDB(t)
|
for _, tt := range blockTests {
|
||||||
slots := params.BeaconConfig().SlotsPerEpoch.Mul(7)
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
totalBlocks := make([]block.SignedBeaconBlock, slots)
|
db := setupDB(t)
|
||||||
for i := types.Slot(0); i < slots; i++ {
|
slots := params.BeaconConfig().SlotsPerEpoch.Mul(7)
|
||||||
b := util.NewBeaconBlock()
|
totalBlocks := make([]block.SignedBeaconBlock, slots)
|
||||||
b.Block.Slot = i
|
for i := types.Slot(0); i < slots; i++ {
|
||||||
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
b, err := tt.newBlock(i, bytesutil.PadTo([]byte("parent"), 32))
|
||||||
totalBlocks[i] = wrapper.WrappedPhase0SignedBeaconBlock(b)
|
require.NoError(t, err)
|
||||||
|
totalBlocks[i] = b
|
||||||
|
}
|
||||||
|
ctx := context.Background()
|
||||||
|
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
||||||
|
retrieved, _, err := db.Blocks(ctx, filters.NewFilter().SetStartEpoch(5).SetEndEpoch(6))
|
||||||
|
require.NoError(t, err)
|
||||||
|
want := params.BeaconConfig().SlotsPerEpoch.Mul(2)
|
||||||
|
assert.Equal(t, uint64(want), uint64(len(retrieved)))
|
||||||
|
retrieved, _, err = db.Blocks(ctx, filters.NewFilter().SetStartEpoch(0).SetEndEpoch(0))
|
||||||
|
require.NoError(t, err)
|
||||||
|
want = params.BeaconConfig().SlotsPerEpoch
|
||||||
|
assert.Equal(t, uint64(want), uint64(len(retrieved)))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
ctx := context.Background()
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
|
||||||
retrieved, _, err := db.Blocks(ctx, filters.NewFilter().SetStartEpoch(5).SetEndEpoch(6))
|
|
||||||
require.NoError(t, err)
|
|
||||||
want := params.BeaconConfig().SlotsPerEpoch.Mul(2)
|
|
||||||
assert.Equal(t, uint64(want), uint64(len(retrieved)))
|
|
||||||
retrieved, _, err = db.Blocks(ctx, filters.NewFilter().SetStartEpoch(0).SetEndEpoch(0))
|
|
||||||
require.NoError(t, err)
|
|
||||||
want = params.BeaconConfig().SlotsPerEpoch
|
|
||||||
assert.Equal(t, uint64(want), uint64(len(retrieved)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStore_Blocks_Retrieve_SlotRangeWithStep(t *testing.T) {
|
func TestStore_Blocks_Retrieve_SlotRangeWithStep(t *testing.T) {
|
||||||
db := setupDB(t)
|
for _, tt := range blockTests {
|
||||||
totalBlocks := make([]block.SignedBeaconBlock, 500)
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
for i := 0; i < 500; i++ {
|
db := setupDB(t)
|
||||||
b := util.NewBeaconBlock()
|
totalBlocks := make([]block.SignedBeaconBlock, 500)
|
||||||
b.Block.Slot = types.Slot(i)
|
for i := 0; i < 500; i++ {
|
||||||
b.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
b, err := tt.newBlock(types.Slot(i), bytesutil.PadTo([]byte("parent"), 32))
|
||||||
totalBlocks[i] = wrapper.WrappedPhase0SignedBeaconBlock(b)
|
require.NoError(t, err)
|
||||||
}
|
totalBlocks[i] = b
|
||||||
const step = 2
|
}
|
||||||
ctx := context.Background()
|
const step = 2
|
||||||
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
ctx := context.Background()
|
||||||
retrieved, _, err := db.Blocks(ctx, filters.NewFilter().SetStartSlot(100).SetEndSlot(399).SetSlotStep(step))
|
require.NoError(t, db.SaveBlocks(ctx, totalBlocks))
|
||||||
require.NoError(t, err)
|
retrieved, _, err := db.Blocks(ctx, filters.NewFilter().SetStartSlot(100).SetEndSlot(399).SetSlotStep(step))
|
||||||
assert.Equal(t, 150, len(retrieved))
|
require.NoError(t, err)
|
||||||
for _, b := range retrieved {
|
assert.Equal(t, 150, len(retrieved))
|
||||||
assert.Equal(t, types.Slot(0), (b.Block().Slot()-100)%step, "Unexpect block slot %d", b.Block().Slot())
|
for _, b := range retrieved {
|
||||||
|
assert.Equal(t, types.Slot(0), (b.Block().Slot()-100)%step, "Unexpect block slot %d", b.Block().Slot())
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStore_SaveBlock_CanGetHighestAt(t *testing.T) {
|
func TestStore_SaveBlock_CanGetHighestAt(t *testing.T) {
|
||||||
db := setupDB(t)
|
for _, tt := range blockTests {
|
||||||
ctx := context.Background()
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
db := setupDB(t)
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
block1 := util.NewBeaconBlock()
|
block1, err := tt.newBlock(types.Slot(1), nil)
|
||||||
block1.Block.Slot = 1
|
require.NoError(t, err)
|
||||||
require.NoError(t, db.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(block1)))
|
block2, err := tt.newBlock(types.Slot(10), nil)
|
||||||
block2 := util.NewBeaconBlock()
|
require.NoError(t, err)
|
||||||
block2.Block.Slot = 10
|
block3, err := tt.newBlock(types.Slot(100), nil)
|
||||||
require.NoError(t, db.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(block2)))
|
require.NoError(t, err)
|
||||||
block3 := util.NewBeaconBlock()
|
|
||||||
block3.Block.Slot = 100
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(block3)))
|
|
||||||
|
|
||||||
highestAt, err := db.HighestSlotBlocksBelow(ctx, 2)
|
require.NoError(t, db.SaveBlock(ctx, block1))
|
||||||
require.NoError(t, err)
|
require.NoError(t, db.SaveBlock(ctx, block2))
|
||||||
assert.Equal(t, false, len(highestAt) <= 0, "Got empty highest at slice")
|
require.NoError(t, db.SaveBlock(ctx, block3))
|
||||||
assert.Equal(t, true, proto.Equal(block1, highestAt[0].Proto()), "Wanted: %v, received: %v", block1, highestAt[0])
|
|
||||||
highestAt, err = db.HighestSlotBlocksBelow(ctx, 11)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, false, len(highestAt) <= 0, "Got empty highest at slice")
|
|
||||||
assert.Equal(t, true, proto.Equal(block2, highestAt[0].Proto()), "Wanted: %v, received: %v", block2, highestAt[0])
|
|
||||||
highestAt, err = db.HighestSlotBlocksBelow(ctx, 101)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, false, len(highestAt) <= 0, "Got empty highest at slice")
|
|
||||||
assert.Equal(t, true, proto.Equal(block3, highestAt[0].Proto()), "Wanted: %v, received: %v", block3, highestAt[0])
|
|
||||||
|
|
||||||
r3, err := block3.Block.HashTreeRoot()
|
highestAt, err := db.HighestSlotBlocksBelow(ctx, 2)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, db.deleteBlock(ctx, r3))
|
assert.Equal(t, false, len(highestAt) <= 0, "Got empty highest at slice")
|
||||||
|
assert.Equal(t, true, proto.Equal(block1.Proto(), highestAt[0].Proto()), "Wanted: %v, received: %v", block1, highestAt[0])
|
||||||
|
highestAt, err = db.HighestSlotBlocksBelow(ctx, 11)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, false, len(highestAt) <= 0, "Got empty highest at slice")
|
||||||
|
assert.Equal(t, true, proto.Equal(block2.Proto(), highestAt[0].Proto()), "Wanted: %v, received: %v", block2, highestAt[0])
|
||||||
|
highestAt, err = db.HighestSlotBlocksBelow(ctx, 101)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, false, len(highestAt) <= 0, "Got empty highest at slice")
|
||||||
|
assert.Equal(t, true, proto.Equal(block3.Proto(), highestAt[0].Proto()), "Wanted: %v, received: %v", block3, highestAt[0])
|
||||||
|
|
||||||
highestAt, err = db.HighestSlotBlocksBelow(ctx, 101)
|
r3, err := block3.Block().HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, true, proto.Equal(block2, highestAt[0].Proto()), "Wanted: %v, received: %v", block2, highestAt[0])
|
require.NoError(t, db.deleteBlock(ctx, r3))
|
||||||
|
|
||||||
|
highestAt, err = db.HighestSlotBlocksBelow(ctx, 101)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, true, proto.Equal(block2.Proto(), highestAt[0].Proto()), "Wanted: %v, received: %v", block2, highestAt[0])
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStore_GenesisBlock_CanGetHighestAt(t *testing.T) {
|
func TestStore_GenesisBlock_CanGetHighestAt(t *testing.T) {
|
||||||
db := setupDB(t)
|
for _, tt := range blockTests {
|
||||||
ctx := context.Background()
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
db := setupDB(t)
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
genesisBlock := util.NewBeaconBlock()
|
genesisBlock, err := tt.newBlock(types.Slot(0), nil)
|
||||||
genesisRoot, err := genesisBlock.Block.HashTreeRoot()
|
require.NoError(t, err)
|
||||||
require.NoError(t, err)
|
genesisRoot, err := genesisBlock.Block().HashTreeRoot()
|
||||||
require.NoError(t, db.SaveGenesisBlockRoot(ctx, genesisRoot))
|
require.NoError(t, err)
|
||||||
require.NoError(t, db.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(genesisBlock)))
|
require.NoError(t, db.SaveGenesisBlockRoot(ctx, genesisRoot))
|
||||||
block1 := util.NewBeaconBlock()
|
require.NoError(t, db.SaveBlock(ctx, genesisBlock))
|
||||||
block1.Block.Slot = 1
|
block1, err := tt.newBlock(types.Slot(1), nil)
|
||||||
require.NoError(t, db.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(block1)))
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, db.SaveBlock(ctx, block1))
|
||||||
|
|
||||||
highestAt, err := db.HighestSlotBlocksBelow(ctx, 2)
|
highestAt, err := db.HighestSlotBlocksBelow(ctx, 2)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, true, proto.Equal(block1, highestAt[0].Proto()), "Wanted: %v, received: %v", block1, highestAt[0])
|
assert.Equal(t, true, proto.Equal(block1.Proto(), highestAt[0].Proto()), "Wanted: %v, received: %v", block1, highestAt[0])
|
||||||
highestAt, err = db.HighestSlotBlocksBelow(ctx, 1)
|
highestAt, err = db.HighestSlotBlocksBelow(ctx, 1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, true, proto.Equal(genesisBlock, highestAt[0].Proto()), "Wanted: %v, received: %v", genesisBlock, highestAt[0])
|
assert.Equal(t, true, proto.Equal(genesisBlock.Proto(), highestAt[0].Proto()), "Wanted: %v, received: %v", genesisBlock, highestAt[0])
|
||||||
highestAt, err = db.HighestSlotBlocksBelow(ctx, 0)
|
highestAt, err = db.HighestSlotBlocksBelow(ctx, 0)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, true, proto.Equal(genesisBlock, highestAt[0].Proto()), "Wanted: %v, received: %v", genesisBlock, highestAt[0])
|
assert.Equal(t, true, proto.Equal(genesisBlock.Proto(), highestAt[0].Proto()), "Wanted: %v, received: %v", genesisBlock, highestAt[0])
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStore_SaveBlocks_HasCachedBlocks(t *testing.T) {
|
func TestStore_SaveBlocks_HasCachedBlocks(t *testing.T) {
|
||||||
db := setupDB(t)
|
for _, tt := range blockTests {
|
||||||
ctx := context.Background()
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
db := setupDB(t)
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
b := make([]block.SignedBeaconBlock, 500)
|
b := make([]block.SignedBeaconBlock, 500)
|
||||||
for i := 0; i < 500; i++ {
|
for i := 0; i < 500; i++ {
|
||||||
blk := util.NewBeaconBlock()
|
blk, err := tt.newBlock(types.Slot(i), bytesutil.PadTo([]byte("parent"), 32))
|
||||||
blk.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
require.NoError(t, err)
|
||||||
blk.Block.Slot = types.Slot(i)
|
b[i] = blk
|
||||||
b[i] = wrapper.WrappedPhase0SignedBeaconBlock(blk)
|
}
|
||||||
|
|
||||||
|
require.NoError(t, db.SaveBlock(ctx, b[0]))
|
||||||
|
require.NoError(t, db.SaveBlocks(ctx, b))
|
||||||
|
f := filters.NewFilter().SetStartSlot(0).SetEndSlot(500)
|
||||||
|
|
||||||
|
blks, _, err := db.Blocks(ctx, f)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, 500, len(blks), "Did not get wanted blocks")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, b[0]))
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, b))
|
|
||||||
f := filters.NewFilter().SetStartSlot(0).SetEndSlot(500)
|
|
||||||
|
|
||||||
blks, _, err := db.Blocks(ctx, f)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, 500, len(blks), "Did not get wanted blocks")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStore_SaveBlocks_HasRootsMatched(t *testing.T) {
|
func TestStore_SaveBlocks_HasRootsMatched(t *testing.T) {
|
||||||
db := setupDB(t)
|
for _, tt := range blockTests {
|
||||||
ctx := context.Background()
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
db := setupDB(t)
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
b := make([]block.SignedBeaconBlock, 500)
|
b := make([]block.SignedBeaconBlock, 500)
|
||||||
for i := 0; i < 500; i++ {
|
for i := 0; i < 500; i++ {
|
||||||
blk := util.NewBeaconBlock()
|
blk, err := tt.newBlock(types.Slot(i), bytesutil.PadTo([]byte("parent"), 32))
|
||||||
blk.Block.ParentRoot = bytesutil.PadTo([]byte("parent"), 32)
|
require.NoError(t, err)
|
||||||
blk.Block.Slot = types.Slot(i)
|
b[i] = blk
|
||||||
b[i] = wrapper.WrappedPhase0SignedBeaconBlock(blk)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, b))
|
require.NoError(t, db.SaveBlocks(ctx, b))
|
||||||
f := filters.NewFilter().SetStartSlot(0).SetEndSlot(500)
|
f := filters.NewFilter().SetStartSlot(0).SetEndSlot(500)
|
||||||
|
|
||||||
blks, roots, err := db.Blocks(ctx, f)
|
blks, roots, err := db.Blocks(ctx, f)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, 500, len(blks), "Did not get wanted blocks")
|
assert.Equal(t, 500, len(blks), "Did not get wanted blocks")
|
||||||
|
|
||||||
for i, blk := range blks {
|
for i, blk := range blks {
|
||||||
rt, err := blk.Block().HashTreeRoot()
|
rt, err := blk.Block().HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, roots[i], rt, "mismatch of block roots")
|
assert.Equal(t, roots[i], rt, "mismatch of block roots")
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStore_BlocksBySlot_BlockRootsBySlot(t *testing.T) {
|
func TestStore_BlocksBySlot_BlockRootsBySlot(t *testing.T) {
|
||||||
db := setupDB(t)
|
for _, tt := range blockTests {
|
||||||
ctx := context.Background()
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
db := setupDB(t)
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
b1 := util.NewBeaconBlock()
|
b1, err := tt.newBlock(types.Slot(20), nil)
|
||||||
b1.Block.Slot = 20
|
require.NoError(t, err)
|
||||||
require.NoError(t, db.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b1)))
|
require.NoError(t, db.SaveBlock(ctx, b1))
|
||||||
b2 := util.NewBeaconBlock()
|
b2, err := tt.newBlock(types.Slot(100), bytesutil.PadTo([]byte("parent1"), 32))
|
||||||
b2.Block.Slot = 100
|
require.NoError(t, err)
|
||||||
b2.Block.ParentRoot = bytesutil.PadTo([]byte("parent1"), 32)
|
require.NoError(t, db.SaveBlock(ctx, b2))
|
||||||
require.NoError(t, db.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b2)))
|
b3, err := tt.newBlock(types.Slot(100), bytesutil.PadTo([]byte("parent2"), 32))
|
||||||
b3 := util.NewBeaconBlock()
|
require.NoError(t, err)
|
||||||
b3.Block.Slot = 100
|
require.NoError(t, db.SaveBlock(ctx, b3))
|
||||||
b3.Block.ParentRoot = bytesutil.PadTo([]byte("parent2"), 32)
|
|
||||||
require.NoError(t, db.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b3)))
|
|
||||||
|
|
||||||
r1, err := b1.Block.HashTreeRoot()
|
r1, err := b1.Block().HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
r2, err := b2.Block.HashTreeRoot()
|
r2, err := b2.Block().HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
r3, err := b3.Block.HashTreeRoot()
|
r3, err := b3.Block().HashTreeRoot()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
hasBlocks, retrievedBlocks, err := db.BlocksBySlot(ctx, 1)
|
hasBlocks, retrievedBlocks, err := db.BlocksBySlot(ctx, 1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, 0, len(retrievedBlocks), "Unexpected number of blocks received, expected none")
|
assert.Equal(t, 0, len(retrievedBlocks), "Unexpected number of blocks received, expected none")
|
||||||
assert.Equal(t, false, hasBlocks, "Expected no blocks")
|
assert.Equal(t, false, hasBlocks, "Expected no blocks")
|
||||||
hasBlocks, retrievedBlocks, err = db.BlocksBySlot(ctx, 20)
|
hasBlocks, retrievedBlocks, err = db.BlocksBySlot(ctx, 20)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, true, proto.Equal(b1, retrievedBlocks[0].Proto()), "Wanted: %v, received: %v", b1, retrievedBlocks[0])
|
assert.Equal(t, true, proto.Equal(b1.Proto(), retrievedBlocks[0].Proto()), "Wanted: %v, received: %v", b1, retrievedBlocks[0])
|
||||||
assert.Equal(t, true, hasBlocks, "Expected to have blocks")
|
assert.Equal(t, true, hasBlocks, "Expected to have blocks")
|
||||||
hasBlocks, retrievedBlocks, err = db.BlocksBySlot(ctx, 100)
|
hasBlocks, retrievedBlocks, err = db.BlocksBySlot(ctx, 100)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, true, proto.Equal(b2, retrievedBlocks[0].Proto()), "Wanted: %v, received: %v", b2, retrievedBlocks[0])
|
if len(retrievedBlocks) != 2 {
|
||||||
assert.Equal(t, true, proto.Equal(b3, retrievedBlocks[1].Proto()), "Wanted: %v, received: %v", b3, retrievedBlocks[1])
|
t.Fatalf("Expected 2 blocks, received %d blocks", len(retrievedBlocks))
|
||||||
assert.Equal(t, true, hasBlocks, "Expected to have blocks")
|
}
|
||||||
|
assert.Equal(t, true, proto.Equal(b2.Proto(), retrievedBlocks[0].Proto()), "Wanted: %v, received: %v", b2, retrievedBlocks[0])
|
||||||
|
assert.Equal(t, true, proto.Equal(b3.Proto(), retrievedBlocks[1].Proto()), "Wanted: %v, received: %v", b3, retrievedBlocks[1])
|
||||||
|
assert.Equal(t, true, hasBlocks, "Expected to have blocks")
|
||||||
|
|
||||||
hasBlockRoots, retrievedBlockRoots, err := db.BlockRootsBySlot(ctx, 1)
|
hasBlockRoots, retrievedBlockRoots, err := db.BlockRootsBySlot(ctx, 1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.DeepEqual(t, [][32]byte{}, retrievedBlockRoots)
|
assert.DeepEqual(t, [][32]byte{}, retrievedBlockRoots)
|
||||||
assert.Equal(t, false, hasBlockRoots, "Expected no block roots")
|
assert.Equal(t, false, hasBlockRoots, "Expected no block roots")
|
||||||
hasBlockRoots, retrievedBlockRoots, err = db.BlockRootsBySlot(ctx, 20)
|
hasBlockRoots, retrievedBlockRoots, err = db.BlockRootsBySlot(ctx, 20)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.DeepEqual(t, [][32]byte{r1}, retrievedBlockRoots)
|
assert.DeepEqual(t, [][32]byte{r1}, retrievedBlockRoots)
|
||||||
assert.Equal(t, true, hasBlockRoots, "Expected no block roots")
|
assert.Equal(t, true, hasBlockRoots, "Expected no block roots")
|
||||||
hasBlockRoots, retrievedBlockRoots, err = db.BlockRootsBySlot(ctx, 100)
|
hasBlockRoots, retrievedBlockRoots, err = db.BlockRootsBySlot(ctx, 100)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.DeepEqual(t, [][32]byte{r2, r3}, retrievedBlockRoots)
|
assert.DeepEqual(t, [][32]byte{r2, r3}, retrievedBlockRoots)
|
||||||
assert.Equal(t, true, hasBlockRoots, "Expected no block roots")
|
assert.Equal(t, true, hasBlockRoots, "Expected no block roots")
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,76 +136,57 @@ func TestStore_IsFinalized_ForkEdgeCase(t *testing.T) {
|
|||||||
|
|
||||||
func TestStore_IsFinalizedChildBlock(t *testing.T) {
|
func TestStore_IsFinalizedChildBlock(t *testing.T) {
|
||||||
slotsPerEpoch := uint64(params.BeaconConfig().SlotsPerEpoch)
|
slotsPerEpoch := uint64(params.BeaconConfig().SlotsPerEpoch)
|
||||||
db := setupDB(t)
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
require.NoError(t, db.SaveGenesisBlockRoot(ctx, genesisBlockRoot))
|
eval := func(t testing.TB, ctx context.Context, db *Store, blks []block.SignedBeaconBlock) {
|
||||||
|
require.NoError(t, db.SaveBlocks(ctx, blks))
|
||||||
blks := makeBlocks(t, 0, slotsPerEpoch*3, genesisBlockRoot)
|
root, err := blks[slotsPerEpoch].Block().HashTreeRoot()
|
||||||
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, blks))
|
|
||||||
root, err := blks[slotsPerEpoch].Block().HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
cp := ðpb.Checkpoint{
|
|
||||||
Epoch: 1,
|
|
||||||
Root: root[:],
|
|
||||||
}
|
|
||||||
|
|
||||||
st, err := util.NewBeaconState()
|
|
||||||
require.NoError(t, err)
|
|
||||||
// a state is required to save checkpoint
|
|
||||||
require.NoError(t, db.SaveState(ctx, st, root))
|
|
||||||
require.NoError(t, db.SaveFinalizedCheckpoint(ctx, cp))
|
|
||||||
|
|
||||||
// All blocks up to slotsPerEpoch should have a finalized child block.
|
|
||||||
for i := uint64(0); i < slotsPerEpoch; i++ {
|
|
||||||
root, err := blks[i].Block().HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, true, db.IsFinalizedBlock(ctx, root), "Block at index %d was not considered finalized in the index", i)
|
|
||||||
blk, err := db.FinalizedChildBlock(ctx, root)
|
cp := ðpb.Checkpoint{
|
||||||
assert.NoError(t, err)
|
Epoch: 1,
|
||||||
if blk == nil {
|
Root: root[:],
|
||||||
t.Error("Child block doesn't exist for valid finalized block.")
|
}
|
||||||
|
|
||||||
|
st, err := util.NewBeaconState()
|
||||||
|
require.NoError(t, err)
|
||||||
|
// a state is required to save checkpoint
|
||||||
|
require.NoError(t, db.SaveState(ctx, st, root))
|
||||||
|
require.NoError(t, db.SaveFinalizedCheckpoint(ctx, cp))
|
||||||
|
|
||||||
|
// All blocks up to slotsPerEpoch should have a finalized child block.
|
||||||
|
for i := uint64(0); i < slotsPerEpoch; i++ {
|
||||||
|
root, err := blks[i].Block().HashTreeRoot()
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, true, db.IsFinalizedBlock(ctx, root), "Block at index %d was not considered finalized in the index", i)
|
||||||
|
blk, err := db.FinalizedChildBlock(ctx, root)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
if blk == nil {
|
||||||
|
t.Error("Child block doesn't exist for valid finalized block.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func TestStore_IsFinalizedChildBlockAltair(t *testing.T) {
|
setup := func(t testing.TB) *Store {
|
||||||
slotsPerEpoch := uint64(params.BeaconConfig().SlotsPerEpoch)
|
db := setupDB(t)
|
||||||
db := setupDB(t)
|
require.NoError(t, db.SaveGenesisBlockRoot(ctx, genesisBlockRoot))
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
require.NoError(t, db.SaveGenesisBlockRoot(ctx, genesisBlockRoot))
|
return db
|
||||||
|
|
||||||
blks := makeBlocksAltair(t, 0, slotsPerEpoch*3, genesisBlockRoot)
|
|
||||||
|
|
||||||
require.NoError(t, db.SaveBlocks(ctx, blks))
|
|
||||||
root, err := blks[slotsPerEpoch].Block().HashTreeRoot()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
cp := ðpb.Checkpoint{
|
|
||||||
Epoch: 1,
|
|
||||||
Root: root[:],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
st, err := util.NewBeaconState()
|
t.Run("phase0", func(t *testing.T) {
|
||||||
require.NoError(t, err)
|
db := setup(t)
|
||||||
// a state is required to save checkpoint
|
|
||||||
require.NoError(t, db.SaveState(ctx, st, root))
|
|
||||||
require.NoError(t, db.SaveFinalizedCheckpoint(ctx, cp))
|
|
||||||
|
|
||||||
// All blocks up to slotsPerEpoch should have a finalized child block.
|
blks := makeBlocks(t, 0, slotsPerEpoch*3, genesisBlockRoot)
|
||||||
for i := uint64(0); i < slotsPerEpoch; i++ {
|
eval(t, ctx, db, blks)
|
||||||
root, err := blks[i].Block().HashTreeRoot()
|
})
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, true, db.IsFinalizedBlock(ctx, root), "Block at index %d was not considered finalized in the index", i)
|
t.Run("altair", func(t *testing.T) {
|
||||||
blk, err := db.FinalizedChildBlock(ctx, root)
|
db := setup(t)
|
||||||
assert.NoError(t, err)
|
|
||||||
if blk == nil {
|
blks := makeBlocksAltair(t, 0, slotsPerEpoch*3, genesisBlockRoot)
|
||||||
t.Error("Child block doesn't exist for valid finalized block.")
|
eval(t, ctx, db, blks)
|
||||||
}
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func sszRootOrDie(t *testing.T, block block.SignedBeaconBlock) []byte {
|
func sszRootOrDie(t *testing.T, block block.SignedBeaconBlock) []byte {
|
||||||
|
|||||||
@@ -99,14 +99,7 @@ func (bs *Server) ListSyncCommittees(ctx context.Context, req *ethpbv2.StateSync
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func currentCommitteeIndicesFromState(st state.BeaconState) ([]types.ValidatorIndex, *ethpbalpha.SyncCommittee, error) {
|
func committeeIndicesFromState(st state.BeaconState, committee *ethpbalpha.SyncCommittee) ([]types.ValidatorIndex, *ethpbalpha.SyncCommittee, error) {
|
||||||
committee, err := st.CurrentSyncCommittee()
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf(
|
|
||||||
"could not get sync committee: %v", err,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
committeeIndices := make([]types.ValidatorIndex, len(committee.Pubkeys))
|
committeeIndices := make([]types.ValidatorIndex, len(committee.Pubkeys))
|
||||||
for i, key := range committee.Pubkeys {
|
for i, key := range committee.Pubkeys {
|
||||||
index, ok := st.ValidatorIndexByPubkey(bytesutil.ToBytes48(key))
|
index, ok := st.ValidatorIndexByPubkey(bytesutil.ToBytes48(key))
|
||||||
@@ -121,6 +114,17 @@ func currentCommitteeIndicesFromState(st state.BeaconState) ([]types.ValidatorIn
|
|||||||
return committeeIndices, committee, nil
|
return committeeIndices, committee, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func currentCommitteeIndicesFromState(st state.BeaconState) ([]types.ValidatorIndex, *ethpbalpha.SyncCommittee, error) {
|
||||||
|
committee, err := st.CurrentSyncCommittee()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf(
|
||||||
|
"could not get sync committee: %v", err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return committeeIndicesFromState(st, committee)
|
||||||
|
}
|
||||||
|
|
||||||
func nextCommitteeIndicesFromState(st state.BeaconState) ([]types.ValidatorIndex, *ethpbalpha.SyncCommittee, error) {
|
func nextCommitteeIndicesFromState(st state.BeaconState) ([]types.ValidatorIndex, *ethpbalpha.SyncCommittee, error) {
|
||||||
committee, err := st.NextSyncCommittee()
|
committee, err := st.NextSyncCommittee()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -129,18 +133,7 @@ func nextCommitteeIndicesFromState(st state.BeaconState) ([]types.ValidatorIndex
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
committeeIndices := make([]types.ValidatorIndex, len(committee.Pubkeys))
|
return committeeIndicesFromState(st, committee)
|
||||||
for i, key := range committee.Pubkeys {
|
|
||||||
index, ok := st.ValidatorIndexByPubkey(bytesutil.ToBytes48(key))
|
|
||||||
if !ok {
|
|
||||||
return nil, nil, fmt.Errorf(
|
|
||||||
"validator index not found for pubkey %#x",
|
|
||||||
bytesutil.Trunc(key),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
committeeIndices[i] = index
|
|
||||||
}
|
|
||||||
return committeeIndices, committee, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractSyncSubcommittees(st state.BeaconState, committee *ethpbalpha.SyncCommittee) ([]*ethpbv2.SyncSubcommitteeValidators, error) {
|
func extractSyncSubcommittees(st state.BeaconState, committee *ethpbalpha.SyncCommittee) ([]*ethpbv2.SyncSubcommitteeValidators, error) {
|
||||||
|
|||||||
@@ -41,75 +41,20 @@ type blockContainer struct {
|
|||||||
func (bs *Server) ListBlocks(
|
func (bs *Server) ListBlocks(
|
||||||
ctx context.Context, req *ethpb.ListBlocksRequest,
|
ctx context.Context, req *ethpb.ListBlocksRequest,
|
||||||
) (*ethpb.ListBlocksResponse, error) {
|
) (*ethpb.ListBlocksResponse, error) {
|
||||||
if int(req.PageSize) > cmd.Get().MaxRPCPageSize {
|
ctrs, numBlks, nextPageToken, err := bs.listBlocks(ctx, req)
|
||||||
return nil, status.Errorf(codes.InvalidArgument, "Requested page size %d can not be greater than max size %d",
|
if err != nil {
|
||||||
req.PageSize, cmd.Get().MaxRPCPageSize)
|
return nil, err
|
||||||
|
}
|
||||||
|
blkContainers, err := convertToProto(ctrs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch q := req.QueryFilter.(type) {
|
return ðpb.ListBlocksResponse{
|
||||||
case *ethpb.ListBlocksRequest_Epoch:
|
BlockContainers: blkContainers,
|
||||||
ctrs, numBlks, nextPageToken, err := bs.listBlocksForEpoch(ctx, req, q)
|
TotalSize: int32(numBlks),
|
||||||
if err != nil {
|
NextPageToken: nextPageToken,
|
||||||
return nil, err
|
}, nil
|
||||||
}
|
|
||||||
blkContainers, err := convertToProto(ctrs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return ðpb.ListBlocksResponse{
|
|
||||||
BlockContainers: blkContainers,
|
|
||||||
TotalSize: int32(numBlks),
|
|
||||||
NextPageToken: nextPageToken,
|
|
||||||
}, nil
|
|
||||||
case *ethpb.ListBlocksRequest_Root:
|
|
||||||
ctrs, numBlks, nextPageToken, err := bs.listBlocksForRoot(ctx, req, q)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
blkContainers, err := convertToProto(ctrs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return ðpb.ListBlocksResponse{
|
|
||||||
BlockContainers: blkContainers,
|
|
||||||
TotalSize: int32(numBlks),
|
|
||||||
NextPageToken: nextPageToken,
|
|
||||||
}, nil
|
|
||||||
|
|
||||||
case *ethpb.ListBlocksRequest_Slot:
|
|
||||||
ctrs, numBlks, nextPageToken, err := bs.listBlocksForSlot(ctx, req, q)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
blkContainers, err := convertToProto(ctrs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return ðpb.ListBlocksResponse{
|
|
||||||
BlockContainers: blkContainers,
|
|
||||||
TotalSize: int32(numBlks),
|
|
||||||
NextPageToken: nextPageToken,
|
|
||||||
}, nil
|
|
||||||
case *ethpb.ListBlocksRequest_Genesis:
|
|
||||||
ctrs, numBlks, nextPageToken, err := bs.listBlocksForGenesis(ctx, req, q)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
blkContainers, err := convertToProto(ctrs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ðpb.ListBlocksResponse{
|
|
||||||
BlockContainers: blkContainers,
|
|
||||||
TotalSize: int32(numBlks),
|
|
||||||
NextPageToken: nextPageToken,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, status.Error(codes.InvalidArgument, "Must specify a filter criteria for fetching blocks")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListBeaconBlocks retrieves blocks by root, slot, or epoch.
|
// ListBeaconBlocks retrieves blocks by root, slot, or epoch.
|
||||||
@@ -121,72 +66,39 @@ func (bs *Server) ListBlocks(
|
|||||||
func (bs *Server) ListBeaconBlocks(
|
func (bs *Server) ListBeaconBlocks(
|
||||||
ctx context.Context, req *ethpb.ListBlocksRequest,
|
ctx context.Context, req *ethpb.ListBlocksRequest,
|
||||||
) (*ethpb.ListBeaconBlocksResponse, error) {
|
) (*ethpb.ListBeaconBlocksResponse, error) {
|
||||||
|
ctrs, numBlks, nextPageToken, err := bs.listBlocks(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
altCtrs, err := convertFromV1Containers(ctrs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ðpb.ListBeaconBlocksResponse{
|
||||||
|
BlockContainers: altCtrs,
|
||||||
|
TotalSize: int32(numBlks),
|
||||||
|
NextPageToken: nextPageToken,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bs *Server) listBlocks(ctx context.Context, req *ethpb.ListBlocksRequest) ([]blockContainer, int, string, error) {
|
||||||
if int(req.PageSize) > cmd.Get().MaxRPCPageSize {
|
if int(req.PageSize) > cmd.Get().MaxRPCPageSize {
|
||||||
return nil, status.Errorf(codes.InvalidArgument, "Requested page size %d can not be greater than max size %d",
|
return nil, 0, "", status.Errorf(codes.InvalidArgument, "Requested page size %d can not be greater than max size %d",
|
||||||
req.PageSize, cmd.Get().MaxRPCPageSize)
|
req.PageSize, cmd.Get().MaxRPCPageSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch q := req.QueryFilter.(type) {
|
switch q := req.QueryFilter.(type) {
|
||||||
case *ethpb.ListBlocksRequest_Epoch:
|
case *ethpb.ListBlocksRequest_Epoch:
|
||||||
ctrs, numBlks, nextPageToken, err := bs.listBlocksForEpoch(ctx, req, q)
|
return bs.listBlocksForEpoch(ctx, req, q)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
altCtrs, err := convertFromV1Containers(ctrs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ðpb.ListBeaconBlocksResponse{
|
|
||||||
BlockContainers: altCtrs,
|
|
||||||
TotalSize: int32(numBlks),
|
|
||||||
NextPageToken: nextPageToken,
|
|
||||||
}, nil
|
|
||||||
case *ethpb.ListBlocksRequest_Root:
|
case *ethpb.ListBlocksRequest_Root:
|
||||||
ctrs, numBlks, nextPageToken, err := bs.listBlocksForRoot(ctx, req, q)
|
return bs.listBlocksForRoot(ctx, req, q)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
altCtrs, err := convertFromV1Containers(ctrs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ðpb.ListBeaconBlocksResponse{
|
|
||||||
BlockContainers: altCtrs,
|
|
||||||
TotalSize: int32(numBlks),
|
|
||||||
NextPageToken: nextPageToken,
|
|
||||||
}, nil
|
|
||||||
|
|
||||||
case *ethpb.ListBlocksRequest_Slot:
|
case *ethpb.ListBlocksRequest_Slot:
|
||||||
ctrs, numBlks, nextPageToken, err := bs.listBlocksForSlot(ctx, req, q)
|
return bs.listBlocksForSlot(ctx, req, q)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
altCtrs, err := convertFromV1Containers(ctrs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ðpb.ListBeaconBlocksResponse{
|
|
||||||
BlockContainers: altCtrs,
|
|
||||||
TotalSize: int32(numBlks),
|
|
||||||
NextPageToken: nextPageToken,
|
|
||||||
}, nil
|
|
||||||
case *ethpb.ListBlocksRequest_Genesis:
|
case *ethpb.ListBlocksRequest_Genesis:
|
||||||
ctrs, numBlks, nextPageToken, err := bs.listBlocksForGenesis(ctx, req, q)
|
return bs.listBlocksForGenesis(ctx, req, q)
|
||||||
if err != nil {
|
default:
|
||||||
return nil, err
|
return nil, 0, "", status.Errorf(codes.InvalidArgument, "Must specify a filter criteria for fetching blocks. Criteria %T not supported", q)
|
||||||
}
|
|
||||||
altCtrs, err := convertFromV1Containers(ctrs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ðpb.ListBeaconBlocksResponse{
|
|
||||||
BlockContainers: altCtrs,
|
|
||||||
TotalSize: int32(numBlks),
|
|
||||||
NextPageToken: nextPageToken,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, status.Error(codes.InvalidArgument, "Must specify a filter criteria for fetching blocks")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertFromV1Containers(ctrs []blockContainer) ([]*ethpb.BeaconBlockContainer, error) {
|
func convertFromV1Containers(ctrs []blockContainer) ([]*ethpb.BeaconBlockContainer, error) {
|
||||||
|
|||||||
@@ -12,7 +12,10 @@ go_library(
|
|||||||
|
|
||||||
go_test(
|
go_test(
|
||||||
name = "go_default_test",
|
name = "go_default_test",
|
||||||
srcs = ["mainnet_test.go"],
|
srcs = [
|
||||||
|
"common_test.go",
|
||||||
|
"mainnet_test.go",
|
||||||
|
],
|
||||||
deps = [
|
deps = [
|
||||||
":go_default_library",
|
":go_default_library",
|
||||||
"//config/params:go_default_library",
|
"//config/params:go_default_library",
|
||||||
@@ -22,7 +25,10 @@ go_test(
|
|||||||
|
|
||||||
go_test(
|
go_test(
|
||||||
name = "go_minimal_test",
|
name = "go_minimal_test",
|
||||||
srcs = ["minimal_test.go"],
|
srcs = [
|
||||||
|
"common_test.go",
|
||||||
|
"minimal_test.go",
|
||||||
|
],
|
||||||
eth_network = "minimal",
|
eth_network = "minimal",
|
||||||
deps = [
|
deps = [
|
||||||
":go_default_library",
|
":go_default_library",
|
||||||
|
|||||||
22
config/fieldparams/common_test.go
Normal file
22
config/fieldparams/common_test.go
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package field_params_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||||
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
|
"github.com/prysmaticlabs/prysm/testing/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func testFieldParametersMatchConfig(t *testing.T) {
|
||||||
|
assert.Equal(t, uint64(params.BeaconConfig().SlotsPerHistoricalRoot), uint64(fieldparams.BlockRootsLength))
|
||||||
|
assert.Equal(t, uint64(params.BeaconConfig().SlotsPerHistoricalRoot), uint64(fieldparams.StateRootsLength))
|
||||||
|
assert.Equal(t, params.BeaconConfig().HistoricalRootsLimit, uint64(fieldparams.HistoricalRootsLength))
|
||||||
|
assert.Equal(t, uint64(params.BeaconConfig().EpochsPerHistoricalVector), uint64(fieldparams.RandaoMixesLength))
|
||||||
|
assert.Equal(t, params.BeaconConfig().ValidatorRegistryLimit, uint64(fieldparams.ValidatorRegistryLimit))
|
||||||
|
assert.Equal(t, uint64(params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().EpochsPerEth1VotingPeriod))), uint64(fieldparams.Eth1DataVotesLength))
|
||||||
|
assert.Equal(t, uint64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().MaxAttestations)), uint64(fieldparams.PreviousEpochAttestationsLength))
|
||||||
|
assert.Equal(t, uint64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().MaxAttestations)), uint64(fieldparams.CurrentEpochAttestationsLength))
|
||||||
|
assert.Equal(t, uint64(params.BeaconConfig().EpochsPerSlashingsVector), uint64(fieldparams.SlashingsLength))
|
||||||
|
assert.Equal(t, params.BeaconConfig().SyncCommitteeSize, uint64(fieldparams.SyncCommitteeLength))
|
||||||
|
}
|
||||||
@@ -5,21 +5,10 @@ package field_params_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFieldParametersValues(t *testing.T) {
|
func TestFieldParametersValues(t *testing.T) {
|
||||||
params.UseMainnetConfig()
|
params.UseMainnetConfig()
|
||||||
assert.Equal(t, uint64(params.BeaconConfig().SlotsPerHistoricalRoot), uint64(fieldparams.BlockRootsLength))
|
testFieldParametersMatchConfig(t)
|
||||||
assert.Equal(t, uint64(params.BeaconConfig().SlotsPerHistoricalRoot), uint64(fieldparams.StateRootsLength))
|
|
||||||
assert.Equal(t, params.BeaconConfig().HistoricalRootsLimit, uint64(fieldparams.HistoricalRootsLength))
|
|
||||||
assert.Equal(t, uint64(params.BeaconConfig().EpochsPerHistoricalVector), uint64(fieldparams.RandaoMixesLength))
|
|
||||||
assert.Equal(t, params.BeaconConfig().ValidatorRegistryLimit, uint64(fieldparams.ValidatorRegistryLimit))
|
|
||||||
assert.Equal(t, uint64(params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().EpochsPerEth1VotingPeriod))), uint64(fieldparams.Eth1DataVotesLength))
|
|
||||||
assert.Equal(t, uint64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().MaxAttestations)), uint64(fieldparams.PreviousEpochAttestationsLength))
|
|
||||||
assert.Equal(t, uint64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().MaxAttestations)), uint64(fieldparams.CurrentEpochAttestationsLength))
|
|
||||||
assert.Equal(t, uint64(params.BeaconConfig().EpochsPerSlashingsVector), uint64(fieldparams.SlashingsLength))
|
|
||||||
assert.Equal(t, params.BeaconConfig().SyncCommitteeSize, uint64(fieldparams.SyncCommitteeLength))
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,21 +5,10 @@ package field_params_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
|
||||||
"github.com/prysmaticlabs/prysm/config/params"
|
"github.com/prysmaticlabs/prysm/config/params"
|
||||||
"github.com/prysmaticlabs/prysm/testing/assert"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFieldParametersValues(t *testing.T) {
|
func TestFieldParametersValues(t *testing.T) {
|
||||||
params.UseMinimalConfig()
|
params.UseMinimalConfig()
|
||||||
assert.Equal(t, uint64(params.BeaconConfig().SlotsPerHistoricalRoot), uint64(fieldparams.BlockRootsLength))
|
testFieldParametersMatchConfig(t)
|
||||||
assert.Equal(t, uint64(params.BeaconConfig().SlotsPerHistoricalRoot), uint64(fieldparams.StateRootsLength))
|
|
||||||
assert.Equal(t, params.BeaconConfig().HistoricalRootsLimit, uint64(fieldparams.HistoricalRootsLength))
|
|
||||||
assert.Equal(t, uint64(params.BeaconConfig().EpochsPerHistoricalVector), uint64(fieldparams.RandaoMixesLength))
|
|
||||||
assert.Equal(t, params.BeaconConfig().ValidatorRegistryLimit, uint64(fieldparams.ValidatorRegistryLimit))
|
|
||||||
assert.Equal(t, uint64(params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().EpochsPerEth1VotingPeriod))), uint64(fieldparams.Eth1DataVotesLength))
|
|
||||||
assert.Equal(t, uint64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().MaxAttestations)), uint64(fieldparams.PreviousEpochAttestationsLength))
|
|
||||||
assert.Equal(t, uint64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().MaxAttestations)), uint64(fieldparams.CurrentEpochAttestationsLength))
|
|
||||||
assert.Equal(t, uint64(params.BeaconConfig().EpochsPerSlashingsVector), uint64(fieldparams.SlashingsLength))
|
|
||||||
assert.Equal(t, params.BeaconConfig().SyncCommitteeSize, uint64(fieldparams.SyncCommitteeLength))
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,27 @@ var (
|
|||||||
_ = block.SignedBeaconBlock(&altairSignedBeaconBlock{})
|
_ = block.SignedBeaconBlock(&altairSignedBeaconBlock{})
|
||||||
_ = block.BeaconBlock(&altairBeaconBlock{})
|
_ = block.BeaconBlock(&altairBeaconBlock{})
|
||||||
_ = block.BeaconBlockBody(&altairBeaconBlockBody{})
|
_ = block.BeaconBlockBody(&altairBeaconBlockBody{})
|
||||||
|
|
||||||
|
// ErrUnsupportedSignedBeaconBlock is returned when the struct type is not a supported signed
|
||||||
|
// beacon block type.
|
||||||
|
ErrUnsupportedSignedBeaconBlock = errors.New("unsupported signed beacon block")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// WrappedSignedBeaconBlock will wrap a signed beacon block to conform to the
|
||||||
|
// signed beacon block interface.
|
||||||
|
func WrappedSignedBeaconBlock(i interface{}) (block.SignedBeaconBlock, error) {
|
||||||
|
switch b := i.(type) {
|
||||||
|
case *eth.SignedBeaconBlock:
|
||||||
|
return WrappedPhase0SignedBeaconBlock(b), nil
|
||||||
|
case *eth.SignedBeaconBlockAltair:
|
||||||
|
return WrappedAltairSignedBeaconBlock(b)
|
||||||
|
case *eth.SignedBeaconBlockMerge:
|
||||||
|
return WrappedMergeSignedBeaconBlock(b)
|
||||||
|
default:
|
||||||
|
return nil, errors.Wrapf(ErrUnsupportedSignedBeaconBlock, "unable to wrap block of type %T", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Phase0SignedBeaconBlock is a convenience wrapper around a phase 0 beacon block
|
// Phase0SignedBeaconBlock is a convenience wrapper around a phase 0 beacon block
|
||||||
// object. This wrapper allows us to conform to a common interface so that beacon
|
// object. This wrapper allows us to conform to a common interface so that beacon
|
||||||
// blocks for future forks can also be applied across prysm without issues.
|
// blocks for future forks can also be applied across prysm without issues.
|
||||||
@@ -24,6 +43,7 @@ type Phase0SignedBeaconBlock struct {
|
|||||||
|
|
||||||
// WrappedPhase0SignedBeaconBlock is constructor which wraps a protobuf phase 0 block
|
// WrappedPhase0SignedBeaconBlock is constructor which wraps a protobuf phase 0 block
|
||||||
// with the block wrapper.
|
// with the block wrapper.
|
||||||
|
// Deprecated: use WrappedSignedBeaconBlock instead.
|
||||||
func WrappedPhase0SignedBeaconBlock(b *eth.SignedBeaconBlock) block.SignedBeaconBlock {
|
func WrappedPhase0SignedBeaconBlock(b *eth.SignedBeaconBlock) block.SignedBeaconBlock {
|
||||||
return Phase0SignedBeaconBlock{b: b}
|
return Phase0SignedBeaconBlock{b: b}
|
||||||
}
|
}
|
||||||
@@ -291,6 +311,7 @@ type altairSignedBeaconBlock struct {
|
|||||||
|
|
||||||
// WrappedAltairSignedBeaconBlock is constructor which wraps a protobuf altair block
|
// WrappedAltairSignedBeaconBlock is constructor which wraps a protobuf altair block
|
||||||
// with the block wrapper.
|
// with the block wrapper.
|
||||||
|
// Deprecated: use WrappedSignedBeaconBlock instead.
|
||||||
func WrappedAltairSignedBeaconBlock(b *eth.SignedBeaconBlockAltair) (block.SignedBeaconBlock, error) {
|
func WrappedAltairSignedBeaconBlock(b *eth.SignedBeaconBlockAltair) (block.SignedBeaconBlock, error) {
|
||||||
w := altairSignedBeaconBlock{b: b}
|
w := altairSignedBeaconBlock{b: b}
|
||||||
if w.IsNil() {
|
if w.IsNil() {
|
||||||
@@ -561,6 +582,7 @@ type mergeSignedBeaconBlock struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WrappedMergeSignedBeaconBlock is constructor which wraps a protobuf merge block with the block wrapper.
|
// WrappedMergeSignedBeaconBlock is constructor which wraps a protobuf merge block with the block wrapper.
|
||||||
|
// Deprecated: use WrappedSignedBeaconBlock instead.
|
||||||
func WrappedMergeSignedBeaconBlock(b *eth.SignedBeaconBlockMerge) (block.SignedBeaconBlock, error) {
|
func WrappedMergeSignedBeaconBlock(b *eth.SignedBeaconBlockMerge) (block.SignedBeaconBlock, error) {
|
||||||
w := mergeSignedBeaconBlock{b: b}
|
w := mergeSignedBeaconBlock{b: b}
|
||||||
if w.IsNil() {
|
if w.IsNil() {
|
||||||
|
|||||||
@@ -14,6 +14,42 @@ import (
|
|||||||
"github.com/prysmaticlabs/prysm/testing/util"
|
"github.com/prysmaticlabs/prysm/testing/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestWrappedSignedBeaconBlock(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
blk interface{}
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "unsupported type",
|
||||||
|
blk: "not a beacon block",
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "phase0",
|
||||||
|
blk: util.NewBeaconBlock(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "altair",
|
||||||
|
blk: util.NewBeaconBlockAltair(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "bellatrix",
|
||||||
|
blk: util.NewBeaconBlockMerge(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
_, err := wrapper.WrappedSignedBeaconBlock(tt.blk)
|
||||||
|
if tt.wantErr {
|
||||||
|
require.ErrorIs(t, err, wrapper.ErrUnsupportedSignedBeaconBlock)
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestAltairSignedBeaconBlock_Signature(t *testing.T) {
|
func TestAltairSignedBeaconBlock_Signature(t *testing.T) {
|
||||||
sig := []byte{0x11, 0x22}
|
sig := []byte{0x11, 0x22}
|
||||||
wsb, err := wrapper.WrappedAltairSignedBeaconBlock(ðpb.SignedBeaconBlockAltair{Block: ðpb.BeaconBlockAltair{}, Signature: sig})
|
wsb, err := wrapper.WrappedAltairSignedBeaconBlock(ðpb.SignedBeaconBlockAltair{Block: ðpb.BeaconBlockAltair{}, Signature: sig})
|
||||||
|
|||||||
Reference in New Issue
Block a user