diff --git a/contractcourt/chain_arbitrator.go b/contractcourt/chain_arbitrator.go index 07eab9e1..696b4636 100644 --- a/contractcourt/chain_arbitrator.go +++ b/contractcourt/chain_arbitrator.go @@ -6,8 +6,6 @@ import ( "sync" "sync/atomic" - "github.com/lightningnetwork/lnd/sweep" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" @@ -15,6 +13,7 @@ import ( "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwire" + "github.com/lightningnetwork/lnd/sweep" ) // ErrChainArbExiting signals that the chain arbitrator is shutting down. @@ -135,6 +134,11 @@ type ChainArbitratorConfig struct { // Sweeper allows resolvers to sweep their final outputs. Sweeper *sweep.UtxoSweeper + + // SettleInvoice attempts to settle an existing invoice on-chain with + // the given payment hash. ErrInvoiceNotFound is returned if an invoice + // is not found. + SettleInvoice func(chainhash.Hash, lnwire.MilliSatoshi) error } // ChainArbitrator is a sub-system that oversees the on-chain resolution of all diff --git a/contractcourt/channel_arbitrator_test.go b/contractcourt/channel_arbitrator_test.go index aae59f2b..e910de0a 100644 --- a/contractcourt/channel_arbitrator_test.go +++ b/contractcourt/channel_arbitrator_test.go @@ -175,6 +175,9 @@ func createTestChannelArbitrator(log ArbitratorLog) (*ChannelArbitrator, *lnwallet.IncomingHtlcResolution, uint32) error { return nil }, + SettleInvoice: func(chainhash.Hash, lnwire.MilliSatoshi) error { + return nil + }, } // We'll use the resolvedChan to synchronize on call to diff --git a/contractcourt/htlc_success_resolver.go b/contractcourt/htlc_success_resolver.go index f41e4331..3a35c850 100644 --- a/contractcourt/htlc_success_resolver.go +++ b/contractcourt/htlc_success_resolver.go @@ -3,9 +3,11 @@ package contractcourt import ( "encoding/binary" "fmt" - "github.com/lightningnetwork/lnd/lnwire" "io" + "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/lnwire" + "github.com/btcsuite/btcd/wire" "github.com/davecgh/go-spew/spew" "github.com/lightningnetwork/lnd/lnwallet" @@ -174,6 +176,14 @@ func (h *htlcSuccessResolver) Resolve() (ContractResolver, error) { return nil, fmt.Errorf("quitting") } + // With the HTLC claimed, we can attempt to settle its + // corresponding invoice if we were the original destination. + err = h.SettleInvoice(h.payHash, h.htlcAmt) + if err != nil && err != channeldb.ErrInvoiceNotFound { + log.Errorf("Unable to settle invoice with payment "+ + "hash %x: %v", h.payHash, err) + } + // Once the transaction has received a sufficient number of // confirmations, we'll mark ourselves as fully resolved and exit. h.resolved = true @@ -239,6 +249,14 @@ func (h *htlcSuccessResolver) Resolve() (ContractResolver, error) { return nil, fmt.Errorf("quitting") } + // With the HTLC claimed, we can attempt to settle its corresponding + // invoice if we were the original destination. + err = h.SettleInvoice(h.payHash, h.htlcAmt) + if err != nil && err != channeldb.ErrInvoiceNotFound { + log.Errorf("Unable to settle invoice with payment "+ + "hash %x: %v", h.payHash, err) + } + h.resolved = true return nil, h.Checkpoint(h) } diff --git a/server.go b/server.go index f12053c1..85178f81 100644 --- a/server.go +++ b/server.go @@ -728,7 +728,8 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB, cc *chainControl, DisableChannel: func(op wire.OutPoint) error { return s.announceChanStatus(op, true) }, - Sweeper: s.sweeper, + Sweeper: s.sweeper, + SettleInvoice: s.invoices.SettleInvoice, }, chanDB) s.breachArbiter = newBreachArbiter(&BreachConfig{