watchtower/multi: move BreachHint to blob pkg

This commit is contained in:
Conner Fromknecht 2019-06-13 17:26:26 -07:00
parent 8e6b903476
commit 1b89ba1782
No known key found for this signature in database
GPG Key ID: E7D737B67FA592C7
15 changed files with 56 additions and 47 deletions

@ -1,4 +1,4 @@
package wtdb
package blob
import (
"encoding/hex"

@ -4,6 +4,7 @@ import (
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/watchtower/blob"
"github.com/lightningnetwork/lnd/watchtower/wtdb"
)
@ -37,7 +38,7 @@ type DB interface {
// QueryMatches searches its database for any state updates matching the
// provided breach hints. If any matches are found, they will be
// returned along with encrypted blobs so that justice can be exacted.
QueryMatches([]wtdb.BreachHint) ([]wtdb.Match, error)
QueryMatches([]blob.BreachHint) ([]wtdb.Match, error)
// SetLookoutTip writes the best epoch for which the watchtower has
// queried for breach hints.

@ -7,7 +7,6 @@ import (
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/watchtower/blob"
"github.com/lightningnetwork/lnd/watchtower/wtdb"
)
// Config houses the Lookout's required resources to properly fulfill it's duty,
@ -159,11 +158,11 @@ func (l *Lookout) processEpoch(epoch *chainntnfs.BlockEpoch,
// Iterate over the transactions contained in the block, deriving a
// breach hint for each transaction and constructing an index mapping
// the hint back to it's original transaction.
hintToTx := make(map[wtdb.BreachHint]*wire.MsgTx, numTxnsInBlock)
txHints := make([]wtdb.BreachHint, 0, numTxnsInBlock)
hintToTx := make(map[blob.BreachHint]*wire.MsgTx, numTxnsInBlock)
txHints := make([]blob.BreachHint, 0, numTxnsInBlock)
for _, tx := range block.Transactions {
hash := tx.TxHash()
hint := wtdb.NewBreachHintFromHash(&hash)
hint := blob.NewBreachHintFromHash(&hash)
txHints = append(txHints, hint)
hintToTx[hint] = tx

@ -163,13 +163,13 @@ func TestLookoutBreachMatching(t *testing.T) {
// Add both state updates to the tower's database.
txBlob1 := &wtdb.SessionStateUpdate{
ID: makeArray33(1),
Hint: wtdb.NewBreachHintFromHash(&hash1),
Hint: blob.NewBreachHintFromHash(&hash1),
EncryptedBlob: encBlob1,
SeqNum: 1,
}
txBlob2 := &wtdb.SessionStateUpdate{
ID: makeArray33(2),
Hint: wtdb.NewBreachHintFromHash(&hash2),
Hint: blob.NewBreachHintFromHash(&hash2),
EncryptedBlob: encBlob2,
SeqNum: 1,
}

@ -173,9 +173,9 @@ func (t *backupTask) bindSession(session *wtdb.ClientSessionBody) error {
// required pieces from signatures, witness scripts, etc are then packaged into
// a JusticeKit and encrypted using the breach transaction's key.
func (t *backupTask) craftSessionPayload(
signer input.Signer) (wtdb.BreachHint, []byte, error) {
signer input.Signer) (blob.BreachHint, []byte, error) {
var hint wtdb.BreachHint
var hint blob.BreachHint
// First, copy over the sweep pkscript, the pubkeys used to derive the
// to-local script, and the remote CSV delay.
@ -290,7 +290,7 @@ func (t *backupTask) craftSessionPayload(
// Finally, compute the breach hint, taken as the first half of the
// breach transactions txid. Once the tower sees the breach transaction
// on the network, it can use the full txid to decyrpt the blob.
hint = wtdb.NewBreachHintFromHash(&breachKey)
hint = blob.NewBreachHintFromHash(&breachKey)
return hint, encBlob, nil
}

@ -516,7 +516,7 @@ func testBackupTask(t *testing.T, test backupTaskTest) {
// Verify that the breach hint matches the breach txid's prefix.
breachTxID := test.breachInfo.BreachTransaction.TxHash()
expHint := wtdb.NewBreachHintFromHash(&breachTxID)
expHint := blob.NewBreachHintFromHash(&breachTxID)
if hint != expHint {
t.Fatalf("breach hint mismatch, want: %x, got: %v",
expHint, hint)

@ -576,17 +576,17 @@ func (h *testHarness) registerChannel(id uint64) {
// advanceChannelN calls advanceState on the channel identified by id the number
// of provided times and returns the breach hints corresponding to the new
// states.
func (h *testHarness) advanceChannelN(id uint64, n int) []wtdb.BreachHint {
func (h *testHarness) advanceChannelN(id uint64, n int) []blob.BreachHint {
h.t.Helper()
channel := h.channel(id)
var hints []wtdb.BreachHint
var hints []blob.BreachHint
for i := uint64(0); i < uint64(n); i++ {
channel.advanceState(h.t)
commitTx, _ := h.channel(id).getState(i)
breachTxID := commitTx.TxHash()
hints = append(hints, wtdb.NewBreachHintFromHash(&breachTxID))
hints = append(hints, blob.NewBreachHintFromHash(&breachTxID))
}
return hints
@ -621,18 +621,18 @@ func (h *testHarness) backupState(id, i uint64, expErr error) {
// party for each state in from-to times and returns the breach hints for states
// [from, to).
func (h *testHarness) sendPayments(id, from, to uint64,
amt lnwire.MilliSatoshi) []wtdb.BreachHint {
amt lnwire.MilliSatoshi) []blob.BreachHint {
h.t.Helper()
channel := h.channel(id)
var hints []wtdb.BreachHint
var hints []blob.BreachHint
for i := from; i < to; i++ {
h.channel(id).sendPayment(h.t, amt)
commitTx, _ := channel.getState(i)
breachTxID := commitTx.TxHash()
hints = append(hints, wtdb.NewBreachHintFromHash(&breachTxID))
hints = append(hints, blob.NewBreachHintFromHash(&breachTxID))
}
return hints
@ -642,18 +642,18 @@ func (h *testHarness) sendPayments(id, from, to uint64,
// remote party for each state in from-to times and returns the breach hints for
// states [from, to).
func (h *testHarness) recvPayments(id, from, to uint64,
amt lnwire.MilliSatoshi) []wtdb.BreachHint {
amt lnwire.MilliSatoshi) []blob.BreachHint {
h.t.Helper()
channel := h.channel(id)
var hints []wtdb.BreachHint
var hints []blob.BreachHint
for i := from; i < to; i++ {
channel.receivePayment(h.t, amt)
commitTx, _ := channel.getState(i)
breachTxID := commitTx.TxHash()
hints = append(hints, wtdb.NewBreachHintFromHash(&breachTxID))
hints = append(hints, blob.NewBreachHintFromHash(&breachTxID))
}
return hints
@ -662,7 +662,7 @@ func (h *testHarness) recvPayments(id, from, to uint64,
// waitServerUpdates blocks until the breach hints provided all appear in the
// watchtower's database or the timeout expires. This is used to test that the
// client in fact sends the updates to the server, even if it is offline.
func (h *testHarness) waitServerUpdates(hints []wtdb.BreachHint,
func (h *testHarness) waitServerUpdates(hints []blob.BreachHint,
timeout time.Duration) {
h.t.Helper()
@ -671,7 +671,7 @@ func (h *testHarness) waitServerUpdates(hints []wtdb.BreachHint,
// assert that no updates appear.
wantUpdates := len(hints) > 0
hintSet := make(map[wtdb.BreachHint]struct{})
hintSet := make(map[blob.BreachHint]struct{})
for _, hint := range hints {
hintSet[hint] = struct{}{}
}
@ -737,7 +737,7 @@ func (h *testHarness) waitServerUpdates(hints []wtdb.BreachHint,
// assertUpdatesForPolicy queries the server db for matches using the provided
// breach hints, then asserts that each match has a session with the expected
// policy.
func (h *testHarness) assertUpdatesForPolicy(hints []wtdb.BreachHint,
func (h *testHarness) assertUpdatesForPolicy(hints []blob.BreachHint,
expPolicy wtpolicy.Policy) {
// Query for matches on the provided hints.
@ -1113,7 +1113,7 @@ var clientTests = []clientTest{
// Generate the retributions for all 10 channels and
// collect the breach hints.
var hints []wtdb.BreachHint
var hints []blob.BreachHint
for id := uint64(0); id < 10; id++ {
chanHints := h.advanceChannelN(id, numUpdates)
hints = append(hints, chanHints...)

@ -664,7 +664,7 @@ func randCommittedUpdate(t *testing.T, seqNum uint16) *wtdb.CommittedUpdate {
t.Fatalf("unable to generate chan id: %v", err)
}
var hint wtdb.BreachHint
var hint blob.BreachHint
if _, err := io.ReadFull(crand.Reader, hint[:]); err != nil {
t.Fatalf("unable to generate breach hint: %v", err)
}

@ -5,6 +5,7 @@ import (
"github.com/btcsuite/btcd/btcec"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/watchtower/blob"
"github.com/lightningnetwork/lnd/watchtower/wtpolicy"
)
@ -178,7 +179,7 @@ type CommittedUpdateBody struct {
BackupID BackupID
// Hint is the 16-byte prefix of the revoked commitment transaction ID.
Hint BreachHint
Hint blob.BreachHint
// EncryptedBlob is a ciphertext containing the sweep information for
// exacting justice if the commitment transaction matching the breach

@ -36,7 +36,7 @@ func ReadElement(r io.Reader, element interface{}) error {
return err
}
case *BreachHint:
case *blob.BreachHint:
if _, err := io.ReadFull(r, e[:]); err != nil {
return err
}
@ -94,7 +94,7 @@ func WriteElement(w io.Writer, element interface{}) error {
return err
}
case BreachHint:
case blob.BreachHint:
if _, err := w.Write(e[:]); err != nil {
return err
}

@ -4,6 +4,7 @@ import (
"errors"
"io"
"github.com/lightningnetwork/lnd/watchtower/blob"
"github.com/lightningnetwork/lnd/watchtower/wtpolicy"
)
@ -134,7 +135,7 @@ type Match struct {
SeqNum uint16
// Hint is the breach hint that triggered the match.
Hint BreachHint
Hint blob.BreachHint
// EncryptedBlob is the encrypted payload containing the justice kit
// uploaded by the client.

@ -1,6 +1,10 @@
package wtdb
import "io"
import (
"io"
"github.com/lightningnetwork/lnd/watchtower/blob"
)
// SessionStateUpdate holds a state update sent by a client along with its
// SessionID.
@ -16,7 +20,7 @@ type SessionStateUpdate struct {
LastApplied uint16
// Hint is the 16-byte prefix of the revoked commitment transaction.
Hint BreachHint
Hint blob.BreachHint
// EncryptedBlob is a ciphertext containing the sweep information for
// exacting justice if the commitment transaction matching the breach

@ -7,6 +7,7 @@ import (
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/coreos/bbolt"
"github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/watchtower/blob"
)
const (
@ -369,7 +370,7 @@ func (t *TowerDB) DeleteSession(target SessionID) error {
// QueryMatches searches against all known state updates for any that match the
// passed breachHints. More than one Match will be returned for a given hint if
// they exist in the database.
func (t *TowerDB) QueryMatches(breachHints []BreachHint) ([]Match, error) {
func (t *TowerDB) QueryMatches(breachHints []blob.BreachHint) ([]Match, error) {
var matches []Match
err := t.db.View(func(tx *bbolt.Tx) error {
sessions := tx.Bucket(sessionsBkt)
@ -534,20 +535,20 @@ func removeSessionHintBkt(updateIndex *bbolt.Bucket, id *SessionID) error {
// If the index for the session has not been initialized, this method returns
// ErrNoSessionHintIndex.
func getHintsForSession(updateIndex *bbolt.Bucket,
id *SessionID) ([]BreachHint, error) {
id *SessionID) ([]blob.BreachHint, error) {
sessionHints := updateIndex.Bucket(id[:])
if sessionHints == nil {
return nil, ErrNoSessionHintIndex
}
var hints []BreachHint
var hints []blob.BreachHint
err := sessionHints.ForEach(func(k, _ []byte) error {
if len(k) != BreachHintSize {
if len(k) != blob.BreachHintSize {
return nil
}
var hint BreachHint
var hint blob.BreachHint
copy(hint[:], k)
hints = append(hints, hint)
return nil
@ -565,7 +566,7 @@ func getHintsForSession(updateIndex *bbolt.Bucket,
// for the session has not been initialized, this method returns
// ErrNoSessionHintIndex.
func putHintForSession(updateIndex *bbolt.Bucket, id *SessionID,
hint BreachHint) error {
hint blob.BreachHint) error {
sessionHints := updateIndex.Bucket(id[:])
if sessionHints == nil {

@ -10,6 +10,7 @@ import (
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/watchtower"
"github.com/lightningnetwork/lnd/watchtower/blob"
"github.com/lightningnetwork/lnd/watchtower/wtdb"
"github.com/lightningnetwork/lnd/watchtower/wtmock"
"github.com/lightningnetwork/lnd/watchtower/wtpolicy"
@ -97,10 +98,10 @@ func (h *towerDBHarness) deleteSession(id wtdb.SessionID, expErr error) {
// queryMatches queries that database for the passed breach hint, returning all
// matches found.
func (h *towerDBHarness) queryMatches(hint wtdb.BreachHint) []wtdb.Match {
func (h *towerDBHarness) queryMatches(hint blob.BreachHint) []wtdb.Match {
h.t.Helper()
matches, err := h.db.QueryMatches([]wtdb.BreachHint{hint})
matches, err := h.db.QueryMatches([]blob.BreachHint{hint})
if err != nil {
h.t.Fatalf("unable to query matches: %v", err)
}
@ -111,7 +112,7 @@ func (h *towerDBHarness) queryMatches(hint wtdb.BreachHint) []wtdb.Match {
// hasUpdate queries the database for the passed breach hint, asserting that
// only one match is present and that the hints indeed match. If successful, the
// match is returned.
func (h *towerDBHarness) hasUpdate(hint wtdb.BreachHint) wtdb.Match {
func (h *towerDBHarness) hasUpdate(hint blob.BreachHint) wtdb.Match {
h.t.Helper()
matches := h.queryMatches(hint)
@ -169,7 +170,7 @@ func testMultipleMatches(h *towerDBHarness) {
const numUpdates = 3
// Create a new session and send updates with all the same hint.
var hint wtdb.BreachHint
var hint blob.BreachHint
for i := 0; i < numUpdates; i++ {
id := *id(i)
session := &wtdb.SessionInfo{
@ -291,7 +292,7 @@ func testDeleteSession(h *towerDBHarness) {
h.insertSession(session1, nil)
// Create and insert updates for both sessions that have the same hint.
var hint wtdb.BreachHint
var hint blob.BreachHint
update0 := &wtdb.SessionStateUpdate{
ID: *id0,
Hint: hint,
@ -705,7 +706,7 @@ func updateFromInt(id *wtdb.SessionID, i int,
lastApplied uint16) *wtdb.SessionStateUpdate {
// Ensure the hint is unique.
var hint wtdb.BreachHint
var hint blob.BreachHint
copy(hint[:4], id[:4])
binary.BigEndian.PutUint16(hint[4:6], uint16(i))

@ -4,6 +4,7 @@ import (
"sync"
"github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/watchtower/blob"
"github.com/lightningnetwork/lnd/watchtower/wtdb"
)
@ -12,14 +13,14 @@ type TowerDB struct {
mu sync.Mutex
lastEpoch *chainntnfs.BlockEpoch
sessions map[wtdb.SessionID]*wtdb.SessionInfo
blobs map[wtdb.BreachHint]map[wtdb.SessionID]*wtdb.SessionStateUpdate
blobs map[blob.BreachHint]map[wtdb.SessionID]*wtdb.SessionStateUpdate
}
// NewTowerDB initializes a fresh mock TowerDB.
func NewTowerDB() *TowerDB {
return &TowerDB{
sessions: make(map[wtdb.SessionID]*wtdb.SessionInfo),
blobs: make(map[wtdb.BreachHint]map[wtdb.SessionID]*wtdb.SessionStateUpdate),
blobs: make(map[blob.BreachHint]map[wtdb.SessionID]*wtdb.SessionStateUpdate),
}
}
@ -113,7 +114,7 @@ func (db *TowerDB) DeleteSession(target wtdb.SessionID) error {
// passed breachHints. More than one Match will be returned for a given hint if
// they exist in the database.
func (db *TowerDB) QueryMatches(
breachHints []wtdb.BreachHint) ([]wtdb.Match, error) {
breachHints []blob.BreachHint) ([]wtdb.Match, error) {
db.mu.Lock()
defer db.mu.Unlock()