diff --git a/blockstore/badger/blockstore.go b/blockstore/badger/blockstore.go index 5527bf89076..90f9bbfcbab 100644 --- a/blockstore/badger/blockstore.go +++ b/blockstore/badger/blockstore.go @@ -732,6 +732,20 @@ func (b *Blockstore) Put(ctx context.Context, block blocks.Block) error { } put := func(db *badger.DB) error { + // Check if we have it before writing it. + switch err := db.View(func(txn *badger.Txn) error { + _, err := txn.Get(k) + return err + }); err { + case badger.ErrKeyNotFound: + case nil: + // Already exists, skip the put. + return nil + default: + return err + } + + // Then write it. err := db.Update(func(txn *badger.Txn) error { return txn.Set(k, block.RawData()) }) @@ -787,12 +801,33 @@ func (b *Blockstore) PutMany(ctx context.Context, blocks []blocks.Block) error { keys = append(keys, k) } + err := b.db.View(func(txn *badger.Txn) error { + for i, k := range keys { + switch _, err := txn.Get(k); err { + case badger.ErrKeyNotFound: + case nil: + keys[i] = nil + default: + // Something is actually wrong + return err + } + } + return nil + }) + if err != nil { + return err + } + put := func(db *badger.DB) error { batch := db.NewWriteBatch() defer batch.Cancel() for i, block := range blocks { k := keys[i] + if k == nil { + // skipped because we already have it. + continue + } if err := batch.Set(k, block.RawData()); err != nil { return err }