contractcourt: add Launch method to outgoing contest resolver
This commit is contained in:
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,
|
||||||
|
|||||||
Reference in new issue
Block a user