Skip to content

Commit e15d92d

Browse files
authored
Apply fixes to block slots methods in DB (#5194)
* Apply fixes * Typo * Merge refs/heads/master into fix-slots-saved-for-blocks
1 parent 729bd83 commit e15d92d

File tree

3 files changed

+38
-25
lines changed

3 files changed

+38
-25
lines changed

beacon-chain/db/kv/blocks.go

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"context"
66
"fmt"
7+
"math"
78
"strconv"
89

910
"github.com/pkg/errors"
@@ -302,9 +303,9 @@ func (k *Store) SaveGenesisBlockRoot(ctx context.Context, blockRoot [32]byte) er
302303
})
303304
}
304305

305-
// HighestSlotBlock returns the block with the highest slot from the db.
306-
func (k *Store) HighestSlotBlock(ctx context.Context) (*ethpb.SignedBeaconBlock, error) {
307-
ctx, span := trace.StartSpan(ctx, "BeaconDB.HighestSlotBlock")
306+
// HighestSlotBlocks returns the blocks with the highest slot from the db.
307+
func (k *Store) HighestSlotBlocks(ctx context.Context) ([]*ethpb.SignedBeaconBlock, error) {
308+
ctx, span := trace.StartSpan(ctx, "BeaconDB.HighestSlotBlocks")
308309
defer span.End()
309310

310311
blocks := make([]*ethpb.SignedBeaconBlock, 0)
@@ -316,6 +317,7 @@ func (k *Store) HighestSlotBlock(ctx context.Context) (*ethpb.SignedBeaconBlock,
316317
return err
317318
}
318319
highestSlot := highestIndex - 1
320+
highestSlot = int(math.Max(0, float64(highestSlot)))
319321
f := filters.NewFilter().SetStartSlot(uint64(highestSlot)).SetEndSlot(uint64(highestSlot))
320322

321323
keys, err := getBlockRootsByFilter(ctx, tx, f)
@@ -335,11 +337,7 @@ func (k *Store) HighestSlotBlock(ctx context.Context) (*ethpb.SignedBeaconBlock,
335337
return nil
336338
})
337339

338-
if len(blocks) != 1 {
339-
return nil, errors.New("no highest slot block saved")
340-
}
341-
342-
return blocks[0], err
340+
return blocks, err
343341
}
344342

345343
// setBlockSlotBitField sets the block slot bit in DB.
@@ -348,10 +346,17 @@ func (k *Store) setBlockSlotBitField(ctx context.Context, tx *bolt.Tx, slot uint
348346
ctx, span := trace.StartSpan(ctx, "BeaconDB.setBlockSlotBitField")
349347
defer span.End()
350348

349+
k.blockSlotBitLock.Lock()
350+
defer k.blockSlotBitLock.Unlock()
351+
351352
bucket := tx.Bucket(slotsHasObjectBucket)
352353
slotBitfields := bucket.Get(savedBlockSlotsKey)
354+
355+
// Copy is needed to avoid unsafe pointer conversions.
356+
// See: https://github.com/etcd-io/bbolt/pull/201
353357
tmp := make([]byte, len(slotBitfields))
354358
copy(tmp, slotBitfields)
359+
355360
slotBitfields = bytesutil.SetBit(tmp, int(slot))
356361
return bucket.Put(savedBlockSlotsKey, slotBitfields)
357362
}
@@ -362,10 +367,17 @@ func (k *Store) clearBlockSlotBitField(ctx context.Context, tx *bolt.Tx, slot ui
362367
ctx, span := trace.StartSpan(ctx, "BeaconDB.clearBlockSlotBitField")
363368
defer span.End()
364369

370+
k.blockSlotBitLock.Lock()
371+
defer k.blockSlotBitLock.Unlock()
372+
365373
bucket := tx.Bucket(slotsHasObjectBucket)
366374
slotBitfields := bucket.Get(savedBlockSlotsKey)
375+
376+
// Copy is needed to avoid unsafe pointer conversions.
377+
// See: https://github.com/etcd-io/bbolt/pull/201
367378
tmp := make([]byte, len(slotBitfields))
368379
copy(tmp, slotBitfields)
380+
369381
slotBitfields = bytesutil.ClearBit(tmp, int(slot))
370382
return bucket.Put(savedBlockSlotsKey, slotBitfields)
371383
}

beacon-chain/db/kv/blocks_test.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -429,35 +429,35 @@ func TestStore_SaveBlock_CanGetHighest(t *testing.T) {
429429
if err := db.SaveBlock(ctx, block); err != nil {
430430
t.Fatal(err)
431431
}
432-
highestSavedBlock, err := db.HighestSlotBlock(ctx)
432+
highestSavedBlock, err := db.HighestSlotBlocks(ctx)
433433
if err != nil {
434434
t.Fatal(err)
435435
}
436-
if !proto.Equal(block, highestSavedBlock) {
436+
if !proto.Equal(block, highestSavedBlock[0]) {
437437
t.Errorf("Wanted %v, received %v", block, highestSavedBlock)
438438
}
439439

440440
block = &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 999}}
441441
if err := db.SaveBlock(ctx, block); err != nil {
442442
t.Fatal(err)
443443
}
444-
highestSavedBlock, err = db.HighestSlotBlock(ctx)
444+
highestSavedBlock, err = db.HighestSlotBlocks(ctx)
445445
if err != nil {
446446
t.Fatal(err)
447447
}
448-
if !proto.Equal(block, highestSavedBlock) {
448+
if !proto.Equal(block, highestSavedBlock[0]) {
449449
t.Errorf("Wanted %v, received %v", block, highestSavedBlock)
450450
}
451451

452452
block = &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: 300000000}} // 100 years.
453453
if err := db.SaveBlock(ctx, block); err != nil {
454454
t.Fatal(err)
455455
}
456-
highestSavedBlock, err = db.HighestSlotBlock(ctx)
456+
highestSavedBlock, err = db.HighestSlotBlocks(ctx)
457457
if err != nil {
458458
t.Fatal(err)
459459
}
460-
if !proto.Equal(block, highestSavedBlock) {
460+
if !proto.Equal(block, highestSavedBlock[0]) {
461461
t.Errorf("Wanted %v, received %v", block, highestSavedBlock)
462462
}
463463
}
@@ -480,11 +480,11 @@ func TestStore_SaveBlocks_CanGetHighest(t *testing.T) {
480480
if err := db.SaveBlocks(ctx, b); err != nil {
481481
t.Fatal(err)
482482
}
483-
highestSavedBlock, err := db.HighestSlotBlock(ctx)
483+
highestSavedBlock, err := db.HighestSlotBlocks(ctx)
484484
if err != nil {
485485
t.Fatal(err)
486486
}
487-
if !proto.Equal(b[len(b)-1], highestSavedBlock) {
487+
if !proto.Equal(b[len(b)-1], highestSavedBlock[0]) {
488488
t.Errorf("Wanted %v, received %v", b[len(b)-1], highestSavedBlock)
489489
}
490490
}
@@ -498,11 +498,11 @@ func TestStore_DeleteBlock_CanGetHighest(t *testing.T) {
498498
if err := db.SaveBlock(ctx, b50); err != nil {
499499
t.Fatal(err)
500500
}
501-
highestSavedBlock, err := db.HighestSlotBlock(ctx)
501+
highestSavedBlock, err := db.HighestSlotBlocks(ctx)
502502
if err != nil {
503503
t.Fatal(err)
504504
}
505-
if !proto.Equal(b50, highestSavedBlock) {
505+
if !proto.Equal(b50, highestSavedBlock[0]) {
506506
t.Errorf("Wanted %v, received %v", b50, highestSavedBlock)
507507
}
508508

@@ -512,22 +512,22 @@ func TestStore_DeleteBlock_CanGetHighest(t *testing.T) {
512512
t.Fatal(err)
513513
}
514514

515-
highestSavedBlock, err = db.HighestSlotBlock(ctx)
515+
highestSavedBlock, err = db.HighestSlotBlocks(ctx)
516516
if err != nil {
517517
t.Fatal(err)
518518
}
519-
if !proto.Equal(b51, highestSavedBlock) {
519+
if !proto.Equal(b51, highestSavedBlock[0]) {
520520
t.Errorf("Wanted %v, received %v", b51, highestSavedBlock)
521521
}
522522

523523
if err := db.DeleteBlock(ctx, r51); err != nil {
524524
t.Fatal(err)
525525
}
526-
highestSavedBlock, err = db.HighestSlotBlock(ctx)
526+
highestSavedBlock, err = db.HighestSlotBlocks(ctx)
527527
if err != nil {
528528
t.Fatal(err)
529529
}
530-
if !proto.Equal(b50, highestSavedBlock) {
530+
if !proto.Equal(b50, highestSavedBlock[0]) {
531531
t.Errorf("Wanted %v, received %v", b50, highestSavedBlock)
532532
}
533533
}
@@ -555,11 +555,11 @@ func TestStore_DeleteBlocks_CanGetHighest(t *testing.T) {
555555
if err := db.DeleteBlocks(ctx, [][32]byte{r[99], r[98], r[97]}); err != nil {
556556
t.Fatal(err)
557557
}
558-
highestSavedBlock, err := db.HighestSlotBlock(ctx)
558+
highestSavedBlock, err := db.HighestSlotBlocks(ctx)
559559
if err != nil {
560560
t.Fatal(err)
561561
}
562-
if !proto.Equal(b[96], highestSavedBlock) {
562+
if !proto.Equal(b[96], highestSavedBlock[0]) {
563563
t.Errorf("Wanted %v, received %v", b[len(b)-1], highestSavedBlock)
564564
}
565565
}

beacon-chain/db/kv/kv.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"github.com/dgraph-io/ristretto"
1010
"github.com/pkg/errors"
1111
"github.com/prometheus/client_golang/prometheus"
12-
"github.com/prysmaticlabs/prombbolt"
12+
prombolt "github.com/prysmaticlabs/prombbolt"
1313
"github.com/prysmaticlabs/prysm/beacon-chain/db/iface"
1414
bolt "go.etcd.io/bbolt"
1515
)
@@ -37,6 +37,7 @@ type Store struct {
3737
blockCache *ristretto.Cache
3838
validatorIndexCache *ristretto.Cache
3939
stateSlotBitLock sync.Mutex
40+
blockSlotBitLock sync.Mutex
4041
}
4142

4243
// NewKVStore initializes a new boltDB key-value store at the directory

0 commit comments

Comments
 (0)