multi: refactor NewAnchorResolutions to return fixed values

This commit adds a new struct AnchorResolutions which wraps the anchor
resolutions for local/remote/pending remote commitment transactions. It
is then returned from NewAnchorResolutions. Thus the caller knows how to
retrieve a certain anchor resolution.
This commit is contained in:
yyforyongyu 2021-05-06 19:53:11 +08:00
parent 21626fed7c
commit adddc1442e
No known key found for this signature in database
GPG Key ID: 9BCD95C4FF296868
5 changed files with 49 additions and 29 deletions

@ -241,7 +241,7 @@ type arbChannel struct {
// commitment transactions. // commitment transactions.
// //
// NOTE: Part of the ArbChannel interface. // NOTE: Part of the ArbChannel interface.
func (a *arbChannel) NewAnchorResolutions() ([]*lnwallet.AnchorResolution, func (a *arbChannel) NewAnchorResolutions() (*lnwallet.AnchorResolutions,
error) { error) {
// Get a fresh copy of the database state to base the anchor resolutions // Get a fresh copy of the database state to base the anchor resolutions

@ -91,7 +91,7 @@ type ArbChannel interface {
// NewAnchorResolutions returns the anchor resolutions for currently // NewAnchorResolutions returns the anchor resolutions for currently
// valid commitment transactions. // valid commitment transactions.
NewAnchorResolutions() ([]*lnwallet.AnchorResolution, error) NewAnchorResolutions() (*lnwallet.AnchorResolutions, error)
} }
// ChannelArbitratorConfig contains all the functionality that the // ChannelArbitratorConfig contains all the functionality that the
@ -1087,14 +1087,18 @@ func (c *ChannelArbitrator) stateStep(
// sweepAnchors offers all given anchor resolutions to the sweeper. It requests // sweepAnchors offers all given anchor resolutions to the sweeper. It requests
// sweeping at the minimum fee rate. This fee rate can be upped manually by the // sweeping at the minimum fee rate. This fee rate can be upped manually by the
// user via the BumpFee rpc. // user via the BumpFee rpc.
func (c *ChannelArbitrator) sweepAnchors(anchors []*lnwallet.AnchorResolution, func (c *ChannelArbitrator) sweepAnchors(anchors *lnwallet.AnchorResolutions,
heightHint uint32) error { heightHint uint32) error {
// Use the chan id as the exclusive group. This prevents any of the // Use the chan id as the exclusive group. This prevents any of the
// anchors from being batched together. // anchors from being batched together.
exclusiveGroup := c.cfg.ShortChanID.ToUint64() exclusiveGroup := c.cfg.ShortChanID.ToUint64()
for _, anchor := range anchors { // TODO: refactor this function in next commit.
for _, anchor := range []*lnwallet.AnchorResolution{
anchors.Local, anchors.Remote, anchors.RemotePending,
} {
log.Debugf("ChannelArbitrator(%v): pre-confirmation sweep of "+ log.Debugf("ChannelArbitrator(%v): pre-confirmation sweep of "+
"anchor of tx %v", c.cfg.ChanPoint, anchor.CommitAnchor) "anchor of tx %v", c.cfg.ChanPoint, anchor.CommitAnchor)

@ -2119,9 +2119,7 @@ func TestChannelArbitratorAnchors(t *testing.T) {
// Setup two pre-confirmation anchor resolutions on the mock channel. // Setup two pre-confirmation anchor resolutions on the mock channel.
chanArb.cfg.Channel.(*mockChannel).anchorResolutions = chanArb.cfg.Channel.(*mockChannel).anchorResolutions =
[]*lnwallet.AnchorResolution{ &lnwallet.AnchorResolutions{}
{}, {},
}
if err := chanArb.Start(nil); err != nil { if err := chanArb.Start(nil); err != nil {
t.Fatalf("unable to start ChannelArbitrator: %v", err) t.Fatalf("unable to start ChannelArbitrator: %v", err)
@ -2286,13 +2284,16 @@ func assertResolverReport(t *testing.T, reports chan *channeldb.ResolverReport,
} }
type mockChannel struct { type mockChannel struct {
anchorResolutions []*lnwallet.AnchorResolution anchorResolutions *lnwallet.AnchorResolutions
} }
func (m *mockChannel) NewAnchorResolutions() ([]*lnwallet.AnchorResolution, func (m *mockChannel) NewAnchorResolutions() (*lnwallet.AnchorResolutions,
error) { error) {
if m.anchorResolutions != nil {
return m.anchorResolutions, nil
}
return m.anchorResolutions, nil return &lnwallet.AnchorResolutions{}, nil
} }
func (m *mockChannel) ForceCloseChan() (*lnwallet.LocalForceCloseSummary, error) { func (m *mockChannel) ForceCloseChan() (*lnwallet.LocalForceCloseSummary, error) {

@ -6404,16 +6404,33 @@ func (lc *LightningChannel) CompleteCooperativeClose(
return closeTx, ourBalance, nil return closeTx, ourBalance, nil
} }
// NewAnchorResolutions returns the anchor resolutions for all currently valid // AnchorResolutions is a set of anchor resolutions that's being used when
// commitment transactions. Because we have no view on the mempool, we can only // sweeping anchors during local channel force close.
// blindly anchor all of these txes down. type AnchorResolutions struct {
func (lc *LightningChannel) NewAnchorResolutions() ([]*AnchorResolution, // Local is the anchor resolution for the local commitment tx.
Local *AnchorResolution
// Remote is the anchor resolution for the remote commitment tx.
Remote *AnchorResolution
// RemotePending is the anchor resolution for the remote pending
// commitment tx. The value will be non-nil iff we've created a new
// commitment tx for the remote party which they haven't ACKed yet.
RemotePending *AnchorResolution
}
// NewAnchorResolutions returns a set of anchor resolutions wrapped in the
// struct AnchorResolutions. Because we have no view on the mempool, we can
// only blindly anchor all of these txes down. Caller needs to check the
// returned values against nil to decide whether there exists an anchor
// resolution for local/remote/pending remote commitment txes.
func (lc *LightningChannel) NewAnchorResolutions() (*AnchorResolutions,
error) { error) {
lc.Lock() lc.Lock()
defer lc.Unlock() defer lc.Unlock()
var resolutions []*AnchorResolution resolutions := &AnchorResolutions{}
// Add anchor for local commitment tx, if any. // Add anchor for local commitment tx, if any.
localRes, err := NewAnchorResolution( localRes, err := NewAnchorResolution(
@ -6422,9 +6439,7 @@ func (lc *LightningChannel) NewAnchorResolutions() ([]*AnchorResolution,
if err != nil { if err != nil {
return nil, err return nil, err
} }
if localRes != nil { resolutions.Local = localRes
resolutions = append(resolutions, localRes)
}
// Add anchor for remote commitment tx, if any. // Add anchor for remote commitment tx, if any.
remoteRes, err := NewAnchorResolution( remoteRes, err := NewAnchorResolution(
@ -6433,9 +6448,7 @@ func (lc *LightningChannel) NewAnchorResolutions() ([]*AnchorResolution,
if err != nil { if err != nil {
return nil, err return nil, err
} }
if remoteRes != nil { resolutions.Remote = remoteRes
resolutions = append(resolutions, remoteRes)
}
// Add anchor for remote pending commitment tx, if any. // Add anchor for remote pending commitment tx, if any.
remotePendingCommit, err := lc.channelState.RemoteCommitChainTip() remotePendingCommit, err := lc.channelState.RemoteCommitChainTip()
@ -6451,10 +6464,7 @@ func (lc *LightningChannel) NewAnchorResolutions() ([]*AnchorResolution,
if err != nil { if err != nil {
return nil, err return nil, err
} }
resolutions.RemotePending = remotePendingRes
if remotePendingRes != nil {
resolutions = append(resolutions, remotePendingRes)
}
} }
return resolutions, nil return resolutions, nil

@ -917,14 +917,19 @@ func testForceClose(t *testing.T, testCase *forceCloseTestCase) {
} }
// Check the pre-confirmation resolutions. // Check the pre-confirmation resolutions.
resList, err := aliceChannel.NewAnchorResolutions() res, err := aliceChannel.NewAnchorResolutions()
if err != nil { if err != nil {
t.Fatalf("pre-confirmation resolution error: %v", err) t.Fatalf("pre-confirmation resolution error: %v", err)
} }
if len(resList) != 2 { // Check we have the expected anchor resolutions.
t.Fatal("expected two resolutions") require.NotNil(t, res.Local, "expected local anchor resolution")
} require.NotNil(t,
res.Remote, "expected remote anchor resolution",
)
require.Nil(t,
res.RemotePending, "expected no anchor resolution",
)
} }
// The SelfOutputSignDesc should be non-nil since the output to-self is // The SelfOutputSignDesc should be non-nil since the output to-self is