mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-30 04:32:33 +02:00
contractcourt+lnd: make IncubateOutputs
take fn.Option
`IncubateOutputs` never takes more than one HTLC, so we change the params to be optional, which helps with the following commit where we pass the deadline height when incubating outgoing HTLCs.
This commit is contained in:
parent
6f0c2b5bab
commit
33abbe1942
@ -114,14 +114,15 @@ type ChainArbitratorConfig struct {
|
||||
// returned.
|
||||
IsOurAddress func(btcutil.Address) bool
|
||||
|
||||
// IncubateOutput sends either an incoming HTLC, an outgoing HTLC, or
|
||||
// IncubateOutputs sends either an incoming HTLC, an outgoing HTLC, or
|
||||
// both to the utxo nursery. Once this function returns, the nursery
|
||||
// should have safely persisted the outputs to disk, and should start
|
||||
// the process of incubation. This is used when a resolver wishes to
|
||||
// pass off the output to the nursery as we're only waiting on an
|
||||
// absolute/relative item block.
|
||||
IncubateOutputs func(wire.OutPoint, *lnwallet.OutgoingHtlcResolution,
|
||||
*lnwallet.IncomingHtlcResolution, uint32) error
|
||||
IncubateOutputs func(wire.OutPoint,
|
||||
fn.Option[lnwallet.OutgoingHtlcResolution],
|
||||
fn.Option[lnwallet.IncomingHtlcResolution], uint32) error
|
||||
|
||||
// PreimageDB is a global store of all known pre-images. We'll use this
|
||||
// to decide if we should broadcast a commitment transaction to claim
|
||||
|
@ -362,8 +362,9 @@ func createTestChannelArbitrator(t *testing.T, log ArbitratorLog,
|
||||
ConfChan: make(chan *chainntnfs.TxConfirmation),
|
||||
},
|
||||
IncubateOutputs: func(wire.OutPoint,
|
||||
*lnwallet.OutgoingHtlcResolution,
|
||||
*lnwallet.IncomingHtlcResolution, uint32) error {
|
||||
fn.Option[lnwallet.OutgoingHtlcResolution],
|
||||
fn.Option[lnwallet.IncomingHtlcResolution],
|
||||
uint32) error {
|
||||
|
||||
incubateChan <- struct{}{}
|
||||
return nil
|
||||
|
@ -206,7 +206,8 @@ func (h *htlcSuccessResolver) broadcastSuccessTx() (*wire.OutPoint, error) {
|
||||
h, h.htlc.RHash[:])
|
||||
|
||||
err := h.IncubateOutputs(
|
||||
h.ChanPoint, nil, &h.htlcResolution,
|
||||
h.ChanPoint, fn.None[lnwallet.OutgoingHtlcResolution](),
|
||||
fn.Some(h.htlcResolution),
|
||||
h.broadcastHeight,
|
||||
)
|
||||
if err != nil {
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/fn"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/kvdb"
|
||||
"github.com/lightningnetwork/lnd/lnmock"
|
||||
@ -65,8 +66,10 @@ func newHtlcResolverTestContext(t *testing.T,
|
||||
return nil
|
||||
},
|
||||
Sweeper: newMockSweeper(),
|
||||
IncubateOutputs: func(wire.OutPoint, *lnwallet.OutgoingHtlcResolution,
|
||||
*lnwallet.IncomingHtlcResolution, uint32) error {
|
||||
IncubateOutputs: func(wire.OutPoint,
|
||||
fn.Option[lnwallet.OutgoingHtlcResolution],
|
||||
fn.Option[lnwallet.IncomingHtlcResolution],
|
||||
uint32) error {
|
||||
|
||||
return nil
|
||||
},
|
||||
|
@ -545,7 +545,8 @@ func (h *htlcTimeoutResolver) sendSecondLevelTxLegacy() error {
|
||||
h.htlcResolution.ClaimOutpoint)
|
||||
|
||||
err := h.IncubateOutputs(
|
||||
h.ChanPoint, &h.htlcResolution, nil,
|
||||
h.ChanPoint, fn.Some(h.htlcResolution),
|
||||
fn.None[lnwallet.IncomingHtlcResolution](),
|
||||
h.broadcastHeight,
|
||||
)
|
||||
if err != nil {
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/fn"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/kvdb"
|
||||
@ -279,13 +280,14 @@ func TestHtlcTimeoutResolver(t *testing.T) {
|
||||
resolutionChan := make(chan ResolutionMsg, 1)
|
||||
reportChan := make(chan *channeldb.ResolverReport)
|
||||
|
||||
//nolint:lll
|
||||
chainCfg := ChannelArbitratorConfig{
|
||||
ChainArbitratorConfig: ChainArbitratorConfig{
|
||||
Notifier: notifier,
|
||||
PreimageDB: witnessBeacon,
|
||||
IncubateOutputs: func(wire.OutPoint,
|
||||
*lnwallet.OutgoingHtlcResolution,
|
||||
*lnwallet.IncomingHtlcResolution,
|
||||
fn.Option[lnwallet.OutgoingHtlcResolution],
|
||||
fn.Option[lnwallet.IncomingHtlcResolution],
|
||||
uint32) error {
|
||||
|
||||
incubateChan <- struct{}{}
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/fn"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/labels"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
@ -333,8 +334,8 @@ func (u *UtxoNursery) Stop() error {
|
||||
// they're CLTV absolute time locked, or if they're CSV relative time locked.
|
||||
// Once all outputs reach maturity, they'll be swept back into the wallet.
|
||||
func (u *UtxoNursery) IncubateOutputs(chanPoint wire.OutPoint,
|
||||
outgoingHtlcs []lnwallet.OutgoingHtlcResolution,
|
||||
incomingHtlcs []lnwallet.IncomingHtlcResolution,
|
||||
outgoingHtlc fn.Option[lnwallet.OutgoingHtlcResolution],
|
||||
incomingHtlc fn.Option[lnwallet.IncomingHtlcResolution],
|
||||
broadcastHeight uint32) error {
|
||||
|
||||
// Add to wait group because nursery might shut down during execution of
|
||||
@ -352,14 +353,13 @@ func (u *UtxoNursery) IncubateOutputs(chanPoint wire.OutPoint,
|
||||
default:
|
||||
}
|
||||
|
||||
numHtlcs := len(incomingHtlcs) + len(outgoingHtlcs)
|
||||
var (
|
||||
// Kid outputs can be swept after an initial confirmation
|
||||
// followed by a maturity period.Baby outputs are two stage and
|
||||
// will need to wait for an absolute time out to reach a
|
||||
// confirmation, then require a relative confirmation delay.
|
||||
kidOutputs = make([]kidOutput, 0, 1+len(incomingHtlcs))
|
||||
babyOutputs = make([]babyOutput, 0, len(outgoingHtlcs))
|
||||
kidOutputs = make([]kidOutput, 0)
|
||||
babyOutputs = make([]babyOutput, 0)
|
||||
)
|
||||
|
||||
// 1. Build all the spendable outputs that we will try to incubate.
|
||||
@ -369,7 +369,7 @@ func (u *UtxoNursery) IncubateOutputs(chanPoint wire.OutPoint,
|
||||
// For each incoming HTLC, we'll register a kid output marked as a
|
||||
// second-layer HTLC output. We effectively skip the baby stage (as the
|
||||
// timelock is zero), and enter the kid stage.
|
||||
for _, htlcRes := range incomingHtlcs {
|
||||
incomingHtlc.WhenSome(func(htlcRes lnwallet.IncomingHtlcResolution) {
|
||||
// Based on the input pk script of the sign descriptor, we can
|
||||
// determine if this is a taproot output or not. This'll
|
||||
// determine the witness type we try to set below.
|
||||
@ -392,13 +392,13 @@ func (u *UtxoNursery) IncubateOutputs(chanPoint wire.OutPoint,
|
||||
if htlcOutput.Amount() > 0 {
|
||||
kidOutputs = append(kidOutputs, htlcOutput)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// For each outgoing HTLC, we'll create a baby output. If this is our
|
||||
// commitment transaction, then we'll broadcast a second-layer
|
||||
// transaction to transition to a kid output. Otherwise, we'll directly
|
||||
// spend once the CLTV delay us up.
|
||||
for _, htlcRes := range outgoingHtlcs {
|
||||
outgoingHtlc.WhenSome(func(htlcRes lnwallet.OutgoingHtlcResolution) {
|
||||
// If this HTLC is on our commitment transaction, then it'll be
|
||||
// a baby output as we need to go to the second level to sweep
|
||||
// it.
|
||||
@ -408,7 +408,8 @@ func (u *UtxoNursery) IncubateOutputs(chanPoint wire.OutPoint,
|
||||
if htlcOutput.Amount() > 0 {
|
||||
babyOutputs = append(babyOutputs, htlcOutput)
|
||||
}
|
||||
continue
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Based on the input pk script of the sign descriptor, we can
|
||||
@ -435,12 +436,13 @@ func (u *UtxoNursery) IncubateOutputs(chanPoint wire.OutPoint,
|
||||
witType, &htlcRes.SweepSignDesc, htlcRes.Expiry,
|
||||
)
|
||||
kidOutputs = append(kidOutputs, htlcOutput)
|
||||
}
|
||||
})
|
||||
|
||||
// TODO(roasbeef): if want to handle outgoing on remote commit
|
||||
// * need ability to cancel in the case that we learn of pre-image or
|
||||
// remote party pulls
|
||||
|
||||
numHtlcs := len(babyOutputs) + len(kidOutputs)
|
||||
utxnLog.Infof("Incubating Channel(%s) num-htlcs=%d",
|
||||
chanPoint, numHtlcs)
|
||||
|
||||
|
@ -16,7 +16,9 @@ import (
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/fn"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/lntest/mock"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
@ -627,8 +629,8 @@ func incubateTestOutput(t *testing.T, nursery *UtxoNursery,
|
||||
// Hand off to nursery.
|
||||
err := nursery.IncubateOutputs(
|
||||
testChanPoint,
|
||||
[]lnwallet.OutgoingHtlcResolution{*outgoingRes},
|
||||
nil, 0,
|
||||
fn.Some(*outgoingRes),
|
||||
fn.None[lnwallet.IncomingHtlcResolution](), 0,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -709,8 +711,8 @@ func TestRejectedCribTransaction(t *testing.T) {
|
||||
// Hand off to nursery.
|
||||
err := ctx.nursery.IncubateOutputs(
|
||||
testChanPoint,
|
||||
[]lnwallet.OutgoingHtlcResolution{*outgoingRes},
|
||||
nil, 0,
|
||||
fn.Some(*outgoingRes),
|
||||
fn.None[lnwallet.IncomingHtlcResolution](), 0,
|
||||
)
|
||||
if test.expectErr {
|
||||
require.ErrorIs(t, err, test.broadcastErr)
|
||||
@ -758,7 +760,8 @@ func assertNurseryReport(t *testing.T, nursery *UtxoNursery,
|
||||
|
||||
if len(report.Htlcs) != expectedNofHtlcs {
|
||||
t.Fatalf("expected %v outputs to be reported, but report "+
|
||||
"only contains %v", expectedNofHtlcs, len(report.Htlcs))
|
||||
"contains %s", expectedNofHtlcs,
|
||||
spew.Sdump(report.Htlcs))
|
||||
}
|
||||
|
||||
if expectedNofHtlcs != 0 {
|
||||
|
18
server.go
18
server.go
@ -38,6 +38,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/contractcourt"
|
||||
"github.com/lightningnetwork/lnd/discovery"
|
||||
"github.com/lightningnetwork/lnd/feature"
|
||||
"github.com/lightningnetwork/lnd/fn"
|
||||
"github.com/lightningnetwork/lnd/funding"
|
||||
"github.com/lightningnetwork/lnd/healthcheck"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch"
|
||||
@ -1148,23 +1149,12 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
|
||||
return nil
|
||||
},
|
||||
IncubateOutputs: func(chanPoint wire.OutPoint,
|
||||
outHtlcRes *lnwallet.OutgoingHtlcResolution,
|
||||
inHtlcRes *lnwallet.IncomingHtlcResolution,
|
||||
outHtlcRes fn.Option[lnwallet.OutgoingHtlcResolution],
|
||||
inHtlcRes fn.Option[lnwallet.IncomingHtlcResolution],
|
||||
broadcastHeight uint32) error {
|
||||
|
||||
var (
|
||||
inRes []lnwallet.IncomingHtlcResolution
|
||||
outRes []lnwallet.OutgoingHtlcResolution
|
||||
)
|
||||
if inHtlcRes != nil {
|
||||
inRes = append(inRes, *inHtlcRes)
|
||||
}
|
||||
if outHtlcRes != nil {
|
||||
outRes = append(outRes, *outHtlcRes)
|
||||
}
|
||||
|
||||
return s.utxoNursery.IncubateOutputs(
|
||||
chanPoint, outRes, inRes,
|
||||
chanPoint, outHtlcRes, inHtlcRes,
|
||||
broadcastHeight,
|
||||
)
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user