invoices: create package

This commit isolates the invoice registry in a separate package. It is
a preparation for the creation of an invoices sub server.
This commit is contained in:
Joost Jager 2018-12-20 11:57:44 +01:00
parent 3c950e8f0d
commit c1eaf60000
No known key found for this signature in database
GPG Key ID: AE6B0D042C8E38D9
6 changed files with 107 additions and 48 deletions

@ -1,9 +1,10 @@
package main package invoices
import ( import (
"bytes" "bytes"
"crypto/sha256" "crypto/sha256"
"fmt" "fmt"
"github.com/btcsuite/btcd/chaincfg"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
@ -18,29 +19,30 @@ import (
) )
var ( var (
// debugPre is the default debug preimage which is inserted into the // DebugPre is the default debug preimage which is inserted into the
// invoice registry if the --debughtlc flag is activated on start up. // invoice registry if the --debughtlc flag is activated on start up.
// All nodes initialized with the flag active will immediately settle // All nodes initialized with the flag active will immediately settle
// any incoming HTLC whose rHash corresponds with the debug // any incoming HTLC whose rHash corresponds with the debug
// preimage. // preimage.
debugPre, _ = chainhash.NewHash(bytes.Repeat([]byte{1}, 32)) DebugPre, _ = chainhash.NewHash(bytes.Repeat([]byte{1}, 32))
debugHash = chainhash.Hash(sha256.Sum256(debugPre[:])) // DebugHash is the hash of the default preimage.
DebugHash = chainhash.Hash(sha256.Sum256(DebugPre[:]))
) )
// invoiceRegistry is a central registry of all the outstanding invoices // InvoiceRegistry is a central registry of all the outstanding invoices
// created by the daemon. The registry is a thin wrapper around a map in order // created by the daemon. The registry is a thin wrapper around a map in order
// to ensure that all updates/reads are thread safe. // to ensure that all updates/reads are thread safe.
type invoiceRegistry struct { type InvoiceRegistry struct {
sync.RWMutex sync.RWMutex
cdb *channeldb.DB cdb *channeldb.DB
clientMtx sync.Mutex clientMtx sync.Mutex
nextClientID uint32 nextClientID uint32
notificationClients map[uint32]*invoiceSubscription notificationClients map[uint32]*InvoiceSubscription
newSubscriptions chan *invoiceSubscription newSubscriptions chan *InvoiceSubscription
subscriptionCancels chan uint32 subscriptionCancels chan uint32
invoiceEvents chan *invoiceEvent invoiceEvents chan *invoiceEvent
@ -49,28 +51,33 @@ type invoiceRegistry struct {
// that *all* nodes are able to fully settle. // that *all* nodes are able to fully settle.
debugInvoices map[chainhash.Hash]*channeldb.Invoice debugInvoices map[chainhash.Hash]*channeldb.Invoice
activeNetParams *chaincfg.Params
wg sync.WaitGroup wg sync.WaitGroup
quit chan struct{} quit chan struct{}
} }
// newInvoiceRegistry creates a new invoice registry. The invoice registry // NewRegistry creates a new invoice registry. The invoice registry
// wraps the persistent on-disk invoice storage with an additional in-memory // wraps the persistent on-disk invoice storage with an additional in-memory
// layer. The in-memory layer is in place such that debug invoices can be added // layer. The in-memory layer is in place such that debug invoices can be added
// which are volatile yet available system wide within the daemon. // which are volatile yet available system wide within the daemon.
func newInvoiceRegistry(cdb *channeldb.DB) *invoiceRegistry { func NewRegistry(cdb *channeldb.DB,
return &invoiceRegistry{ activeNetParams *chaincfg.Params) *InvoiceRegistry {
return &InvoiceRegistry{
cdb: cdb, cdb: cdb,
debugInvoices: make(map[chainhash.Hash]*channeldb.Invoice), debugInvoices: make(map[chainhash.Hash]*channeldb.Invoice),
notificationClients: make(map[uint32]*invoiceSubscription), notificationClients: make(map[uint32]*InvoiceSubscription),
newSubscriptions: make(chan *invoiceSubscription), newSubscriptions: make(chan *InvoiceSubscription),
subscriptionCancels: make(chan uint32), subscriptionCancels: make(chan uint32),
invoiceEvents: make(chan *invoiceEvent, 100), invoiceEvents: make(chan *invoiceEvent, 100),
activeNetParams: activeNetParams,
quit: make(chan struct{}), quit: make(chan struct{}),
} }
} }
// Start starts the registry and all goroutines it needs to carry out its task. // Start starts the registry and all goroutines it needs to carry out its task.
func (i *invoiceRegistry) Start() error { func (i *InvoiceRegistry) Start() error {
i.wg.Add(1) i.wg.Add(1)
go i.invoiceEventNotifier() go i.invoiceEventNotifier()
@ -79,7 +86,7 @@ func (i *invoiceRegistry) Start() error {
} }
// Stop signals the registry for a graceful shutdown. // Stop signals the registry for a graceful shutdown.
func (i *invoiceRegistry) Stop() { func (i *InvoiceRegistry) Stop() {
close(i.quit) close(i.quit)
i.wg.Wait() i.wg.Wait()
@ -96,7 +103,7 @@ type invoiceEvent struct {
// invoiceEventNotifier is the dedicated goroutine responsible for accepting // invoiceEventNotifier is the dedicated goroutine responsible for accepting
// new notification subscriptions, cancelling old subscriptions, and // new notification subscriptions, cancelling old subscriptions, and
// dispatching new invoice events. // dispatching new invoice events.
func (i *invoiceRegistry) invoiceEventNotifier() { func (i *InvoiceRegistry) invoiceEventNotifier() {
defer i.wg.Done() defer i.wg.Done()
for { for {
@ -110,11 +117,11 @@ func (i *invoiceRegistry) invoiceEventNotifier() {
// invoice events. // invoice events.
err := i.deliverBacklogEvents(newClient) err := i.deliverBacklogEvents(newClient)
if err != nil { if err != nil {
ltndLog.Errorf("unable to deliver backlog invoice "+ log.Errorf("unable to deliver backlog invoice "+
"notifications: %v", err) "notifications: %v", err)
} }
ltndLog.Infof("New invoice subscription "+ log.Infof("New invoice subscription "+
"client: id=%v", newClient.id) "client: id=%v", newClient.id)
// With the backlog notifications delivered (if any), // With the backlog notifications delivered (if any),
@ -125,7 +132,7 @@ func (i *invoiceRegistry) invoiceEventNotifier() {
// A client no longer wishes to receive invoice notifications. // A client no longer wishes to receive invoice notifications.
// So we'll remove them from the set of active clients. // So we'll remove them from the set of active clients.
case clientID := <-i.subscriptionCancels: case clientID := <-i.subscriptionCancels:
ltndLog.Infof("Cancelling invoice subscription for "+ log.Infof("Cancelling invoice subscription for "+
"client=%v", clientID) "client=%v", clientID)
delete(i.notificationClients, clientID) delete(i.notificationClients, clientID)
@ -157,14 +164,14 @@ func (i *invoiceRegistry) invoiceEventNotifier() {
// instance. // instance.
case event.state == channeldb.ContractOpen && case event.state == channeldb.ContractOpen &&
client.addIndex+1 != invoice.AddIndex: client.addIndex+1 != invoice.AddIndex:
ltndLog.Warnf("client=%v for invoice "+ log.Warnf("client=%v for invoice "+
"notifications missed an update, "+ "notifications missed an update, "+
"add_index=%v, new add event index=%v", "add_index=%v, new add event index=%v",
clientID, client.addIndex, clientID, client.addIndex,
invoice.AddIndex) invoice.AddIndex)
case event.state == channeldb.ContractSettled && case event.state == channeldb.ContractSettled &&
client.settleIndex+1 != invoice.SettleIndex: client.settleIndex+1 != invoice.SettleIndex:
ltndLog.Warnf("client=%v for invoice "+ log.Warnf("client=%v for invoice "+
"notifications missed an update, "+ "notifications missed an update, "+
"settle_index=%v, new settle event index=%v", "settle_index=%v, new settle event index=%v",
clientID, client.settleIndex, clientID, client.settleIndex,
@ -192,7 +199,7 @@ func (i *invoiceRegistry) invoiceEventNotifier() {
case channeldb.ContractOpen: case channeldb.ContractOpen:
client.addIndex = invoice.AddIndex client.addIndex = invoice.AddIndex
default: default:
ltndLog.Errorf("unknown invoice "+ log.Errorf("unknown invoice "+
"state: %v", event.state) "state: %v", event.state)
} }
} }
@ -205,7 +212,7 @@ func (i *invoiceRegistry) invoiceEventNotifier() {
// deliverBacklogEvents will attempts to query the invoice database for any // deliverBacklogEvents will attempts to query the invoice database for any
// notifications that the client has missed since it reconnected last. // notifications that the client has missed since it reconnected last.
func (i *invoiceRegistry) deliverBacklogEvents(client *invoiceSubscription) error { func (i *InvoiceRegistry) deliverBacklogEvents(client *InvoiceSubscription) error {
// First, we'll query the database to see if based on the provided // First, we'll query the database to see if based on the provided
// addIndex and settledIndex we need to deliver any backlog // addIndex and settledIndex we need to deliver any backlog
// notifications. // notifications.
@ -257,7 +264,7 @@ func (i *invoiceRegistry) deliverBacklogEvents(client *invoiceSubscription) erro
// by the passed preimage. Once this invoice is added, subsystems within the // by the passed preimage. Once this invoice is added, subsystems within the
// daemon add/forward HTLCs that are able to obtain the proper preimage // daemon add/forward HTLCs that are able to obtain the proper preimage
// required for redemption in the case that we're the final destination. // required for redemption in the case that we're the final destination.
func (i *invoiceRegistry) AddDebugInvoice(amt btcutil.Amount, preimage chainhash.Hash) { func (i *InvoiceRegistry) AddDebugInvoice(amt btcutil.Amount, preimage chainhash.Hash) {
paymentHash := chainhash.Hash(sha256.Sum256(preimage[:])) paymentHash := chainhash.Hash(sha256.Sum256(preimage[:]))
invoice := &channeldb.Invoice{ invoice := &channeldb.Invoice{
@ -272,7 +279,7 @@ func (i *invoiceRegistry) AddDebugInvoice(amt btcutil.Amount, preimage chainhash
i.debugInvoices[paymentHash] = invoice i.debugInvoices[paymentHash] = invoice
i.Unlock() i.Unlock()
ltndLog.Debugf("Adding debug invoice %v", newLogClosure(func() string { log.Debugf("Adding debug invoice %v", newLogClosure(func() string {
return spew.Sdump(invoice) return spew.Sdump(invoice)
})) }))
} }
@ -284,11 +291,11 @@ func (i *invoiceRegistry) AddDebugInvoice(amt btcutil.Amount, preimage chainhash
// redemption in the case that we're the final destination. We also return the // redemption in the case that we're the final destination. We also return the
// addIndex of the newly created invoice which monotonically increases for each // addIndex of the newly created invoice which monotonically increases for each
// new invoice added. // new invoice added.
func (i *invoiceRegistry) AddInvoice(invoice *channeldb.Invoice) (uint64, error) { func (i *InvoiceRegistry) AddInvoice(invoice *channeldb.Invoice) (uint64, error) {
i.Lock() i.Lock()
defer i.Unlock() defer i.Unlock()
ltndLog.Debugf("Adding invoice %v", newLogClosure(func() string { log.Debugf("Adding invoice %v", newLogClosure(func() string {
return spew.Sdump(invoice) return spew.Sdump(invoice)
})) }))
@ -311,7 +318,7 @@ func (i *invoiceRegistry) AddInvoice(invoice *channeldb.Invoice) (uint64, error)
// according to the cltv delta. // according to the cltv delta.
// //
// TODO(roasbeef): ignore if settled? // TODO(roasbeef): ignore if settled?
func (i *invoiceRegistry) LookupInvoice(rHash chainhash.Hash) (channeldb.Invoice, uint32, error) { func (i *InvoiceRegistry) LookupInvoice(rHash chainhash.Hash) (channeldb.Invoice, uint32, error) {
// First check the in-memory debug invoice index to see if this is an // First check the in-memory debug invoice index to see if this is an
// existing invoice added for debugging. // existing invoice added for debugging.
i.RLock() i.RLock()
@ -331,7 +338,7 @@ func (i *invoiceRegistry) LookupInvoice(rHash chainhash.Hash) (channeldb.Invoice
} }
payReq, err := zpay32.Decode( payReq, err := zpay32.Decode(
string(invoice.PaymentRequest), activeNetParams.Params, string(invoice.PaymentRequest), i.activeNetParams,
) )
if err != nil { if err != nil {
return channeldb.Invoice{}, 0, err return channeldb.Invoice{}, 0, err
@ -343,13 +350,13 @@ func (i *invoiceRegistry) LookupInvoice(rHash chainhash.Hash) (channeldb.Invoice
// SettleInvoice attempts to mark an invoice as settled. If the invoice is a // SettleInvoice attempts to mark an invoice as settled. If the invoice is a
// debug invoice, then this method is a noop as debug invoices are never fully // debug invoice, then this method is a noop as debug invoices are never fully
// settled. // settled.
func (i *invoiceRegistry) SettleInvoice(rHash chainhash.Hash, func (i *InvoiceRegistry) SettleInvoice(rHash chainhash.Hash,
amtPaid lnwire.MilliSatoshi) error { amtPaid lnwire.MilliSatoshi) error {
i.Lock() i.Lock()
defer i.Unlock() defer i.Unlock()
ltndLog.Debugf("Settling invoice %x", rHash[:]) log.Debugf("Settling invoice %x", rHash[:])
// First check the in-memory debug invoice index to see if this is an // First check the in-memory debug invoice index to see if this is an
// existing invoice added for debugging. // existing invoice added for debugging.
@ -366,7 +373,7 @@ func (i *invoiceRegistry) SettleInvoice(rHash chainhash.Hash,
return err return err
} }
ltndLog.Infof("Payment received: %v", spew.Sdump(invoice)) log.Infof("Payment received: %v", spew.Sdump(invoice))
i.notifyClients(invoice, channeldb.ContractSettled) i.notifyClients(invoice, channeldb.ContractSettled)
@ -375,7 +382,7 @@ func (i *invoiceRegistry) SettleInvoice(rHash chainhash.Hash,
// notifyClients notifies all currently registered invoice notification clients // notifyClients notifies all currently registered invoice notification clients
// of a newly added/settled invoice. // of a newly added/settled invoice.
func (i *invoiceRegistry) notifyClients(invoice *channeldb.Invoice, func (i *InvoiceRegistry) notifyClients(invoice *channeldb.Invoice,
state channeldb.ContractState) { state channeldb.ContractState) {
event := &invoiceEvent{ event := &invoiceEvent{
@ -389,12 +396,12 @@ func (i *invoiceRegistry) notifyClients(invoice *channeldb.Invoice,
} }
} }
// invoiceSubscription represents an intent to receive updates for newly added // InvoiceSubscription represents an intent to receive updates for newly added
// or settled invoices. For each newly added invoice, a copy of the invoice // or settled invoices. For each newly added invoice, a copy of the invoice
// will be sent over the NewInvoices channel. Similarly, for each newly settled // will be sent over the NewInvoices channel. Similarly, for each newly settled
// invoice, a copy of the invoice will be sent over the SettledInvoices // invoice, a copy of the invoice will be sent over the SettledInvoices
// channel. // channel.
type invoiceSubscription struct { type InvoiceSubscription struct {
cancelled uint32 // To be used atomically. cancelled uint32 // To be used atomically.
// NewInvoices is a channel that we'll use to send all newly created // NewInvoices is a channel that we'll use to send all newly created
@ -424,16 +431,16 @@ type invoiceSubscription struct {
id uint32 id uint32
inv *invoiceRegistry inv *InvoiceRegistry
cancelChan chan struct{} cancelChan chan struct{}
wg sync.WaitGroup wg sync.WaitGroup
} }
// Cancel unregisters the invoiceSubscription, freeing any previously allocated // Cancel unregisters the InvoiceSubscription, freeing any previously allocated
// resources. // resources.
func (i *invoiceSubscription) Cancel() { func (i *InvoiceSubscription) Cancel() {
if !atomic.CompareAndSwapUint32(&i.cancelled, 0, 1) { if !atomic.CompareAndSwapUint32(&i.cancelled, 0, 1) {
return return
} }
@ -449,13 +456,13 @@ func (i *invoiceSubscription) Cancel() {
i.wg.Wait() i.wg.Wait()
} }
// SubscribeNotifications returns an invoiceSubscription which allows the // SubscribeNotifications returns an InvoiceSubscription which allows the
// caller to receive async notifications when any invoices are settled or // caller to receive async notifications when any invoices are settled or
// added. The invoiceIndex parameter is a streaming "checkpoint". We'll start // added. The invoiceIndex parameter is a streaming "checkpoint". We'll start
// by first sending out all new events with an invoice index _greater_ than // by first sending out all new events with an invoice index _greater_ than
// this value. Afterwards, we'll send out real-time notifications. // this value. Afterwards, we'll send out real-time notifications.
func (i *invoiceRegistry) SubscribeNotifications(addIndex, settleIndex uint64) *invoiceSubscription { func (i *InvoiceRegistry) SubscribeNotifications(addIndex, settleIndex uint64) *InvoiceSubscription {
client := &invoiceSubscription{ client := &InvoiceSubscription{
NewInvoices: make(chan *channeldb.Invoice), NewInvoices: make(chan *channeldb.Invoice),
SettledInvoices: make(chan *channeldb.Invoice), SettledInvoices: make(chan *channeldb.Invoice),
addIndex: addIndex, addIndex: addIndex,
@ -495,7 +502,7 @@ func (i *invoiceRegistry) SubscribeNotifications(addIndex, settleIndex uint64) *
case channeldb.ContractSettled: case channeldb.ContractSettled:
targetChan = client.SettledInvoices targetChan = client.SettledInvoices
default: default:
ltndLog.Errorf("unknown invoice "+ log.Errorf("unknown invoice "+
"state: %v", invoiceEvent.state) "state: %v", invoiceEvent.state)
continue continue

45
invoices/log.go Normal file

@ -0,0 +1,45 @@
package invoices
import (
"github.com/btcsuite/btclog"
"github.com/lightningnetwork/lnd/build"
)
// log is a logger that is initialized with no output filters. This
// means the package will not perform any logging by default until the caller
// requests it.
var log btclog.Logger
// The default amount of logging is none.
func init() {
UseLogger(build.NewSubLogger("INVC", nil))
}
// DisableLog disables all library log output. Logging output is disabled
// by default until UseLogger is called.
func DisableLog() {
UseLogger(btclog.Disabled)
}
// UseLogger uses a specified Logger to output package logging info.
// This should be used in preference to SetLogWriter if the caller is also
// using btclog.
func UseLogger(logger btclog.Logger) {
log = logger
}
// logClosure is used to provide a closure over expensive logging operations so
// don't have to be performed when the logging level doesn't warrant it.
type logClosure func() string
// String invokes the underlying function and returns the result.
func (c logClosure) String() string {
return c()
}
// newLogClosure returns a new closure over a function that returns a string
// which itself provides a Stringer interface so that it can be used with the
// logging system.
func newLogClosure(c func() string) logClosure {
return logClosure(c)
}

4
log.go

@ -2,6 +2,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/lightningnetwork/lnd/invoices"
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
@ -71,6 +72,7 @@ var (
sgnrLog = build.NewSubLogger("SGNR", backendLog.Logger) sgnrLog = build.NewSubLogger("SGNR", backendLog.Logger)
wlktLog = build.NewSubLogger("WLKT", backendLog.Logger) wlktLog = build.NewSubLogger("WLKT", backendLog.Logger)
arpcLog = build.NewSubLogger("ARPC", backendLog.Logger) arpcLog = build.NewSubLogger("ARPC", backendLog.Logger)
invcLog = build.NewSubLogger("INVC", backendLog.Logger)
) )
// Initialize package-global logger variables. // Initialize package-global logger variables.
@ -91,6 +93,7 @@ func init() {
signrpc.UseLogger(sgnrLog) signrpc.UseLogger(sgnrLog)
walletrpc.UseLogger(wlktLog) walletrpc.UseLogger(wlktLog)
autopilotrpc.UseLogger(arpcLog) autopilotrpc.UseLogger(arpcLog)
invoices.UseLogger(invcLog)
} }
// subsystemLoggers maps each subsystem identifier to its associated logger. // subsystemLoggers maps each subsystem identifier to its associated logger.
@ -117,6 +120,7 @@ var subsystemLoggers = map[string]btclog.Logger{
"SGNR": sgnrLog, "SGNR": sgnrLog,
"WLKT": wlktLog, "WLKT": wlktLog,
"ARPC": arpcLog, "ARPC": arpcLog,
"INVC": invcLog,
} }
// initLogRotator initializes the logging rotator to write logs to logFile and // initLogRotator initializes the logging rotator to write logs to logFile and

@ -31,6 +31,7 @@ import (
"github.com/lightningnetwork/lnd/build" "github.com/lightningnetwork/lnd/build"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/htlcswitch" "github.com/lightningnetwork/lnd/htlcswitch"
"github.com/lightningnetwork/lnd/invoices"
"github.com/lightningnetwork/lnd/lncfg" "github.com/lightningnetwork/lnd/lncfg"
"github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwallet"
@ -2608,7 +2609,7 @@ func extractPaymentIntent(rpcPayReq *rpcPaymentRequest) (rpcPaymentIntent, error
// same debug rHash. Otherwise, we pay to the rHash specified within // same debug rHash. Otherwise, we pay to the rHash specified within
// the RPC request. // the RPC request.
case cfg.DebugHTLC && bytes.Equal(payIntent.rHash[:], zeroHash[:]): case cfg.DebugHTLC && bytes.Equal(payIntent.rHash[:], zeroHash[:]):
copy(payIntent.rHash[:], debugHash[:]) copy(payIntent.rHash[:], invoices.DebugHash[:])
default: default:
copy(payIntent.rHash[:], rpcPayReq.PaymentHash) copy(payIntent.rHash[:], rpcPayReq.PaymentHash)

@ -31,6 +31,7 @@ import (
"github.com/lightningnetwork/lnd/contractcourt" "github.com/lightningnetwork/lnd/contractcourt"
"github.com/lightningnetwork/lnd/discovery" "github.com/lightningnetwork/lnd/discovery"
"github.com/lightningnetwork/lnd/htlcswitch" "github.com/lightningnetwork/lnd/htlcswitch"
"github.com/lightningnetwork/lnd/invoices"
"github.com/lightningnetwork/lnd/lncfg" "github.com/lightningnetwork/lnd/lncfg"
"github.com/lightningnetwork/lnd/lnpeer" "github.com/lightningnetwork/lnd/lnpeer"
"github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc"
@ -143,7 +144,7 @@ type server struct {
htlcSwitch *htlcswitch.Switch htlcSwitch *htlcswitch.Switch
invoices *invoiceRegistry invoices *invoices.InvoiceRegistry
witnessBeacon contractcourt.WitnessBeacon witnessBeacon contractcourt.WitnessBeacon
@ -266,7 +267,7 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB, cc *chainControl,
cc: cc, cc: cc,
sigPool: lnwallet.NewSigPool(runtime.NumCPU()*2, cc.signer), sigPool: lnwallet.NewSigPool(runtime.NumCPU()*2, cc.signer),
invoices: newInvoiceRegistry(chanDB), invoices: invoices.NewRegistry(chanDB, activeNetParams.Params),
identityPriv: privKey, identityPriv: privKey,
nodeSigner: newNodeSigner(privKey), nodeSigner: newNodeSigner(privKey),
@ -306,9 +307,9 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB, cc *chainControl,
// HTLCs with the debug R-Hash immediately settled. // HTLCs with the debug R-Hash immediately settled.
if cfg.DebugHTLC { if cfg.DebugHTLC {
kiloCoin := btcutil.Amount(btcutil.SatoshiPerBitcoin * 1000) kiloCoin := btcutil.Amount(btcutil.SatoshiPerBitcoin * 1000)
s.invoices.AddDebugInvoice(kiloCoin, *debugPre) s.invoices.AddDebugInvoice(kiloCoin, *invoices.DebugPre)
srvrLog.Debugf("Debug HTLC invoice inserted, preimage=%x, hash=%x", srvrLog.Debugf("Debug HTLC invoice inserted, preimage=%x, hash=%x",
debugPre[:], debugHash[:]) invoices.DebugPre[:], invoices.DebugHash[:])
} }
_, currentHeight, err := s.cc.chainIO.GetBestBlock() _, currentHeight, err := s.cc.chainIO.GetBestBlock()

@ -6,6 +6,7 @@ import (
"github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/contractcourt" "github.com/lightningnetwork/lnd/contractcourt"
"github.com/lightningnetwork/lnd/invoices"
"github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwallet"
) )
@ -23,7 +24,7 @@ type preimageSubscriber struct {
type preimageBeacon struct { type preimageBeacon struct {
sync.RWMutex sync.RWMutex
invoices *invoiceRegistry invoices *invoices.InvoiceRegistry
wCache *channeldb.WitnessCache wCache *channeldb.WitnessCache