contractcourt: add Launch method to outgoing contest resolver

This commit is contained in:
yyforyongyu committed 2024-12-20 17:54:05 +08:00
1 parent ef98c52d10
commit 47722292c5
2 files changed
+45 -5

No files matched your search

@@ -1,7 +1,6 @@
package contractcourt package contractcourt
import ( import (
"fmt"
"io" "io"
"github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/btcutil"
@@ -36,6 +35,37 @@ func newOutgoingContestResolver(res lnwallet.OutgoingHtlcResolution,
} }
} }
// Launch will call the inner resolver's launch method if the expiry height has
// been reached, otherwise it's a no-op.
func (h *htlcOutgoingContestResolver) Launch() error {
// NOTE: we don't mark this resolver as launched as the inner resolver
// will set it when it's launched.
if h.launched {
h.log.Tracef("already launched")
return nil
}
h.log.Debugf("launching contest resolver...")
_, bestHeight, err := h.ChainIO.GetBestBlock()
if err != nil {
return err
}
if uint32(bestHeight) < h.htlcResolution.Expiry {
return nil
}
// If the current height is >= expiry, then a timeout path spend will
// be valid to be included in the next block, and we can immediately
// return the resolver.
h.log.Infof("expired (height=%v, expiry=%v), transforming into "+
"timeout resolver and launching it", bestHeight,
h.htlcResolution.Expiry)
return h.htlcTimeoutResolver.Launch()
}
// Resolve commences the resolution of this contract. As this contract hasn't // Resolve commences the resolution of this contract. As this contract hasn't
// yet timed out, we'll wait for one of two things to happen // yet timed out, we'll wait for one of two things to happen
// //
@@ -53,6 +83,7 @@ func (h *htlcOutgoingContestResolver) Resolve() (ContractResolver, error) {
// If we're already full resolved, then we don't have anything further // If we're already full resolved, then we don't have anything further
// to do. // to do.
if h.resolved { if h.resolved {
h.log.Errorf("already resolved")
return nil, nil return nil, nil
} }
@@ -86,7 +117,6 @@ func (h *htlcOutgoingContestResolver) Resolve() (ContractResolver, error) {
return nil, errResolverShuttingDown return nil, errResolverShuttingDown
} }
// TODO(roasbeef): Checkpoint?
return nil, h.claimCleanUp(commitSpend) return nil, h.claimCleanUp(commitSpend)
// If it hasn't, then we'll watch for both the expiration, and the // If it hasn't, then we'll watch for both the expiration, and the
@@ -124,12 +154,14 @@ func (h *htlcOutgoingContestResolver) Resolve() (ContractResolver, error) {
// finalized` will be returned and the broadcast will // finalized` will be returned and the broadcast will
// fail. // fail.
newHeight := uint32(newBlock.Height) newHeight := uint32(newBlock.Height)
if newHeight >= h.htlcResolution.Expiry { expiry := h.htlcResolution.Expiry
log.Infof("%T(%v): HTLC has expired "+ if newHeight >= expiry {
h.log.Infof("HTLC about to expire "+
"(height=%v, expiry=%v), transforming "+ "(height=%v, expiry=%v), transforming "+
"into timeout resolver", h, "into timeout resolver", h,
h.htlcResolution.ClaimOutpoint, h.htlcResolution.ClaimOutpoint,
newHeight, h.htlcResolution.Expiry) newHeight, h.htlcResolution.Expiry)
return h.htlcTimeoutResolver, nil return h.htlcTimeoutResolver, nil
} }
@@ -147,7 +179,7 @@ func (h *htlcOutgoingContestResolver) Resolve() (ContractResolver, error) {
return nil, h.claimCleanUp(commitSpend) return nil, h.claimCleanUp(commitSpend)
case <-h.quit: case <-h.quit:
return nil, fmt.Errorf("resolver canceled") return nil, errResolverShuttingDown
} }
} }
} }
@@ -178,6 +210,8 @@ func (h *htlcOutgoingContestResolver) report() *ContractReport {
// //
// NOTE: Part of the ContractResolver interface. // NOTE: Part of the ContractResolver interface.
func (h *htlcOutgoingContestResolver) Stop() { func (h *htlcOutgoingContestResolver) Stop() {
h.log.Debugf("stopping...")
defer h.log.Debugf("stopped")
close(h.quit) close(h.quit)
} }
@@ -15,6 +15,7 @@ import (
"github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
"github.com/stretchr/testify/require"
) )
const ( const (
@@ -159,6 +160,7 @@ func newOutgoingResolverTestContext(t *testing.T) *outgoingResolverTestContext {
return nil return nil
}, },
ChainIO: &mock.ChainIO{},
}, },
PutResolverReport: func(_ kvdb.RwTx, PutResolverReport: func(_ kvdb.RwTx,
_ *channeldb.ResolverReport) error { _ *channeldb.ResolverReport) error {
@@ -195,6 +197,7 @@ func newOutgoingResolverTestContext(t *testing.T) *outgoingResolverTestContext {
}, },
}, },
} }
resolver.initLogger("htlcOutgoingContestResolver")
return &outgoingResolverTestContext{ return &outgoingResolverTestContext{
resolver: resolver, resolver: resolver,
@@ -209,6 +212,9 @@ func (i *outgoingResolverTestContext) resolve() {
// Start resolver. // Start resolver.
i.resolverResultChan = make(chan resolveResult, 1) i.resolverResultChan = make(chan resolveResult, 1)
go func() { go func() {
err := i.resolver.Launch()
require.NoError(i.t, err)
nextResolver, err := i.resolver.Resolve() nextResolver, err := i.resolver.Resolve()
i.resolverResultChan <- resolveResult{ i.resolverResultChan <- resolveResult{
nextResolver: nextResolver, nextResolver: nextResolver,