mirror of
https://github.com/lightningnetwork/lnd.git
synced 2026-08-13 12:32:48 +02:00
contractcourt: retain deadline across contest resolution
Forward the supplied incoming HTLC expiry from the outgoing contest resolver to its embedded timeout resolver. This keeps the deadline available when resolution transitions after the outgoing HTLC expires.
This commit is contained in:
parent
f4ae565619
commit
f77606851f
2 changed files with 41 additions and 2 deletions
|
|
@ -230,10 +230,14 @@ func (h *htlcOutgoingContestResolver) Encode(w io.Writer) error {
|
|||
return h.htlcTimeoutResolver.Encode(w)
|
||||
}
|
||||
|
||||
// SupplementDeadline does nothing for an incoming htlc resolver.
|
||||
// SupplementDeadline forwards the incoming HTLC's expiry height to the inner
|
||||
// timeout resolver. This resolver morphs into that timeout resolver once the
|
||||
// outgoing HTLC expires on-chain, so the deadline is retained across the
|
||||
// transition.
|
||||
//
|
||||
// NOTE: Part of the htlcContractResolver interface.
|
||||
func (h *htlcOutgoingContestResolver) SupplementDeadline(_ fn.Option[int32]) {
|
||||
func (h *htlcOutgoingContestResolver) SupplementDeadline(d fn.Option[int32]) {
|
||||
h.htlcTimeoutResolver.SupplementDeadline(d)
|
||||
}
|
||||
|
||||
// newOutgoingContestResolverFromReader attempts to decode an encoded ContractResolver
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/btcsuite/btcd/wire/v2"
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/fn/v2"
|
||||
"github.com/lightningnetwork/lnd/graph/db/models"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/kvdb"
|
||||
|
|
@ -20,6 +21,10 @@ import (
|
|||
|
||||
const (
|
||||
outgoingContestHtlcExpiry = 110
|
||||
|
||||
// outgoingContestIncomingHtlcExpiry is kept distinct from the outgoing
|
||||
// HTLC expiry to verify that the supplied value is retained.
|
||||
outgoingContestIncomingHtlcExpiry = 144
|
||||
)
|
||||
|
||||
// TestHtlcOutgoingResolverTimeout tests resolution of an offered htlc that
|
||||
|
|
@ -116,6 +121,36 @@ type resolveResult struct {
|
|||
nextResolver ContractResolver
|
||||
}
|
||||
|
||||
// TestHtlcOutgoingResolverSupplementDeadline checks that the outgoing contest
|
||||
// resolver forwards the incoming HTLC deadline to the timeout resolver it
|
||||
// transitions into once the outgoing HTLC expires on-chain.
|
||||
func TestHtlcOutgoingResolverSupplementDeadline(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer timeout()()
|
||||
|
||||
ctx := newOutgoingResolverTestContext(t)
|
||||
|
||||
// Initially the embedded timeout resolver carries no deadline.
|
||||
require.True(t, ctx.resolver.incomingHTLCExpiryHeight.IsNone())
|
||||
|
||||
// Supply the deadline through the contest resolver, as the channel
|
||||
// arbitrator does when constructing the resolver.
|
||||
deadline := fn.Some(int32(outgoingContestIncomingHtlcExpiry))
|
||||
ctx.resolver.SupplementDeadline(deadline)
|
||||
|
||||
// Drive the contest resolver to the point where it returns the embedded
|
||||
// timeout resolver.
|
||||
ctx.resolve()
|
||||
ctx.notifyEpoch(outgoingContestHtlcExpiry)
|
||||
|
||||
result := <-ctx.resolverResultChan
|
||||
require.NoError(t, result.err)
|
||||
|
||||
timeoutRes, ok := result.nextResolver.(*htlcTimeoutResolver)
|
||||
require.True(t, ok, "expected htlcTimeoutResolver")
|
||||
require.Equal(t, deadline, timeoutRes.incomingHTLCExpiryHeight)
|
||||
}
|
||||
|
||||
type outgoingResolverTestContext struct {
|
||||
resolver *htlcOutgoingContestResolver
|
||||
notifier *mock.ChainNotifier
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue