Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Modify ReplayLog interface.
- Change parameter types for Get and Delete from []byte to *HashPrefix
- Return error on failing Get lookup
  • Loading branch information
Jim Posen committed Mar 26, 2018
1 parent c861375 commit eeb3c0a
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 58 deletions.
26 changes: 12 additions & 14 deletions decayedlog.go
Expand Up @@ -6,7 +6,6 @@ import (
"encoding/binary"
"errors"
"fmt"
"math"
"sync"
"sync/atomic"

Expand Down Expand Up @@ -66,9 +65,10 @@ type ReplayLog interface {
// Stop safely stops the on-disk persistent log.
Stop() error

// Get retrieves an entry from the persistent log given a []byte. It
// returns the value stored and an error if one occurs.
Get([]byte) (uint32, error)
// Get retrieves an entry from the persistent log given its hash prefix. It
// returns the value stored and an error if one occurs. Returns
// ErrLogEntryNotFound if hash prefix is not in the log.
Get(*HashPrefix) (uint32, error)

// Put stores an entry into the persistent log given a []byte and an
// accompanying purposefully general type. It returns an error if the
Expand All @@ -78,8 +78,8 @@ type ReplayLog interface {
// PutBatch stores
PutBatch(*Batch) (*ReplaySet, error)

// Delete deletes an entry from the persistent log given []byte
Delete([]byte) error
// Delete deletes an entry from the persistent log given its hash prefix.
Delete(*HashPrefix) error
}

// DecayedLog implements the PersistLog interface. It stores the first
Expand Down Expand Up @@ -298,23 +298,21 @@ func hashSharedSecret(sharedSecret *Hash256) HashPrefix {

// Delete removes a <shared secret hash, CLTV> key-pair from the
// sharedHashBucket.
func (d *DecayedLog) Delete(hash []byte) error {
func (d *DecayedLog) Delete(hash *HashPrefix) error {
return d.db.Batch(func(tx *bolt.Tx) error {
sharedHashes := tx.Bucket(sharedHashBucket)
if sharedHashes == nil {
return ErrDecayedLogCorrupted
}

return sharedHashes.Delete(hash)
return sharedHashes.Delete(hash[:])
})
}

// Get retrieves the CLTV of a processed HTLC given the first 20 bytes of the
// Sha-256 hash of the shared secret.
func (d *DecayedLog) Get(hash []byte) (uint32, error) {
// math.MaxUint32 is returned when Get did not retrieve a value.
// This was chosen because it's not feasible for a CLTV to be this high.
var value uint32 = math.MaxUint32
func (d *DecayedLog) Get(hash *HashPrefix) (uint32, error) {
var value uint32

err := d.db.View(func(tx *bolt.Tx) error {
// Grab the shared hash bucket which stores the mapping from
Expand All @@ -326,9 +324,9 @@ func (d *DecayedLog) Get(hash []byte) (uint32, error) {
}

// Retrieve the bytes which represents the CLTV
valueBytes := sharedHashes.Get(hash)
valueBytes := sharedHashes.Get(hash[:])
if valueBytes == nil {
return nil
return ErrLogEntryNotFound
}

// The first 4 bytes represent the CLTV, store it in value.
Expand Down
75 changes: 34 additions & 41 deletions decayedlog_test.go
@@ -1,7 +1,6 @@
package sphinx

import (
"math"
"testing"
"time"

Expand Down Expand Up @@ -56,7 +55,7 @@ func (m *mockNotifier) Stop() error {
}

// startup sets up the DecayedLog and possibly the garbage collector.
func startup(notifier bool) (ReplayLog, *mockNotifier, HashPrefix, error) {
func startup(notifier bool) (ReplayLog, *mockNotifier, *HashPrefix, error) {
var log ReplayLog
var chainNotifier *mockNotifier
var hashedSecret HashPrefix
Expand All @@ -77,13 +76,13 @@ func startup(notifier bool) (ReplayLog, *mockNotifier, HashPrefix, error) {
// Open the channeldb (start the garbage collector)
err := log.Start()
if err != nil {
return nil, nil, hashedSecret, err
return nil, nil, nil, err
}

// Create a new private key on elliptic curve secp256k1
priv, err := btcec.NewPrivateKey(btcec.S256())
if err != nil {
return nil, nil, hashedSecret, err
return nil, nil, nil, err
}

// Generate a public key from the key bytes
Expand All @@ -97,7 +96,7 @@ func startup(notifier bool) (ReplayLog, *mockNotifier, HashPrefix, error) {
// This is used as a key to retrieve the cltv value.
hashedSecret = hashSharedSecret(&secret)

return log, chainNotifier, hashedSecret, nil
return log, chainNotifier, &hashedSecret, nil
}

// TestDecayedLogGarbageCollector tests the ability of the garbage collector
Expand All @@ -111,7 +110,7 @@ func TestDecayedLogGarbageCollector(t *testing.T) {
defer shutdown("tempdir", d)

// Store <hashedSecret, cltv> in the sharedHashBucket.
err = d.Put(&hashedSecret, cltv)
err = d.Put(hashedSecret, cltv)
if err != nil {
t.Fatalf("Unable to store in channeldb: %v", err)
}
Expand All @@ -128,7 +127,7 @@ func TestDecayedLogGarbageCollector(t *testing.T) {
}

// Assert that hashedSecret is still in the sharedHashBucket
val, err := d.Get(hashedSecret[:])
val, err := d.Get(hashedSecret)
if err != nil {
t.Fatalf("Get failed - received an error upon Get: %v", err)
}
Expand All @@ -146,14 +145,13 @@ func TestDecayedLogGarbageCollector(t *testing.T) {
time.Sleep(500 * time.Millisecond)

// Assert that hashedSecret is not in the sharedHashBucket
val, err = d.Get(hashedSecret[:])
if err != nil {
t.Fatalf("Get failed - received an error upon Get: %v", err)
}

if val != math.MaxUint32 {
val, err = d.Get(hashedSecret)
if err == nil {
t.Fatalf("CLTV was not deleted")
}
if err != ErrLogEntryNotFound {
t.Fatalf("Get failed - received unexpected error upon Get: %v", err)
}
}

// TestDecayedLogPersistentGarbageCollector tests the persistence property of
Expand All @@ -169,7 +167,7 @@ func TestDecayedLogPersistentGarbageCollector(t *testing.T) {
defer shutdown("tempdir", d)

// Store <hashedSecret, cltv> in the sharedHashBucket
if err = d.Put(&hashedSecret, cltv); err != nil {
if err = d.Put(hashedSecret, cltv); err != nil {
t.Fatalf("Unable to store in channeldb: %v", err)
}

Expand All @@ -195,13 +193,12 @@ func TestDecayedLogPersistentGarbageCollector(t *testing.T) {
time.Sleep(500 * time.Millisecond)

// Assert that hashedSecret is not in the sharedHashBucket
val, err := d2.Get(hashedSecret2[:])
if err != nil {
t.Fatalf("Delete failed - received an error upon Get: %v", err)
_, err = d2.Get(hashedSecret2)
if err == nil {
t.Fatalf("CLTV was not deleted")
}

if val != math.MaxUint32 {
t.Fatalf("cltv was not deleted")
if err != ErrLogEntryNotFound {
t.Fatalf("Get failed - received unexpected error upon Get: %v", err)
}
}

Expand All @@ -216,27 +213,25 @@ func TestDecayedLogInsertionAndDeletion(t *testing.T) {
defer shutdown("tempdir", d)

// Store <hashedSecret, cltv> in the sharedHashBucket.
err = d.Put(&hashedSecret, cltv)
err = d.Put(hashedSecret, cltv)
if err != nil {
t.Fatalf("Unable to store in channeldb: %v", err)
}

// Delete hashedSecret from the sharedHashBucket.
err = d.Delete(hashedSecret[:])
err = d.Delete(hashedSecret)
if err != nil {
t.Fatalf("Unable to delete from channeldb: %v", err)
}

// Assert that hashedSecret is not in the sharedHashBucket
val, err := d.Get(hashedSecret[:])
if err != nil {
t.Fatalf("Delete failed - received the wrong error message: %v", err)
_, err = d.Get(hashedSecret)
if err == nil {
t.Fatalf("CLTV was not deleted")
}

if val != math.MaxUint32 {
t.Fatalf("cltv was not deleted")
if err != ErrLogEntryNotFound {
t.Fatalf("Get failed - received unexpected error upon Get: %v", err)
}

}

// TestDecayedLogStartAndStop tests for persistence. The DecayedLog is started,
Expand All @@ -252,7 +247,7 @@ func TestDecayedLogStartAndStop(t *testing.T) {
defer shutdown("tempdir", d)

// Store <hashedSecret, cltv> in the sharedHashBucket.
err = d.Put(&hashedSecret, cltv)
err = d.Put(hashedSecret, cltv)
if err != nil {
t.Fatalf("Unable to store in channeldb: %v", err)
}
Expand All @@ -267,7 +262,7 @@ func TestDecayedLogStartAndStop(t *testing.T) {
defer shutdown("tempdir", d2)

// Retrieve the stored cltv value given the hashedSecret key.
value, err := d2.Get(hashedSecret[:])
value, err := d2.Get(hashedSecret)
if err != nil {
t.Fatalf("Unable to retrieve from channeldb: %v", err)
}
Expand All @@ -279,7 +274,7 @@ func TestDecayedLogStartAndStop(t *testing.T) {
}

// Delete hashedSecret from sharedHashBucket
err = d2.Delete(hashedSecret2[:])
err = d2.Delete(hashedSecret2)
if err != nil {
t.Fatalf("Unable to delete from channeldb: %v", err)
}
Expand All @@ -294,15 +289,13 @@ func TestDecayedLogStartAndStop(t *testing.T) {
defer shutdown("tempdir", d3)

// Assert that hashedSecret is not in the sharedHashBucket
val, err := d3.Get(hashedSecret3[:])
if err != nil {
t.Fatalf("Delete failed: %v", err)
_, err = d3.Get(hashedSecret3)
if err == nil {
t.Fatalf("CLTV was not deleted")
}

if val != math.MaxUint32 {
t.Fatalf("cltv was not deleted")
if err != ErrLogEntryNotFound {
t.Fatalf("Get failed - received unexpected error upon Get: %v", err)
}

}

// TestDecayedLogStorageAndRetrieval stores a cltv value and then retrieves it
Expand All @@ -316,13 +309,13 @@ func TestDecayedLogStorageAndRetrieval(t *testing.T) {
defer shutdown("tempdir", d)

// Store <hashedSecret, cltv> in the sharedHashBucket
err = d.Put(&hashedSecret, cltv)
err = d.Put(hashedSecret, cltv)
if err != nil {
t.Fatalf("Unable to store in channeldb: %v", err)
}

// Retrieve the stored cltv value given the hashedSecret key.
value, err := d.Get(hashedSecret[:])
value, err := d.Get(hashedSecret)
if err != nil {
t.Fatalf("Unable to retrieve from channeldb: %v", err)
}
Expand Down
6 changes: 5 additions & 1 deletion error.go
Expand Up @@ -14,10 +14,14 @@ var (

// ErrInvalidOnionHMAC is returned during onion parsing process, when received
// mac does not corresponds to the generated one.
ErrInvalidOnionHMAC = fmt.Errorf("invalid mismathed mac")
ErrInvalidOnionHMAC = fmt.Errorf("invalid mismatched mac")

// ErrInvalidOnionKey is returned during onion parsing process, when
// onion key is invalid.
ErrInvalidOnionKey = fmt.Errorf("invalid onion key: pubkey isn't on " +
"secp256k1 curve")

// ErrLogEntryNotFound is an error returned when a packet lookup in a replay
// log fails because it is missing.
ErrLogEntryNotFound = fmt.Errorf("sphinx packet is not in log")
)
3 changes: 1 addition & 2 deletions sphinx_test.go
Expand Up @@ -138,8 +138,7 @@ func TestBolt4Packet(t *testing.T) {
for i, pubKeyHex := range bolt4PubKeys {
pubKeyBytes, err := hex.DecodeString(pubKeyHex)
if err != nil {
t.Fatalf("unable to decode BOLT 4 hex pubkey #%d: %v",
i, err)
t.Fatalf("unable to decode BOLT 4 hex pubkey #%d: %v", i, err)
}

route[i], err = btcec.ParsePubKey(pubKeyBytes, btcec.S256())
Expand Down

0 comments on commit eeb3c0a

Please sign in to comment.