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:
Conner Fromknecht committed 2019-02-19 17:05:04 -08:00
1 parent 81783a60dc
commit 30f61b7630
11 files changed
+95 -42

No files matched your search

+40 -12
View File
@@ -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
})
}
+4 -4
View File
@@ -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)
}