contractcourt+server: settle invoice for on-chain HTLC sweep

In this commit, we extend the htlcSuccessResolver to settle the invoice,
if any, of the corresponding on-chain HTLC sweep. This ensures that the
invoice state is consistent as when claiming the HTLC "off-chain".
This commit is contained in:
Wilmer Paulino 2019-01-22 20:45:35 -08:00
parent 974e0f2df5
commit 41f638c7cf
No known key found for this signature in database
GPG Key ID: 6DF57B9F9514972F
4 changed files with 30 additions and 4 deletions

@ -6,8 +6,6 @@ import (
"sync" "sync"
"sync/atomic" "sync/atomic"
"github.com/lightningnetwork/lnd/sweep"
"github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil" "github.com/btcsuite/btcutil"
@ -15,6 +13,7 @@ import (
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/sweep"
) )
// ErrChainArbExiting signals that the chain arbitrator is shutting down. // 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 allows resolvers to sweep their final outputs.
Sweeper *sweep.UtxoSweeper 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 // ChainArbitrator is a sub-system that oversees the on-chain resolution of all

@ -175,6 +175,9 @@ func createTestChannelArbitrator(log ArbitratorLog) (*ChannelArbitrator,
*lnwallet.IncomingHtlcResolution, uint32) error { *lnwallet.IncomingHtlcResolution, uint32) error {
return nil return nil
}, },
SettleInvoice: func(chainhash.Hash, lnwire.MilliSatoshi) error {
return nil
},
} }
// We'll use the resolvedChan to synchronize on call to // We'll use the resolvedChan to synchronize on call to

@ -3,9 +3,11 @@ package contractcourt
import ( import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"github.com/lightningnetwork/lnd/lnwire"
"io" "io"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
"github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwallet"
@ -174,6 +176,14 @@ func (h *htlcSuccessResolver) Resolve() (ContractResolver, error) {
return nil, fmt.Errorf("quitting") 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 // Once the transaction has received a sufficient number of
// confirmations, we'll mark ourselves as fully resolved and exit. // confirmations, we'll mark ourselves as fully resolved and exit.
h.resolved = true h.resolved = true
@ -239,6 +249,14 @@ func (h *htlcSuccessResolver) Resolve() (ContractResolver, error) {
return nil, fmt.Errorf("quitting") 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 h.resolved = true
return nil, h.Checkpoint(h) return nil, h.Checkpoint(h)
} }

@ -728,7 +728,8 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB, cc *chainControl,
DisableChannel: func(op wire.OutPoint) error { DisableChannel: func(op wire.OutPoint) error {
return s.announceChanStatus(op, true) return s.announceChanStatus(op, true)
}, },
Sweeper: s.sweeper, Sweeper: s.sweeper,
SettleInvoice: s.invoices.SettleInvoice,
}, chanDB) }, chanDB)
s.breachArbiter = newBreachArbiter(&BreachConfig{ s.breachArbiter = newBreachArbiter(&BreachConfig{