github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/rpc/eth/v1/beacon/blocks_test.go (about)

     1  package beacon
     2  
     3  import (
     4  	"context"
     5  	"reflect"
     6  	"testing"
     7  
     8  	types "github.com/prysmaticlabs/eth2-types"
     9  	mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
    10  	"github.com/prysmaticlabs/prysm/beacon-chain/db"
    11  	dbTest "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
    12  	mockp2p "github.com/prysmaticlabs/prysm/beacon-chain/p2p/testing"
    13  	p2ppb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
    14  	ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1"
    15  	ethpb_alpha "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
    16  	"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
    17  	"github.com/prysmaticlabs/prysm/proto/interfaces"
    18  	"github.com/prysmaticlabs/prysm/proto/migration"
    19  	"github.com/prysmaticlabs/prysm/shared/bytesutil"
    20  	"github.com/prysmaticlabs/prysm/shared/params"
    21  	"github.com/prysmaticlabs/prysm/shared/testutil"
    22  	"github.com/prysmaticlabs/prysm/shared/testutil/assert"
    23  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    24  )
    25  
    26  func fillDBTestBlocks(ctx context.Context, t *testing.T, beaconDB db.Database) (*ethpb_alpha.SignedBeaconBlock, []*ethpb_alpha.BeaconBlockContainer) {
    27  	parentRoot := [32]byte{1, 2, 3}
    28  	genBlk := testutil.NewBeaconBlock()
    29  	genBlk.Block.ParentRoot = parentRoot[:]
    30  	root, err := genBlk.Block.HashTreeRoot()
    31  	require.NoError(t, err)
    32  	require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(genBlk)))
    33  	require.NoError(t, beaconDB.SaveGenesisBlockRoot(ctx, root))
    34  
    35  	count := types.Slot(100)
    36  	blks := make([]interfaces.SignedBeaconBlock, count)
    37  	blkContainers := make([]*ethpb_alpha.BeaconBlockContainer, count)
    38  	for i := types.Slot(0); i < count; i++ {
    39  		b := testutil.NewBeaconBlock()
    40  		b.Block.Slot = i
    41  		b.Block.ParentRoot = bytesutil.PadTo([]byte{uint8(i)}, 32)
    42  		att1 := testutil.NewAttestation()
    43  		att1.Data.Slot = i
    44  		att1.Data.CommitteeIndex = types.CommitteeIndex(i)
    45  		att2 := testutil.NewAttestation()
    46  		att2.Data.Slot = i
    47  		att2.Data.CommitteeIndex = types.CommitteeIndex(i + 1)
    48  		b.Block.Body.Attestations = []*ethpb_alpha.Attestation{att1, att2}
    49  		root, err := b.Block.HashTreeRoot()
    50  		require.NoError(t, err)
    51  		blks[i] = wrapper.WrappedPhase0SignedBeaconBlock(b)
    52  		blkContainers[i] = &ethpb_alpha.BeaconBlockContainer{Block: b, BlockRoot: root[:]}
    53  	}
    54  	require.NoError(t, beaconDB.SaveBlocks(ctx, blks))
    55  	headRoot := bytesutil.ToBytes32(blkContainers[len(blks)-1].BlockRoot)
    56  	summary := &p2ppb.StateSummary{
    57  		Root: headRoot[:],
    58  		Slot: blkContainers[len(blks)-1].Block.Block.Slot,
    59  	}
    60  	require.NoError(t, beaconDB.SaveStateSummary(ctx, summary))
    61  	require.NoError(t, beaconDB.SaveHeadBlockRoot(ctx, headRoot))
    62  	return genBlk, blkContainers
    63  }
    64  
    65  func TestServer_GetBlockHeader(t *testing.T) {
    66  	beaconDB := dbTest.SetupDB(t)
    67  	ctx := context.Background()
    68  
    69  	genBlk, blkContainers := fillDBTestBlocks(ctx, t, beaconDB)
    70  	root, err := genBlk.Block.HashTreeRoot()
    71  	require.NoError(t, err)
    72  	headBlock := blkContainers[len(blkContainers)-1]
    73  
    74  	b2 := testutil.NewBeaconBlock()
    75  	b2.Block.Slot = 30
    76  	b2.Block.ParentRoot = bytesutil.PadTo([]byte{1}, 32)
    77  	require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b2)))
    78  	b3 := testutil.NewBeaconBlock()
    79  	b3.Block.Slot = 30
    80  	b3.Block.ParentRoot = bytesutil.PadTo([]byte{4}, 32)
    81  	require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b3)))
    82  
    83  	bs := &Server{
    84  		BeaconDB: beaconDB,
    85  		ChainInfoFetcher: &mock.ChainService{
    86  			DB:                  beaconDB,
    87  			Block:               wrapper.WrappedPhase0SignedBeaconBlock(headBlock.Block),
    88  			Root:                headBlock.BlockRoot,
    89  			FinalizedCheckPoint: &ethpb_alpha.Checkpoint{Root: blkContainers[64].BlockRoot},
    90  		},
    91  	}
    92  
    93  	tests := []struct {
    94  		name    string
    95  		blockID []byte
    96  		want    *ethpb_alpha.SignedBeaconBlock
    97  		wantErr bool
    98  	}{
    99  		{
   100  			name:    "slot",
   101  			blockID: []byte("30"),
   102  			want:    blkContainers[30].Block,
   103  		},
   104  		{
   105  			name:    "root",
   106  			blockID: blkContainers[20].BlockRoot,
   107  			want:    blkContainers[20].Block,
   108  		},
   109  		{
   110  			name:    "canonical",
   111  			blockID: []byte("30"),
   112  			want:    blkContainers[30].Block,
   113  		},
   114  		{
   115  			name:    "genesis",
   116  			blockID: []byte("genesis"),
   117  			want:    genBlk,
   118  		},
   119  		{
   120  			name:    "genesis root",
   121  			blockID: root[:],
   122  			want:    genBlk,
   123  		},
   124  		{
   125  			name:    "head",
   126  			blockID: []byte("head"),
   127  			want:    headBlock.Block,
   128  		},
   129  		{
   130  			name:    "finalized",
   131  			blockID: []byte("finalized"),
   132  			want:    blkContainers[64].Block,
   133  		},
   134  		{
   135  			name:    "no block",
   136  			blockID: []byte("105"),
   137  			wantErr: true,
   138  		},
   139  	}
   140  	for _, tt := range tests {
   141  		t.Run(tt.name, func(t *testing.T) {
   142  			header, err := bs.GetBlockHeader(ctx, &ethpb.BlockRequest{
   143  				BlockId: tt.blockID,
   144  			})
   145  			if !tt.wantErr {
   146  				require.NoError(t, err)
   147  			} else {
   148  				require.NotEqual(t, err, nil)
   149  				return
   150  			}
   151  
   152  			blkHdr, err := migration.V1Alpha1BlockToV1BlockHeader(tt.want)
   153  			require.NoError(t, err)
   154  
   155  			if !reflect.DeepEqual(header.Data.Header.Message, blkHdr.Message) {
   156  				t.Error("Expected blocks to equal")
   157  			}
   158  		})
   159  	}
   160  }
   161  
   162  func TestServer_ListBlockHeaders(t *testing.T) {
   163  	beaconDB := dbTest.SetupDB(t)
   164  	ctx := context.Background()
   165  
   166  	_, blkContainers := fillDBTestBlocks(ctx, t, beaconDB)
   167  	headBlock := blkContainers[len(blkContainers)-1]
   168  	bs := &Server{
   169  		BeaconDB: beaconDB,
   170  		ChainInfoFetcher: &mock.ChainService{
   171  			DB:                  beaconDB,
   172  			Block:               wrapper.WrappedPhase0SignedBeaconBlock(headBlock.Block),
   173  			Root:                headBlock.BlockRoot,
   174  			FinalizedCheckPoint: &ethpb_alpha.Checkpoint{Root: blkContainers[64].BlockRoot},
   175  		},
   176  	}
   177  
   178  	b2 := testutil.NewBeaconBlock()
   179  	b2.Block.Slot = 30
   180  	b2.Block.ParentRoot = bytesutil.PadTo([]byte{1}, 32)
   181  	require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b2)))
   182  	b3 := testutil.NewBeaconBlock()
   183  	b3.Block.Slot = 30
   184  	b3.Block.ParentRoot = bytesutil.PadTo([]byte{4}, 32)
   185  	require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b3)))
   186  	b4 := testutil.NewBeaconBlock()
   187  	b4.Block.Slot = 31
   188  	b4.Block.ParentRoot = bytesutil.PadTo([]byte{1}, 32)
   189  	require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b4)))
   190  	b5 := testutil.NewBeaconBlock()
   191  	b5.Block.Slot = 28
   192  	b5.Block.ParentRoot = bytesutil.PadTo([]byte{1}, 32)
   193  	require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b5)))
   194  
   195  	tests := []struct {
   196  		name       string
   197  		slot       types.Slot
   198  		parentRoot []byte
   199  		want       []*ethpb_alpha.SignedBeaconBlock
   200  		wantErr    bool
   201  	}{
   202  		{
   203  			name: "slot",
   204  			slot: types.Slot(30),
   205  			want: []*ethpb_alpha.SignedBeaconBlock{
   206  				blkContainers[30].Block,
   207  				b2,
   208  				b3,
   209  			},
   210  		},
   211  		{
   212  			name:       "parent root",
   213  			parentRoot: b2.Block.ParentRoot,
   214  			want: []*ethpb_alpha.SignedBeaconBlock{
   215  				blkContainers[1].Block,
   216  				b2,
   217  				b4,
   218  				b5,
   219  			},
   220  		},
   221  	}
   222  	for _, tt := range tests {
   223  		t.Run(tt.name, func(t *testing.T) {
   224  			headers, err := bs.ListBlockHeaders(ctx, &ethpb.BlockHeadersRequest{
   225  				Slot:       &tt.slot,
   226  				ParentRoot: tt.parentRoot,
   227  			})
   228  			require.NoError(t, err)
   229  
   230  			require.Equal(t, len(tt.want), len(headers.Data))
   231  			for i, blk := range tt.want {
   232  				signedHdr, err := migration.V1Alpha1BlockToV1BlockHeader(blk)
   233  				require.NoError(t, err)
   234  
   235  				if !reflect.DeepEqual(headers.Data[i].Header.Message, signedHdr.Message) {
   236  					t.Error("Expected blocks to equal")
   237  				}
   238  			}
   239  		})
   240  	}
   241  }
   242  
   243  func TestServer_ProposeBlock_OK(t *testing.T) {
   244  	beaconDB := dbTest.SetupDB(t)
   245  	ctx := context.Background()
   246  	params.SetupTestConfigCleanup(t)
   247  	params.OverrideBeaconConfig(params.MainnetConfig())
   248  
   249  	genesis := testutil.NewBeaconBlock()
   250  	require.NoError(t, beaconDB.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(genesis)), "Could not save genesis block")
   251  
   252  	numDeposits := uint64(64)
   253  	beaconState, _ := testutil.DeterministicGenesisState(t, numDeposits)
   254  	bsRoot, err := beaconState.HashTreeRoot(ctx)
   255  	require.NoError(t, err)
   256  	genesisRoot, err := genesis.Block.HashTreeRoot()
   257  	require.NoError(t, err)
   258  	require.NoError(t, beaconDB.SaveState(ctx, beaconState, genesisRoot), "Could not save genesis state")
   259  
   260  	c := &mock.ChainService{Root: bsRoot[:], State: beaconState}
   261  	beaconChainServer := &Server{
   262  		BeaconDB:         beaconDB,
   263  		BlockReceiver:    c,
   264  		ChainInfoFetcher: c,
   265  		BlockNotifier:    c.BlockNotifier(),
   266  		Broadcaster:      mockp2p.NewTestP2P(t),
   267  	}
   268  	req := testutil.NewBeaconBlock()
   269  	req.Block.Slot = 5
   270  	req.Block.ParentRoot = bsRoot[:]
   271  	v1Block, err := migration.V1Alpha1ToV1Block(req)
   272  	require.NoError(t, err)
   273  	require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(req)))
   274  	blockReq := &ethpb.BeaconBlockContainer{
   275  		Message:   v1Block.Block,
   276  		Signature: v1Block.Signature,
   277  	}
   278  	_, err = beaconChainServer.SubmitBlock(context.Background(), blockReq)
   279  	assert.NoError(t, err, "Could not propose block correctly")
   280  }
   281  
   282  func TestServer_GetBlock(t *testing.T) {
   283  	beaconDB := dbTest.SetupDB(t)
   284  	ctx := context.Background()
   285  
   286  	_, blkContainers := fillDBTestBlocks(ctx, t, beaconDB)
   287  	headBlock := blkContainers[len(blkContainers)-1]
   288  
   289  	b2 := testutil.NewBeaconBlock()
   290  	b2.Block.Slot = 30
   291  	b2.Block.ParentRoot = bytesutil.PadTo([]byte{1}, 32)
   292  	require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b2)))
   293  	b3 := testutil.NewBeaconBlock()
   294  	b3.Block.Slot = 30
   295  	b3.Block.ParentRoot = bytesutil.PadTo([]byte{4}, 32)
   296  	require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b3)))
   297  
   298  	bs := &Server{
   299  		BeaconDB: beaconDB,
   300  		ChainInfoFetcher: &mock.ChainService{
   301  			DB:                  beaconDB,
   302  			Block:               wrapper.WrappedPhase0SignedBeaconBlock(headBlock.Block),
   303  			Root:                headBlock.BlockRoot,
   304  			FinalizedCheckPoint: &ethpb_alpha.Checkpoint{Root: blkContainers[64].BlockRoot},
   305  		},
   306  	}
   307  
   308  	genBlk, blkContainers := fillDBTestBlocks(ctx, t, beaconDB)
   309  	root, err := genBlk.Block.HashTreeRoot()
   310  	require.NoError(t, err)
   311  
   312  	tests := []struct {
   313  		name    string
   314  		blockID []byte
   315  		want    *ethpb_alpha.SignedBeaconBlock
   316  		wantErr bool
   317  	}{
   318  		{
   319  			name:    "slot",
   320  			blockID: []byte("30"),
   321  			want:    blkContainers[30].Block,
   322  		},
   323  		{
   324  			name:    "bad formatting",
   325  			blockID: []byte("3bad0"),
   326  			wantErr: true,
   327  		},
   328  		{
   329  			name:    "canonical",
   330  			blockID: []byte("30"),
   331  			want:    blkContainers[30].Block,
   332  		},
   333  		{
   334  			name:    "head",
   335  			blockID: []byte("head"),
   336  			want:    headBlock.Block,
   337  		},
   338  		{
   339  			name:    "finalized",
   340  			blockID: []byte("finalized"),
   341  			want:    blkContainers[64].Block,
   342  		},
   343  		{
   344  			name:    "genesis",
   345  			blockID: []byte("genesis"),
   346  			want:    genBlk,
   347  		},
   348  		{
   349  			name:    "genesis root",
   350  			blockID: root[:],
   351  			want:    genBlk,
   352  		},
   353  		{
   354  			name:    "root",
   355  			blockID: blkContainers[20].BlockRoot,
   356  			want:    blkContainers[20].Block,
   357  		},
   358  		{
   359  			name:    "non-existent root",
   360  			blockID: bytesutil.PadTo([]byte("hi there"), 32),
   361  			wantErr: true,
   362  		},
   363  		{
   364  			name:    "slot",
   365  			blockID: []byte("40"),
   366  			want:    blkContainers[40].Block,
   367  		},
   368  		{
   369  			name:    "no block",
   370  			blockID: []byte("105"),
   371  			wantErr: true,
   372  		},
   373  	}
   374  	for _, tt := range tests {
   375  		t.Run(tt.name, func(t *testing.T) {
   376  			block, err := bs.GetBlock(ctx, &ethpb.BlockRequest{
   377  				BlockId: tt.blockID,
   378  			})
   379  			if tt.wantErr {
   380  				require.NotEqual(t, err, nil)
   381  				return
   382  			}
   383  			require.NoError(t, err)
   384  
   385  			v1Block, err := migration.V1Alpha1ToV1Block(tt.want)
   386  			require.NoError(t, err)
   387  
   388  			if !reflect.DeepEqual(block.Data.Message, v1Block.Block) {
   389  				t.Error("Expected blocks to equal")
   390  			}
   391  		})
   392  	}
   393  }
   394  
   395  func TestServer_GetBlockSSZ(t *testing.T) {
   396  	beaconDB := dbTest.SetupDB(t)
   397  	ctx := context.Background()
   398  
   399  	_, blkContainers := fillDBTestBlocks(ctx, t, beaconDB)
   400  	headBlock := blkContainers[len(blkContainers)-1]
   401  
   402  	b2 := testutil.NewBeaconBlock()
   403  	b2.Block.Slot = 30
   404  	b2.Block.ParentRoot = bytesutil.PadTo([]byte{1}, 32)
   405  	require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b2)))
   406  
   407  	bs := &Server{
   408  		BeaconDB: beaconDB,
   409  		ChainInfoFetcher: &mock.ChainService{
   410  			DB:                  beaconDB,
   411  			Block:               wrapper.WrappedPhase0SignedBeaconBlock(headBlock.Block),
   412  			Root:                headBlock.BlockRoot,
   413  			FinalizedCheckPoint: &ethpb_alpha.Checkpoint{Root: blkContainers[64].BlockRoot},
   414  		},
   415  	}
   416  
   417  	ok, blocks, err := beaconDB.BlocksBySlot(ctx, 30)
   418  	require.Equal(t, true, ok)
   419  	require.NoError(t, err)
   420  	sszBlock, err := blocks[0].MarshalSSZ()
   421  	require.NoError(t, err)
   422  
   423  	resp, err := bs.GetBlockSSZ(ctx, &ethpb.BlockRequest{BlockId: []byte("30")})
   424  	require.NoError(t, err)
   425  	assert.NotNil(t, resp)
   426  	assert.DeepEqual(t, sszBlock, resp.Data)
   427  }
   428  
   429  func TestServer_GetBlockRoot(t *testing.T) {
   430  	beaconDB := dbTest.SetupDB(t)
   431  	ctx := context.Background()
   432  
   433  	genBlk, blkContainers := fillDBTestBlocks(ctx, t, beaconDB)
   434  	headBlock := blkContainers[len(blkContainers)-1]
   435  	b2 := testutil.NewBeaconBlock()
   436  	b2.Block.Slot = 30
   437  	b2.Block.ParentRoot = bytesutil.PadTo([]byte{1}, 32)
   438  	require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b2)))
   439  	b3 := testutil.NewBeaconBlock()
   440  	b3.Block.Slot = 30
   441  	b3.Block.ParentRoot = bytesutil.PadTo([]byte{4}, 32)
   442  	require.NoError(t, beaconDB.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(b3)))
   443  
   444  	bs := &Server{
   445  		BeaconDB: beaconDB,
   446  		ChainInfoFetcher: &mock.ChainService{
   447  			DB:                  beaconDB,
   448  			Block:               wrapper.WrappedPhase0SignedBeaconBlock(headBlock.Block),
   449  			Root:                headBlock.BlockRoot,
   450  			FinalizedCheckPoint: &ethpb_alpha.Checkpoint{Root: blkContainers[64].BlockRoot},
   451  		},
   452  	}
   453  
   454  	root, err := genBlk.Block.HashTreeRoot()
   455  	require.NoError(t, err)
   456  
   457  	tests := []struct {
   458  		name    string
   459  		blockID []byte
   460  		want    []byte
   461  		wantErr bool
   462  	}{
   463  		{
   464  			name:    "bad formatting",
   465  			blockID: []byte("3bad0"),
   466  			wantErr: true,
   467  		},
   468  		{
   469  			name:    "canonical slot",
   470  			blockID: []byte("30"),
   471  			want:    blkContainers[30].BlockRoot,
   472  		},
   473  		{
   474  			name:    "head",
   475  			blockID: []byte("head"),
   476  			want:    headBlock.BlockRoot,
   477  		},
   478  		{
   479  			name:    "finalized",
   480  			blockID: []byte("finalized"),
   481  			want:    blkContainers[64].BlockRoot,
   482  		},
   483  		{
   484  			name:    "genesis",
   485  			blockID: []byte("genesis"),
   486  			want:    root[:],
   487  		},
   488  		{
   489  			name:    "genesis root",
   490  			blockID: root[:],
   491  			want:    root[:],
   492  		},
   493  		{
   494  			name:    "root",
   495  			blockID: blkContainers[20].BlockRoot,
   496  			want:    blkContainers[20].BlockRoot,
   497  		},
   498  		{
   499  			name:    "non-existent root",
   500  			blockID: bytesutil.PadTo([]byte("hi there"), 32),
   501  			wantErr: true,
   502  		},
   503  		{
   504  			name:    "slot",
   505  			blockID: []byte("40"),
   506  			want:    blkContainers[40].BlockRoot,
   507  		},
   508  		{
   509  			name:    "no block",
   510  			blockID: []byte("105"),
   511  			wantErr: true,
   512  		},
   513  	}
   514  	for _, tt := range tests {
   515  		t.Run(tt.name, func(t *testing.T) {
   516  			blockRootResp, err := bs.GetBlockRoot(ctx, &ethpb.BlockRequest{
   517  				BlockId: tt.blockID,
   518  			})
   519  			if tt.wantErr {
   520  				require.NotEqual(t, err, nil)
   521  				return
   522  			}
   523  			require.NoError(t, err)
   524  			assert.DeepEqual(t, tt.want, blockRootResp.Data.Root)
   525  		})
   526  	}
   527  }
   528  
   529  func TestServer_ListBlockAttestations(t *testing.T) {
   530  	beaconDB := dbTest.SetupDB(t)
   531  	ctx := context.Background()
   532  
   533  	_, blkContainers := fillDBTestBlocks(ctx, t, beaconDB)
   534  	headBlock := blkContainers[len(blkContainers)-1]
   535  	bs := &Server{
   536  		BeaconDB: beaconDB,
   537  		ChainInfoFetcher: &mock.ChainService{
   538  			DB:                  beaconDB,
   539  			Block:               wrapper.WrappedPhase0SignedBeaconBlock(headBlock.Block),
   540  			Root:                headBlock.BlockRoot,
   541  			FinalizedCheckPoint: &ethpb_alpha.Checkpoint{Root: blkContainers[64].BlockRoot},
   542  		},
   543  	}
   544  
   545  	genBlk, blkContainers := fillDBTestBlocks(ctx, t, beaconDB)
   546  	root, err := genBlk.Block.HashTreeRoot()
   547  	require.NoError(t, err)
   548  
   549  	tests := []struct {
   550  		name    string
   551  		blockID []byte
   552  		want    *ethpb_alpha.SignedBeaconBlock
   553  		wantErr bool
   554  	}{
   555  		{
   556  			name:    "slot",
   557  			blockID: []byte("30"),
   558  			want:    blkContainers[30].Block,
   559  		},
   560  		{
   561  			name:    "bad formatting",
   562  			blockID: []byte("3bad0"),
   563  			wantErr: true,
   564  		},
   565  		{
   566  			name:    "head",
   567  			blockID: []byte("head"),
   568  			want:    headBlock.Block,
   569  		},
   570  		{
   571  			name:    "finalized",
   572  			blockID: []byte("finalized"),
   573  			want:    blkContainers[64].Block,
   574  		},
   575  		{
   576  			name:    "genesis",
   577  			blockID: []byte("genesis"),
   578  			want:    genBlk,
   579  		},
   580  		{
   581  			name:    "genesis root",
   582  			blockID: root[:],
   583  			want:    genBlk,
   584  		},
   585  		{
   586  			name:    "root",
   587  			blockID: blkContainers[20].BlockRoot,
   588  			want:    blkContainers[20].Block,
   589  		},
   590  		{
   591  			name:    "non-existent root",
   592  			blockID: bytesutil.PadTo([]byte("hi there"), 32),
   593  			wantErr: true,
   594  		},
   595  		{
   596  			name:    "slot",
   597  			blockID: []byte("40"),
   598  			want:    blkContainers[40].Block,
   599  		},
   600  		{
   601  			name:    "no block",
   602  			blockID: []byte("105"),
   603  			wantErr: true,
   604  		},
   605  	}
   606  	for _, tt := range tests {
   607  		t.Run(tt.name, func(t *testing.T) {
   608  			block, err := bs.ListBlockAttestations(ctx, &ethpb.BlockRequest{
   609  				BlockId: tt.blockID,
   610  			})
   611  			if tt.wantErr {
   612  				require.NotEqual(t, err, nil)
   613  				return
   614  			}
   615  			require.NoError(t, err)
   616  
   617  			v1Block, err := migration.V1Alpha1ToV1Block(tt.want)
   618  			require.NoError(t, err)
   619  
   620  			if !reflect.DeepEqual(block.Data, v1Block.Block.Body.Attestations) {
   621  				t.Error("Expected attestations to equal")
   622  			}
   623  		})
   624  	}
   625  }