contractcourt: persist remote outgoing htlc claim outcome on disk
When a remote peer claims one of our outgoing htlcs on chain, we do not care whether they claimed with multiple stages. We simply store the claim outgome then forget the resolver.
This commit is contained in:
parent
03b76ad9a4
commit
a38dc256fd
@ -52,6 +52,9 @@ const (
|
|||||||
|
|
||||||
// ResolverTypeIncomingHtlc represents resolution of an incoming htlc.
|
// ResolverTypeIncomingHtlc represents resolution of an incoming htlc.
|
||||||
ResolverTypeIncomingHtlc ResolverType = 1
|
ResolverTypeIncomingHtlc ResolverType = 1
|
||||||
|
|
||||||
|
// ResolverTypeOutgoingHtlc represents resolution of an outgoing htlc.
|
||||||
|
ResolverTypeOutgoingHtlc ResolverType = 2
|
||||||
)
|
)
|
||||||
|
|
||||||
// ResolverOutcome indicates the outcome for the resolver that that the contract
|
// ResolverOutcome indicates the outcome for the resolver that that the contract
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/input"
|
"github.com/lightningnetwork/lnd/input"
|
||||||
"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"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -47,12 +48,27 @@ func TestHtlcOutgoingResolverRemoteClaim(t *testing.T) {
|
|||||||
// Setup the resolver with our test resolution and start the resolution
|
// Setup the resolver with our test resolution and start the resolution
|
||||||
// process.
|
// process.
|
||||||
ctx := newOutgoingResolverTestContext(t)
|
ctx := newOutgoingResolverTestContext(t)
|
||||||
|
|
||||||
|
// Replace our mocked checkpoint function with one which will push
|
||||||
|
// reports into a channel for us to consume. We do so on the resolver
|
||||||
|
// level because our test context has already created the resolver.
|
||||||
|
reportChan := make(chan *channeldb.ResolverReport)
|
||||||
|
ctx.resolver.Checkpoint = func(_ ContractResolver,
|
||||||
|
reports ...*channeldb.ResolverReport) error {
|
||||||
|
|
||||||
|
// Send all of our reports into the channel.
|
||||||
|
for _, report := range reports {
|
||||||
|
reportChan <- report
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
ctx.resolve()
|
ctx.resolve()
|
||||||
|
|
||||||
// The remote party sweeps the htlc. Notify our resolver of this event.
|
// The remote party sweeps the htlc. Notify our resolver of this event.
|
||||||
preimage := lntypes.Preimage{}
|
preimage := lntypes.Preimage{}
|
||||||
ctx.notifier.spendChan <- &chainntnfs.SpendDetail{
|
spendTx := &wire.MsgTx{
|
||||||
SpendingTx: &wire.MsgTx{
|
|
||||||
TxIn: []*wire.TxIn{
|
TxIn: []*wire.TxIn{
|
||||||
{
|
{
|
||||||
Witness: [][]byte{
|
Witness: [][]byte{
|
||||||
@ -60,7 +76,13 @@ func TestHtlcOutgoingResolverRemoteClaim(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
|
|
||||||
|
spendHash := spendTx.TxHash()
|
||||||
|
|
||||||
|
ctx.notifier.spendChan <- &chainntnfs.SpendDetail{
|
||||||
|
SpendingTx: spendTx,
|
||||||
|
SpenderTxHash: &spendHash,
|
||||||
}
|
}
|
||||||
|
|
||||||
// We expect the extracted preimage to be added to the witness beacon.
|
// We expect the extracted preimage to be added to the witness beacon.
|
||||||
@ -70,6 +92,17 @@ func TestHtlcOutgoingResolverRemoteClaim(t *testing.T) {
|
|||||||
// circuit.
|
// circuit.
|
||||||
<-ctx.resolutionChan
|
<-ctx.resolutionChan
|
||||||
|
|
||||||
|
// Finally, check that we have a report as expected.
|
||||||
|
expectedReport := &channeldb.ResolverReport{
|
||||||
|
OutPoint: wire.OutPoint{},
|
||||||
|
Amount: 0,
|
||||||
|
ResolverType: channeldb.ResolverTypeOutgoingHtlc,
|
||||||
|
ResolverOutcome: channeldb.ResolverOutcomeClaimed,
|
||||||
|
SpendTxID: &spendHash,
|
||||||
|
}
|
||||||
|
|
||||||
|
assertResolverReport(t, reportChan, expectedReport)
|
||||||
|
|
||||||
// Assert that the resolver finishes without error.
|
// Assert that the resolver finishes without error.
|
||||||
ctx.waitForResult(false)
|
ctx.waitForResult(false)
|
||||||
}
|
}
|
||||||
@ -147,6 +180,7 @@ func newOutgoingResolverTestContext(t *testing.T) *outgoingResolverTestContext {
|
|||||||
contractResolverKit: *newContractResolverKit(cfg),
|
contractResolverKit: *newContractResolverKit(cfg),
|
||||||
htlcResolution: outgoingRes,
|
htlcResolution: outgoingRes,
|
||||||
htlc: channeldb.HTLC{
|
htlc: channeldb.HTLC{
|
||||||
|
Amt: lnwire.MilliSatoshi(testHtlcAmount),
|
||||||
RHash: testResHash,
|
RHash: testResHash,
|
||||||
OnionBlob: testOnionBlob,
|
OnionBlob: testOnionBlob,
|
||||||
},
|
},
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
|
"github.com/btcsuite/btcutil"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
@ -157,7 +158,19 @@ func (h *htlcTimeoutResolver) claimCleanUp(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
h.resolved = true
|
h.resolved = true
|
||||||
return nil, h.Checkpoint(h)
|
|
||||||
|
// Checkpoint our resolver with a report which reflects the preimage
|
||||||
|
// claim by the remote party.
|
||||||
|
amt := btcutil.Amount(h.htlcResolution.SweepSignDesc.Output.Value)
|
||||||
|
report := &channeldb.ResolverReport{
|
||||||
|
OutPoint: h.htlcResolution.ClaimOutpoint,
|
||||||
|
Amount: amt,
|
||||||
|
ResolverType: channeldb.ResolverTypeOutgoingHtlc,
|
||||||
|
ResolverOutcome: channeldb.ResolverOutcomeClaimed,
|
||||||
|
SpendTxID: commitSpend.SpenderTxHash,
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, h.Checkpoint(h, report)
|
||||||
}
|
}
|
||||||
|
|
||||||
// chainDetailsToWatch returns the output and script which we use to watch for
|
// chainDetailsToWatch returns the output and script which we use to watch for
|
||||||
|
Loading…
Reference in New Issue
Block a user