contractcourt: introduce option for commitKey.

This commit is contained in:
ziggie
2024-10-28 12:46:31 +01:00
parent d5e8df7067
commit 59f32682a5
5 changed files with 55 additions and 31 deletions

View File

@@ -1475,16 +1475,23 @@ func decodeBreachResolution(r io.Reader, b *BreachResolution) error {
return binary.Read(r, endian, &b.FundingOutPoint.Index) return binary.Read(r, endian, &b.FundingOutPoint.Index)
} }
func encodeHtlcSetKey(w io.Writer, h *HtlcSetKey) error { func encodeHtlcSetKey(w io.Writer, htlcSetKey HtlcSetKey) error {
err := binary.Write(w, endian, h.IsRemote) err := binary.Write(w, endian, htlcSetKey.IsRemote)
if err != nil { if err != nil {
return err return err
} }
return binary.Write(w, endian, h.IsPending)
return binary.Write(w, endian, htlcSetKey.IsPending)
} }
func encodeCommitSet(w io.Writer, c *CommitSet) error { func encodeCommitSet(w io.Writer, c *CommitSet) error {
if err := encodeHtlcSetKey(w, c.ConfCommitKey); err != nil { confCommitKey, err := c.ConfCommitKey.UnwrapOrErr(
fmt.Errorf("HtlcSetKey is not set"),
)
if err != nil {
return err
}
if err := encodeHtlcSetKey(w, confCommitKey); err != nil {
return err return err
} }
@@ -1494,8 +1501,7 @@ func encodeCommitSet(w io.Writer, c *CommitSet) error {
} }
for htlcSetKey, htlcs := range c.HtlcSets { for htlcSetKey, htlcs := range c.HtlcSets {
htlcSetKey := htlcSetKey if err := encodeHtlcSetKey(w, htlcSetKey); err != nil {
if err := encodeHtlcSetKey(w, &htlcSetKey); err != nil {
return err return err
} }
@@ -1517,13 +1523,14 @@ func decodeHtlcSetKey(r io.Reader, h *HtlcSetKey) error {
} }
func decodeCommitSet(r io.Reader) (*CommitSet, error) { func decodeCommitSet(r io.Reader) (*CommitSet, error) {
c := &CommitSet{ confCommitKey := HtlcSetKey{}
ConfCommitKey: &HtlcSetKey{}, if err := decodeHtlcSetKey(r, &confCommitKey); err != nil {
HtlcSets: make(map[HtlcSetKey][]channeldb.HTLC), return nil, err
} }
if err := decodeHtlcSetKey(r, c.ConfCommitKey); err != nil { c := &CommitSet{
return nil, err ConfCommitKey: fn.Some(confCommitKey),
HtlcSets: make(map[HtlcSetKey][]channeldb.HTLC),
} }
var numSets uint8 var numSets uint8

View File

@@ -14,6 +14,7 @@ import (
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/fn"
"github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/kvdb"
"github.com/lightningnetwork/lnd/lnmock" "github.com/lightningnetwork/lnd/lnmock"
@@ -753,7 +754,7 @@ func TestCommitSetStorage(t *testing.T) {
for _, pendingRemote := range []bool{true, false} { for _, pendingRemote := range []bool{true, false} {
for _, confType := range confTypes { for _, confType := range confTypes {
commitSet := &CommitSet{ commitSet := &CommitSet{
ConfCommitKey: &confType, ConfCommitKey: fn.Some(confType),
HtlcSets: make(map[HtlcSetKey][]channeldb.HTLC), HtlcSets: make(map[HtlcSetKey][]channeldb.HTLC),
} }
commitSet.HtlcSets[LocalHtlcSet] = activeHTLCs commitSet.HtlcSets[LocalHtlcSet] = activeHTLCs

View File

@@ -93,9 +93,9 @@ type BreachCloseInfo struct {
// HTLCs to determine if any additional actions need to be made based on the // HTLCs to determine if any additional actions need to be made based on the
// remote party's commitments. // remote party's commitments.
type CommitSet struct { type CommitSet struct {
// ConfCommitKey if non-nil, identifies the commitment that was // When the ConfCommitKey is set, it signals that the commitment tx was
// confirmed in the chain. // confirmed in the chain.
ConfCommitKey *HtlcSetKey ConfCommitKey fn.Option[HtlcSetKey]
// HtlcSets stores the set of all known active HTLC for each active // HtlcSets stores the set of all known active HTLC for each active
// commitment at the time of channel closure. // commitment at the time of channel closure.
@@ -509,7 +509,7 @@ func (c *chainWatcher) handleUnknownLocalState(
// If this is our commitment transaction, then we try to act even // If this is our commitment transaction, then we try to act even
// though we won't be able to sweep HTLCs. // though we won't be able to sweep HTLCs.
chainSet.commitSet.ConfCommitKey = &LocalHtlcSet chainSet.commitSet.ConfCommitKey = fn.Some(LocalHtlcSet)
if err := c.dispatchLocalForceClose( if err := c.dispatchLocalForceClose(
commitSpend, broadcastStateNum, chainSet.commitSet, commitSpend, broadcastStateNum, chainSet.commitSet,
); err != nil { ); err != nil {
@@ -806,7 +806,7 @@ func (c *chainWatcher) handleKnownLocalState(
return false, nil return false, nil
} }
chainSet.commitSet.ConfCommitKey = &LocalHtlcSet chainSet.commitSet.ConfCommitKey = fn.Some(LocalHtlcSet)
if err := c.dispatchLocalForceClose( if err := c.dispatchLocalForceClose(
commitSpend, broadcastStateNum, chainSet.commitSet, commitSpend, broadcastStateNum, chainSet.commitSet,
); err != nil { ); err != nil {
@@ -844,7 +844,7 @@ func (c *chainWatcher) handleKnownRemoteState(
log.Infof("Remote party broadcast base set, "+ log.Infof("Remote party broadcast base set, "+
"commit_num=%v", chainSet.remoteStateNum) "commit_num=%v", chainSet.remoteStateNum)
chainSet.commitSet.ConfCommitKey = &RemoteHtlcSet chainSet.commitSet.ConfCommitKey = fn.Some(RemoteHtlcSet)
err := c.dispatchRemoteForceClose( err := c.dispatchRemoteForceClose(
commitSpend, chainSet.remoteCommit, commitSpend, chainSet.remoteCommit,
chainSet.commitSet, chainSet.commitSet,
@@ -869,7 +869,7 @@ func (c *chainWatcher) handleKnownRemoteState(
log.Infof("Remote party broadcast pending set, "+ log.Infof("Remote party broadcast pending set, "+
"commit_num=%v", chainSet.remoteStateNum+1) "commit_num=%v", chainSet.remoteStateNum+1)
chainSet.commitSet.ConfCommitKey = &RemotePendingHtlcSet chainSet.commitSet.ConfCommitKey = fn.Some(RemotePendingHtlcSet)
err := c.dispatchRemoteForceClose( err := c.dispatchRemoteForceClose(
commitSpend, *chainSet.remotePendingCommit, commitSpend, *chainSet.remotePendingCommit,
chainSet.commitSet, chainSet.commitSet,
@@ -936,7 +936,7 @@ func (c *chainWatcher) handlePossibleBreach(commitSpend *chainntnfs.SpendDetail,
// only used to ensure a nil-pointer-dereference doesn't occur and is // only used to ensure a nil-pointer-dereference doesn't occur and is
// not used otherwise. The HTLC's may not exist for the // not used otherwise. The HTLC's may not exist for the
// RemotePendingHtlcSet. // RemotePendingHtlcSet.
chainSet.commitSet.ConfCommitKey = &RemoteHtlcSet chainSet.commitSet.ConfCommitKey = fn.Some(RemoteHtlcSet)
// THEY'RE ATTEMPTING TO VIOLATE THE CONTRACT LAID OUT WITHIN THE // THEY'RE ATTEMPTING TO VIOLATE THE CONTRACT LAID OUT WITHIN THE
// PAYMENT CHANNEL. Therefore we close the signal indicating a revoked // PAYMENT CHANNEL. Therefore we close the signal indicating a revoked
@@ -997,7 +997,7 @@ func (c *chainWatcher) handleUnknownRemoteState(
// means we won't be able to recover any HTLC funds. // means we won't be able to recover any HTLC funds.
// //
// TODO(halseth): can we try to recover some HTLCs? // TODO(halseth): can we try to recover some HTLCs?
chainSet.commitSet.ConfCommitKey = &RemoteHtlcSet chainSet.commitSet.ConfCommitKey = fn.Some(RemoteHtlcSet)
err := c.dispatchRemoteForceClose( err := c.dispatchRemoteForceClose(
commitSpend, channeldb.ChannelCommitment{}, commitSpend, channeldb.ChannelCommitment{},
chainSet.commitSet, commitPoint, chainSet.commitSet, commitPoint,

View File

@@ -682,8 +682,14 @@ func (c *ChannelArbitrator) relaunchResolvers(commitSet *CommitSet,
// chain actions may exclude some information, but we cannot recover it // chain actions may exclude some information, but we cannot recover it
// for these older nodes at the moment. // for these older nodes at the moment.
var confirmedHTLCs []channeldb.HTLC var confirmedHTLCs []channeldb.HTLC
if commitSet != nil && commitSet.ConfCommitKey != nil { if commitSet != nil && commitSet.ConfCommitKey.IsSome() {
confirmedHTLCs = commitSet.HtlcSets[*commitSet.ConfCommitKey] confCommitKey, err := commitSet.ConfCommitKey.UnwrapOrErr(
fmt.Errorf("no commitKey available"),
)
if err != nil {
return err
}
confirmedHTLCs = commitSet.HtlcSets[confCommitKey]
} else { } else {
chainActions, err := c.log.FetchChainActions() chainActions, err := c.log.FetchChainActions()
if err != nil { if err != nil {
@@ -2223,15 +2229,21 @@ func (c *ChannelArbitrator) constructChainActions(confCommitSet *CommitSet,
// then this is an older node that had a pending close channel before // then this is an older node that had a pending close channel before
// the CommitSet was introduced. In this case, we'll just return the // the CommitSet was introduced. In this case, we'll just return the
// existing ChainActionMap they had on disk. // existing ChainActionMap they had on disk.
if confCommitSet == nil || confCommitSet.ConfCommitKey == nil { if confCommitSet == nil || confCommitSet.ConfCommitKey.IsNone() {
return c.log.FetchChainActions() return c.log.FetchChainActions()
} }
// Otherwise, we have the full commitment set written to disk, and can // Otherwise, we have the full commitment set written to disk, and can
// proceed as normal. // proceed as normal.
htlcSets := confCommitSet.toActiveHTLCSets() htlcSets := confCommitSet.toActiveHTLCSets()
switch *confCommitSet.ConfCommitKey { confCommitKey, err := confCommitSet.ConfCommitKey.UnwrapOrErr(
fmt.Errorf("no commitKey available"),
)
if err != nil {
return nil, err
}
switch confCommitKey {
// If the local commitment transaction confirmed, then we'll examine // If the local commitment transaction confirmed, then we'll examine
// that as well as their commitments to the set of chain actions. // that as well as their commitments to the set of chain actions.
case LocalHtlcSet: case LocalHtlcSet:

View File

@@ -590,7 +590,7 @@ func TestChannelArbitratorRemoteForceClose(t *testing.T) {
chanArb.cfg.ChainEvents.RemoteUnilateralClosure <- &RemoteUnilateralCloseInfo{ chanArb.cfg.ChainEvents.RemoteUnilateralClosure <- &RemoteUnilateralCloseInfo{
UnilateralCloseSummary: uniClose, UnilateralCloseSummary: uniClose,
CommitSet: CommitSet{ CommitSet: CommitSet{
ConfCommitKey: &RemoteHtlcSet, ConfCommitKey: fn.Some(RemoteHtlcSet),
HtlcSets: make(map[HtlcSetKey][]channeldb.HTLC), HtlcSets: make(map[HtlcSetKey][]channeldb.HTLC),
}, },
} }
@@ -777,7 +777,7 @@ func TestChannelArbitratorBreachClose(t *testing.T) {
}, },
AnchorResolution: anchorRes, AnchorResolution: anchorRes,
CommitSet: CommitSet{ CommitSet: CommitSet{
ConfCommitKey: &RemoteHtlcSet, ConfCommitKey: fn.Some(RemoteHtlcSet),
HtlcSets: map[HtlcSetKey][]channeldb.HTLC{ HtlcSets: map[HtlcSetKey][]channeldb.HTLC{
RemoteHtlcSet: {htlc1, htlc2}, RemoteHtlcSet: {htlc1, htlc2},
}, },
@@ -999,7 +999,7 @@ func TestChannelArbitratorLocalForceClosePendingHtlc(t *testing.T) {
}, },
ChannelCloseSummary: &channeldb.ChannelCloseSummary{}, ChannelCloseSummary: &channeldb.ChannelCloseSummary{},
CommitSet: CommitSet{ CommitSet: CommitSet{
ConfCommitKey: &LocalHtlcSet, ConfCommitKey: fn.Some(LocalHtlcSet),
HtlcSets: map[HtlcSetKey][]channeldb.HTLC{ HtlcSets: map[HtlcSetKey][]channeldb.HTLC{
LocalHtlcSet: htlcSet, LocalHtlcSet: htlcSet,
}, },
@@ -1527,7 +1527,7 @@ func TestChannelArbitratorForceCloseBreachedChannel(t *testing.T) {
}, },
} }
log.commitSet = &CommitSet{ log.commitSet = &CommitSet{
ConfCommitKey: &RemoteHtlcSet, ConfCommitKey: fn.Some(RemoteHtlcSet),
HtlcSets: map[HtlcSetKey][]channeldb.HTLC{ HtlcSets: map[HtlcSetKey][]channeldb.HTLC{
RemoteHtlcSet: {}, RemoteHtlcSet: {},
}, },
@@ -1954,8 +1954,12 @@ func TestChannelArbitratorDanglingCommitForceClose(t *testing.T) {
}, },
ChannelCloseSummary: &channeldb.ChannelCloseSummary{}, ChannelCloseSummary: &channeldb.ChannelCloseSummary{},
CommitSet: CommitSet{ CommitSet: CommitSet{
ConfCommitKey: &testCase.confCommit, ConfCommitKey: fn.Some(
HtlcSets: make(map[HtlcSetKey][]channeldb.HTLC), testCase.confCommit,
),
HtlcSets: make(
map[HtlcSetKey][]channeldb.HTLC,
),
}, },
} }
@@ -2875,7 +2879,7 @@ func TestChannelArbitratorAnchors(t *testing.T) {
}, },
ChannelCloseSummary: &channeldb.ChannelCloseSummary{}, ChannelCloseSummary: &channeldb.ChannelCloseSummary{},
CommitSet: CommitSet{ CommitSet: CommitSet{
ConfCommitKey: &LocalHtlcSet, ConfCommitKey: fn.Some(LocalHtlcSet),
HtlcSets: map[HtlcSetKey][]channeldb.HTLC{}, HtlcSets: map[HtlcSetKey][]channeldb.HTLC{},
}, },
} }