Skip to content

Commit f9d876e

Browse files
committed
Merge branch '0-18-4-branch-rc1-9253' into 0-18-4-branch-rc1
2 parents 78c8990 + a421125 commit f9d876e

File tree

10 files changed

+205
-69
lines changed

10 files changed

+205
-69
lines changed

contractcourt/chain_arbitrator.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -335,11 +335,10 @@ func (a *arbChannel) NewAnchorResolutions() (*lnwallet.AnchorResolutions,
335335
// ForceCloseChan should force close the contract that this attendant is
336336
// watching over. We'll use this when we decide that we need to go to chain. It
337337
// should in addition tell the switch to remove the corresponding link, such
338-
// that we won't accept any new updates. The returned summary contains all items
339-
// needed to eventually resolve all outputs on chain.
338+
// that we won't accept any new updates.
340339
//
341340
// NOTE: Part of the ArbChannel interface.
342-
func (a *arbChannel) ForceCloseChan() (*lnwallet.LocalForceCloseSummary, error) {
341+
func (a *arbChannel) ForceCloseChan() (*wire.MsgTx, error) {
343342
// First, we mark the channel as borked, this ensure
344343
// that no new state transitions can happen, and also
345344
// that the link won't be loaded into the switch.
@@ -386,7 +385,15 @@ func (a *arbChannel) ForceCloseChan() (*lnwallet.LocalForceCloseSummary, error)
386385
if err != nil {
387386
return nil, err
388387
}
389-
return chanMachine.ForceClose()
388+
389+
closeSummary, err := chanMachine.ForceClose(
390+
lnwallet.WithSkipContractResolutions(),
391+
)
392+
if err != nil {
393+
return nil, err
394+
}
395+
396+
return closeSummary.CloseTx, nil
390397
}
391398

392399
// newActiveChannelArbitrator creates a new instance of an active channel

contractcourt/chain_watcher.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,16 +1175,29 @@ func (c *chainWatcher) dispatchLocalForceClose(
11751175
LocalChanConfig: c.cfg.chanState.LocalChanCfg,
11761176
}
11771177

1178+
resolutions, err := forceClose.ContractResolutions.UnwrapOrErr(
1179+
fmt.Errorf("resolutions not found"),
1180+
)
1181+
if err != nil {
1182+
return err
1183+
}
1184+
11781185
// If our commitment output isn't dust or we have active HTLC's on the
11791186
// commitment transaction, then we'll populate the balances on the
11801187
// close channel summary.
1181-
if forceClose.CommitResolution != nil {
1182-
closeSummary.SettledBalance = chanSnapshot.LocalBalance.ToSatoshis()
1183-
closeSummary.TimeLockedBalance = chanSnapshot.LocalBalance.ToSatoshis()
1188+
if resolutions.CommitResolution != nil {
1189+
localBalance := chanSnapshot.LocalBalance.ToSatoshis()
1190+
closeSummary.SettledBalance = localBalance
1191+
closeSummary.TimeLockedBalance = localBalance
11841192
}
1185-
for _, htlc := range forceClose.HtlcResolutions.OutgoingHTLCs {
1186-
htlcValue := btcutil.Amount(htlc.SweepSignDesc.Output.Value)
1187-
closeSummary.TimeLockedBalance += htlcValue
1193+
1194+
if resolutions.HtlcResolutions != nil {
1195+
for _, htlc := range resolutions.HtlcResolutions.OutgoingHTLCs {
1196+
htlcValue := btcutil.Amount(
1197+
htlc.SweepSignDesc.Output.Value,
1198+
)
1199+
closeSummary.TimeLockedBalance += htlcValue
1200+
}
11881201
}
11891202

11901203
// Attempt to add a channel sync message to the close summary.

contractcourt/chain_watcher_test.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -504,14 +504,24 @@ func TestChainWatcherLocalForceCloseDetect(t *testing.T) {
504504
// outputs.
505505
select {
506506
case summary := <-chanEvents.LocalUnilateralClosure:
507+
resOpt := summary.LocalForceCloseSummary.
508+
ContractResolutions
509+
510+
resolutions, err := resOpt.UnwrapOrErr(
511+
fmt.Errorf("resolutions not found"),
512+
)
513+
if err != nil {
514+
t.Fatalf("unable to get resolutions: %v", err)
515+
}
516+
507517
// Make sure we correctly extracted the commit
508518
// resolution if we had a local output.
509519
if remoteOutputOnly {
510-
if summary.CommitResolution != nil {
520+
if resolutions.CommitResolution != nil {
511521
t.Fatalf("expected no commit resolution")
512522
}
513523
} else {
514-
if summary.CommitResolution == nil {
524+
if resolutions.CommitResolution == nil {
515525
t.Fatalf("expected commit resolution")
516526
}
517527
}

contractcourt/channel_arbitrator.go

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ type ArbChannel interface {
9898
// corresponding link, such that we won't accept any new updates. The
9999
// returned summary contains all items needed to eventually resolve all
100100
// outputs on chain.
101-
ForceCloseChan() (*lnwallet.LocalForceCloseSummary, error)
101+
ForceCloseChan() (*wire.MsgTx, error)
102102

103103
// NewAnchorResolutions returns the anchor resolutions for currently
104104
// valid commitment transactions.
@@ -1058,7 +1058,7 @@ func (c *ChannelArbitrator) stateStep(
10581058
// We'll tell the switch that it should remove the link for
10591059
// this channel, in addition to fetching the force close
10601060
// summary needed to close this channel on chain.
1061-
closeSummary, err := c.cfg.Channel.ForceCloseChan()
1061+
forceCloseTx, err := c.cfg.Channel.ForceCloseChan()
10621062
if err != nil {
10631063
log.Errorf("ChannelArbitrator(%v): unable to "+
10641064
"force close: %v", c.cfg.ChanPoint, err)
@@ -1078,7 +1078,7 @@ func (c *ChannelArbitrator) stateStep(
10781078

10791079
return StateError, closeTx, err
10801080
}
1081-
closeTx = closeSummary.CloseTx
1081+
closeTx = forceCloseTx
10821082

10831083
// Before publishing the transaction, we store it to the
10841084
// database, such that we can re-publish later in case it
@@ -2871,11 +2871,36 @@ func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
28712871
}
28722872
closeTx := closeInfo.CloseTx
28732873

2874+
resolutions, err := closeInfo.ContractResolutions.
2875+
UnwrapOrErr(
2876+
fmt.Errorf("resolutions not found"),
2877+
)
2878+
if err != nil {
2879+
log.Errorf("ChannelArbitrator(%v): unable to "+
2880+
"get resolutions: %v", c.cfg.ChanPoint,
2881+
err)
2882+
2883+
return
2884+
}
2885+
2886+
// We make sure that the htlc resolutions are present
2887+
// otherwise we would panic dereferencing the pointer.
2888+
//
2889+
// TODO(ziggie): Refactor ContractResolutions to use
2890+
// options.
2891+
if resolutions.HtlcResolutions == nil {
2892+
log.Errorf("ChannelArbitrator(%v): htlc "+
2893+
"resolutions not found",
2894+
c.cfg.ChanPoint)
2895+
2896+
return
2897+
}
2898+
28742899
contractRes := &ContractResolutions{
28752900
CommitHash: closeTx.TxHash(),
2876-
CommitResolution: closeInfo.CommitResolution,
2877-
HtlcResolutions: *closeInfo.HtlcResolutions,
2878-
AnchorResolution: closeInfo.AnchorResolution,
2901+
CommitResolution: resolutions.CommitResolution,
2902+
HtlcResolutions: *resolutions.HtlcResolutions,
2903+
AnchorResolution: resolutions.AnchorResolution,
28792904
}
28802905

28812906
// When processing a unilateral close event, we'll
@@ -2884,7 +2909,7 @@ func (c *ChannelArbitrator) channelAttendant(bestHeight int32) {
28842909
// available to fetch in that state, we'll also write
28852910
// the commit set so we can reconstruct our chain
28862911
// actions on restart.
2887-
err := c.log.LogContractResolutions(contractRes)
2912+
err = c.log.LogContractResolutions(contractRes)
28882913
if err != nil {
28892914
log.Errorf("Unable to write resolutions: %v",
28902915
err)

contractcourt/channel_arbitrator_test.go

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -693,11 +693,15 @@ func TestChannelArbitratorLocalForceClose(t *testing.T) {
693693
chanArbCtx.AssertState(StateCommitmentBroadcasted)
694694

695695
// Now notify about the local force close getting confirmed.
696+
//
697+
//nolint:lll
696698
chanArb.cfg.ChainEvents.LocalUnilateralClosure <- &LocalUnilateralCloseInfo{
697699
SpendDetail: &chainntnfs.SpendDetail{},
698700
LocalForceCloseSummary: &lnwallet.LocalForceCloseSummary{
699-
CloseTx: &wire.MsgTx{},
700-
HtlcResolutions: &lnwallet.HtlcResolutions{},
701+
CloseTx: &wire.MsgTx{},
702+
ContractResolutions: fn.Some(lnwallet.ContractResolutions{
703+
HtlcResolutions: &lnwallet.HtlcResolutions{},
704+
}),
701705
},
702706
ChannelCloseSummary: &channeldb.ChannelCloseSummary{},
703707
}
@@ -969,15 +973,18 @@ func TestChannelArbitratorLocalForceClosePendingHtlc(t *testing.T) {
969973
},
970974
}
971975

976+
//nolint:lll
972977
chanArb.cfg.ChainEvents.LocalUnilateralClosure <- &LocalUnilateralCloseInfo{
973978
SpendDetail: &chainntnfs.SpendDetail{},
974979
LocalForceCloseSummary: &lnwallet.LocalForceCloseSummary{
975980
CloseTx: closeTx,
976-
HtlcResolutions: &lnwallet.HtlcResolutions{
977-
OutgoingHTLCs: []lnwallet.OutgoingHtlcResolution{
978-
outgoingRes,
981+
ContractResolutions: fn.Some(lnwallet.ContractResolutions{
982+
HtlcResolutions: &lnwallet.HtlcResolutions{
983+
OutgoingHTLCs: []lnwallet.OutgoingHtlcResolution{
984+
outgoingRes,
985+
},
979986
},
980-
},
987+
}),
981988
},
982989
ChannelCloseSummary: &channeldb.ChannelCloseSummary{},
983990
CommitSet: CommitSet{
@@ -1611,12 +1618,15 @@ func TestChannelArbitratorCommitFailure(t *testing.T) {
16111618
},
16121619
{
16131620
closeType: channeldb.LocalForceClose,
1621+
//nolint:lll
16141622
sendEvent: func(chanArb *ChannelArbitrator) {
16151623
chanArb.cfg.ChainEvents.LocalUnilateralClosure <- &LocalUnilateralCloseInfo{
16161624
SpendDetail: &chainntnfs.SpendDetail{},
16171625
LocalForceCloseSummary: &lnwallet.LocalForceCloseSummary{
1618-
CloseTx: &wire.MsgTx{},
1619-
HtlcResolutions: &lnwallet.HtlcResolutions{},
1626+
CloseTx: &wire.MsgTx{},
1627+
ContractResolutions: fn.Some(lnwallet.ContractResolutions{
1628+
HtlcResolutions: &lnwallet.HtlcResolutions{},
1629+
}),
16201630
},
16211631
ChannelCloseSummary: &channeldb.ChannelCloseSummary{},
16221632
}
@@ -1944,11 +1954,15 @@ func TestChannelArbitratorDanglingCommitForceClose(t *testing.T) {
19441954
// being canalled back. Also note that there're no HTLC
19451955
// resolutions sent since we have none on our
19461956
// commitment transaction.
1957+
//
1958+
//nolint:lll
19471959
uniCloseInfo := &LocalUnilateralCloseInfo{
19481960
SpendDetail: &chainntnfs.SpendDetail{},
19491961
LocalForceCloseSummary: &lnwallet.LocalForceCloseSummary{
1950-
CloseTx: closeTx,
1951-
HtlcResolutions: &lnwallet.HtlcResolutions{},
1962+
CloseTx: closeTx,
1963+
ContractResolutions: fn.Some(lnwallet.ContractResolutions{
1964+
HtlcResolutions: &lnwallet.HtlcResolutions{},
1965+
}),
19521966
},
19531967
ChannelCloseSummary: &channeldb.ChannelCloseSummary{},
19541968
CommitSet: CommitSet{
@@ -2754,12 +2768,15 @@ func TestChannelArbitratorAnchors(t *testing.T) {
27542768
},
27552769
}
27562770

2771+
//nolint:lll
27572772
chanArb.cfg.ChainEvents.LocalUnilateralClosure <- &LocalUnilateralCloseInfo{
27582773
SpendDetail: &chainntnfs.SpendDetail{},
27592774
LocalForceCloseSummary: &lnwallet.LocalForceCloseSummary{
2760-
CloseTx: closeTx,
2761-
HtlcResolutions: &lnwallet.HtlcResolutions{},
2762-
AnchorResolution: anchorResolution,
2775+
CloseTx: closeTx,
2776+
ContractResolutions: fn.Some(lnwallet.ContractResolutions{
2777+
HtlcResolutions: &lnwallet.HtlcResolutions{},
2778+
AnchorResolution: anchorResolution,
2779+
}),
27632780
},
27642781
ChannelCloseSummary: &channeldb.ChannelCloseSummary{},
27652782
CommitSet: CommitSet{
@@ -2993,14 +3010,10 @@ func (m *mockChannel) NewAnchorResolutions() (*lnwallet.AnchorResolutions,
29933010
return &lnwallet.AnchorResolutions{}, nil
29943011
}
29953012

2996-
func (m *mockChannel) ForceCloseChan() (*lnwallet.LocalForceCloseSummary, error) {
3013+
func (m *mockChannel) ForceCloseChan() (*wire.MsgTx, error) {
29973014
if m.forceCloseErr != nil {
29983015
return nil, m.forceCloseErr
29993016
}
30003017

3001-
summary := &lnwallet.LocalForceCloseSummary{
3002-
CloseTx: &wire.MsgTx{},
3003-
HtlcResolutions: &lnwallet.HtlcResolutions{},
3004-
}
3005-
return summary, nil
3018+
return &wire.MsgTx{}, nil
30063019
}

docs/release-notes/release-notes-0.18.4.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
cause a nil pointer dereference during the probing of a payment request that
2424
does not contain a payment address.
2525

26+
* [Make the contract resolutions for the channel arbitrator optional](
27+
https://github.com/lightningnetwork/lnd/pull/9253).
28+
2629
# New Features
2730

2831
The main channel state machine and database now allow for processing and storing

0 commit comments

Comments
 (0)