lntest/itest/lnd_test: assert coop close chan status

This commit adds an itest assertion to check that a coop closed
channel's status is properly refelcted in list channels. We also fix a
race condition that prevented the rpc from being externally consistent
by marking the close sooner in the pipeline.
This commit is contained in:
Conner Fromknecht 2019-12-04 13:31:03 -08:00
parent 46990c412c
commit 0610578abb
No known key found for this signature in database
GPG Key ID: E7D737B67FA592C7
2 changed files with 43 additions and 9 deletions

@ -201,6 +201,24 @@ func (c *channelCloser) initChanShutdown() (*lnwire.Shutdown, error) {
// TODO(roasbeef): err if channel has htlc's?
// Before closing, we'll attempt to send a disable update for the
// channel. We do so before closing the channel as otherwise the current
// edge policy won't be retrievable from the graph.
if err := c.cfg.disableChannel(c.chanPoint); err != nil {
peerLog.Warnf("Unable to disable channel %v on "+
"close: %v", c.chanPoint, err)
}
// Before continuing, mark the channel as cooperatively closed with a
// nil txn. Even though we haven't negotiated the final txn, this
// guarantees that our listchannels rpc will be externally consistent,
// and reflect that the channel is being shutdown by the time the
// closing request returns.
err := c.cfg.channel.MarkCoopBroadcasted(nil)
if err != nil {
return nil, err
}
// Before returning the shutdown message, we'll unregister the channel
// to ensure that it isn't seen as usable within the system.
//
@ -428,14 +446,6 @@ func (c *channelCloser) ProcessCloseMsg(msg lnwire.Message) ([]lnwire.Message, b
}
c.closingTx = closeTx
// Before closing, we'll attempt to send a disable update for
// the channel. We do so before closing the channel as otherwise
// the current edge policy won't be retrievable from the graph.
if err := c.cfg.disableChannel(c.chanPoint); err != nil {
peerLog.Warnf("Unable to disable channel %v on "+
"close: %v", c.chanPoint, err)
}
// Before publishing the closing tx, we persist it to the
// database, such that it can be republished if something goes
// wrong.

@ -32,6 +32,7 @@ import (
"github.com/go-errors/errors"
"github.com/lightningnetwork/lnd"
"github.com/lightningnetwork/lnd/chanbackup"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
@ -332,10 +333,33 @@ func assertChannelClosed(ctx context.Context, t *harnessTest,
}
chanPointStr := fmt.Sprintf("%v:%v", txid, fundingChanPoint.OutputIndex)
// If the channel appears in list channels, ensure that its state
// contains ChanStatusCoopBroadcasted.
ctxt, _ := context.WithTimeout(ctx, defaultTimeout)
listChansRequest := &lnrpc.ListChannelsRequest{}
listChansResp, err := node.ListChannels(ctxt, listChansRequest)
if err != nil {
t.Fatalf("unable to query for list channels: %v", err)
}
for _, channel := range listChansResp.Channels {
// Skip other channels.
if channel.ChannelPoint != chanPointStr {
continue
}
// Assert that the channel is in coop broadcasted.
if !strings.Contains(channel.ChanStatusFlags,
channeldb.ChanStatusCoopBroadcasted.String()) {
t.Fatalf("channel not coop broadcasted, "+
"got: %v", channel.ChanStatusFlags)
}
}
// At this point, the channel should now be marked as being in the
// state of "waiting close".
ctxt, _ = context.WithTimeout(ctx, defaultTimeout)
pendingChansRequest := &lnrpc.PendingChannelsRequest{}
pendingChanResp, err := node.PendingChannels(ctx, pendingChansRequest)
pendingChanResp, err := node.PendingChannels(ctxt, pendingChansRequest)
if err != nil {
t.Fatalf("unable to query for pending channels: %v", err)
}