multi: make AddPreimage variadic, optimistically compute key
In this commit, we modify the WitnessCache's AddPreimage method to accept a variadic number of preimages. This enables callers to batch preimage writes in performance critical areas of the codebase, e.g. the htlcswitch. Additionally, we lift the computation of the witnesses' keys outside of the db transaction. This saves us from having to do hashing inside and blocking other callers, and limits extraneous blocking at the call site.
This commit is contained in:
11 files changed
+95
-42
No files matched your search
+40
-12
@@ -70,12 +70,42 @@ func (d *DB) NewWitnessCache() *WitnessCache {
|
||||
}
|
||||
}
|
||||
|
||||
// AddWitness adds a new witness of wType to the witness cache. The type of the
|
||||
// witness will be used to map the witness to the key that will be used to look
|
||||
// it up.
|
||||
// witnessEntry is a key-value struct that holds each key -> witness pair, used
|
||||
// when inserting records into the cache.
|
||||
type witnessEntry struct {
|
||||
key []byte
|
||||
witness []byte
|
||||
}
|
||||
|
||||
// AddWitnesses adds a batch of new witnesses of wType to the witness cache. The
|
||||
// type of the witness will be used to map each witness to the key that will be
|
||||
// used to look it up. All witnesses should be of the same WitnessType.
|
||||
//
|
||||
// TODO(roasbeef): fake closure to map instead a constructor?
|
||||
func (w *WitnessCache) AddWitness(wType WitnessType, witness []byte) error {
|
||||
func (w *WitnessCache) AddWitnesses(wType WitnessType, witnesses ...[]byte) error {
|
||||
// Optimistically compute the witness keys before attempting to start
|
||||
// the db transaction.
|
||||
entries := make([]witnessEntry, 0, len(witnesses))
|
||||
for _, witness := range witnesses {
|
||||
// Map each witness to its key by applying the appropriate
|
||||
// transformation for the given witness type.
|
||||
switch wType {
|
||||
case Sha256HashWitness:
|
||||
key := sha256.Sum256(witness)
|
||||
entries = append(entries, witnessEntry{
|
||||
key: key[:],
|
||||
witness: witness,
|
||||
})
|
||||
default:
|
||||
return ErrUnknownWitnessType
|
||||
}
|
||||
}
|
||||
|
||||
// Exit early if there are no witnesses to add.
|
||||
if len(entries) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return w.db.Batch(func(tx *bbolt.Tx) error {
|
||||
witnessBucket, err := tx.CreateBucketIfNotExists(witnessBucketKey)
|
||||
if err != nil {
|
||||
@@ -93,16 +123,14 @@ func (w *WitnessCache) AddWitness(wType WitnessType, witness []byte) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Now that we have the proper bucket for this witness, we'll map the
|
||||
// witness type to the proper key.
|
||||
var witnessKey []byte
|
||||
switch wType {
|
||||
case Sha256HashWitness:
|
||||
key := sha256.Sum256(witness)
|
||||
witnessKey = key[:]
|
||||
for _, entry := range entries {
|
||||
err = witnessTypeBucket.Put(entry.key, entry.witness)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return witnessTypeBucket.Put(witnessKey, witness)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ func TestWitnessCacheRetrieval(t *testing.T) {
|
||||
witnessKey := sha256.Sum256(witness)
|
||||
|
||||
// First, we'll attempt to add the witness to the database.
|
||||
err = wCache.AddWitness(Sha256HashWitness, witness)
|
||||
err = wCache.AddWitnesses(Sha256HashWitness, witness)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to add witness: %v", err)
|
||||
}
|
||||
@@ -59,13 +59,13 @@ func TestWitnessCacheDeletion(t *testing.T) {
|
||||
// We'll start by adding two witnesses to the cache.
|
||||
witness1 := rev[:]
|
||||
witness1Key := sha256.Sum256(witness1)
|
||||
if err := wCache.AddWitness(Sha256HashWitness, witness1); err != nil {
|
||||
if err := wCache.AddWitnesses(Sha256HashWitness, witness1); err != nil {
|
||||
t.Fatalf("unable to add witness: %v", err)
|
||||
}
|
||||
|
||||
witness2 := key[:]
|
||||
witness2Key := sha256.Sum256(witness2)
|
||||
if err := wCache.AddWitness(Sha256HashWitness, witness2); err != nil {
|
||||
if err := wCache.AddWitnesses(Sha256HashWitness, witness2); err != nil {
|
||||
t.Fatalf("unable to add witness: %v", err)
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ func TestWitnessCacheUnknownWitness(t *testing.T) {
|
||||
|
||||
// We'll attempt to add a new, undefined witness type to the database.
|
||||
// We should get an error.
|
||||
err = wCache.AddWitness(234, key[:])
|
||||
err = wCache.AddWitnesses(234, key[:])
|
||||
if err != ErrUnknownWitnessType {
|
||||
t.Fatalf("expected ErrUnknownWitnessType, got %v", err)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user