lnd_test: test disable is sent during close

This commit is contained in:
Conner Fromknecht 2019-03-12 17:34:42 -07:00
parent 325d77c431
commit 8baa6d6601
No known key found for this signature in database
GPG Key ID: E7D737B67FA592C7

@ -223,16 +223,80 @@ func openChannelAndAssert(ctx context.Context, t *harnessTest,
// closure is attempted, therefore the passed context should be a child derived // closure is attempted, therefore the passed context should be a child derived
// via timeout from a base parent. Additionally, once the channel has been // via timeout from a base parent. Additionally, once the channel has been
// detected as closed, an assertion checks that the transaction is found within // detected as closed, an assertion checks that the transaction is found within
// a block. // a block. Finally, this assertion verifies that the node always sends out a
// disable update when closing the channel if the channel was previously enabled.
//
// NOTE: This method assumes that the provided funding point is confirmed
// on-chain AND that the edge exists in the node's channel graph. If the funding
// transactions was reorged out at some point, use closeReorgedChannelAndAssert.
func closeChannelAndAssert(ctx context.Context, t *harnessTest, func closeChannelAndAssert(ctx context.Context, t *harnessTest,
net *lntest.NetworkHarness, node *lntest.HarnessNode, net *lntest.NetworkHarness, node *lntest.HarnessNode,
fundingChanPoint *lnrpc.ChannelPoint, force bool) *chainhash.Hash { fundingChanPoint *lnrpc.ChannelPoint, force bool) *chainhash.Hash {
// Fetch the current channel policy. If the channel is currently
// enabled, we will register for graph notifications before closing to
// assert that the node sends out a disabling update as a result of the
// channel being closed.
curPolicy := getChannelPolicies(t, node, node.PubKeyStr, fundingChanPoint)[0]
expectDisable := !curPolicy.Disabled
// If the current channel policy is enabled, begin subscribing the graph
// updates before initiating the channel closure.
var graphSub *graphSubscription
if expectDisable {
sub := subscribeGraphNotifications(t, ctx, node)
graphSub = &sub
defer close(graphSub.quit)
}
closeUpdates, _, err := net.CloseChannel(ctx, node, fundingChanPoint, force)
if err != nil {
t.Fatalf("unable to close channel: %v", err)
}
// If the channel policy was enabled prior to the closure, wait until we
// received the disabled update.
if expectDisable {
curPolicy.Disabled = true
waitForChannelUpdate(
t, *graphSub,
[]expectedChanUpdate{
{node.PubKeyStr, curPolicy, fundingChanPoint},
},
)
}
return assertChannelClosed(ctx, t, net, node, fundingChanPoint, closeUpdates)
}
// closeReorgedChannelAndAssert attempts to close a channel identified by the
// passed channel point owned by the passed Lightning node. A fully blocking
// channel closure is attempted, therefore the passed context should be a child
// derived via timeout from a base parent. Additionally, once the channel has
// been detected as closed, an assertion checks that the transaction is found
// within a block.
//
// NOTE: This method does not verify that the node sends a disable update for
// the closed channel.
func closeReorgedChannelAndAssert(ctx context.Context, t *harnessTest,
net *lntest.NetworkHarness, node *lntest.HarnessNode,
fundingChanPoint *lnrpc.ChannelPoint, force bool) *chainhash.Hash {
closeUpdates, _, err := net.CloseChannel(ctx, node, fundingChanPoint, force) closeUpdates, _, err := net.CloseChannel(ctx, node, fundingChanPoint, force)
if err != nil { if err != nil {
t.Fatalf("unable to close channel: %v", err) t.Fatalf("unable to close channel: %v", err)
} }
return assertChannelClosed(ctx, t, net, node, fundingChanPoint, closeUpdates)
}
// assertChannelClosed asserts that the channel is properly cleaned up after
// initiating a cooperative or local close.
func assertChannelClosed(ctx context.Context, t *harnessTest,
net *lntest.NetworkHarness, node *lntest.HarnessNode,
fundingChanPoint *lnrpc.ChannelPoint,
closeUpdates lnrpc.Lightning_CloseChannelClient) *chainhash.Hash {
txidHash, err := getChanPointFundingTxid(fundingChanPoint) txidHash, err := getChanPointFundingTxid(fundingChanPoint)
if err != nil { if err != nil {
t.Fatalf("unable to get txid: %v", err) t.Fatalf("unable to get txid: %v", err)
@ -989,7 +1053,6 @@ out:
select { select {
case graphUpdate := <-subscription.updateChan: case graphUpdate := <-subscription.updateChan:
for _, update := range graphUpdate.ChannelUpdates { for _, update := range graphUpdate.ChannelUpdates {
// For each expected update, check if it matches // For each expected update, check if it matches
// the update we just received. // the update we just received.
for i, exp := range expUpdates { for i, exp := range expUpdates {
@ -1070,11 +1133,12 @@ func assertNoChannelUpdates(t *harnessTest, subscription graphSubscription,
} }
} }
// assertChannelPolicy asserts that the passed node's known channel policy for // getChannelPolicies queries the channel graph and retrieves the current edge
// the passed chanPoint is consistent with the expected policy values. // policies for the provided channel points.
func assertChannelPolicy(t *harnessTest, node *lntest.HarnessNode, func getChannelPolicies(t *harnessTest, node *lntest.HarnessNode,
advertisingNode string, expectedPolicy *lnrpc.RoutingPolicy, advertisingNode string,
chanPoints ...*lnrpc.ChannelPoint) { chanPoints ...*lnrpc.ChannelPoint) []*lnrpc.RoutingPolicy {
ctxb := context.Background() ctxb := context.Background()
descReq := &lnrpc.ChannelGraphRequest{ descReq := &lnrpc.ChannelGraphRequest{
@ -1086,6 +1150,7 @@ func assertChannelPolicy(t *harnessTest, node *lntest.HarnessNode,
t.Fatalf("unable to query for alice's graph: %v", err) t.Fatalf("unable to query for alice's graph: %v", err)
} }
var policies []*lnrpc.RoutingPolicy
out: out:
for _, chanPoint := range chanPoints { for _, chanPoint := range chanPoints {
for _, e := range chanGraph.Edges { for _, e := range chanGraph.Edges {
@ -1093,18 +1158,10 @@ out:
continue continue
} }
var err error
if e.Node1Pub == advertisingNode { if e.Node1Pub == advertisingNode {
err = checkChannelPolicy( policies = append(policies, e.Node1Policy)
e.Node1Policy, expectedPolicy,
)
} else { } else {
err = checkChannelPolicy( policies = append(policies, e.Node2Policy)
e.Node2Policy, expectedPolicy,
)
}
if err != nil {
t.Fatalf(err.Error())
} }
continue out continue out
@ -1114,6 +1171,23 @@ out:
// able to find this specific one, then we'll fail. // able to find this specific one, then we'll fail.
t.Fatalf("did not find edge %v", txStr(chanPoint)) t.Fatalf("did not find edge %v", txStr(chanPoint))
} }
return policies
}
// assertChannelPolicy asserts that the passed node's known channel policy for
// the passed chanPoint is consistent with the expected policy values.
func assertChannelPolicy(t *harnessTest, node *lntest.HarnessNode,
advertisingNode string, expectedPolicy *lnrpc.RoutingPolicy,
chanPoints ...*lnrpc.ChannelPoint) {
policies := getChannelPolicies(t, node, advertisingNode, chanPoints...)
for _, policy := range policies {
err := checkChannelPolicy(policy, expectedPolicy)
if err != nil {
t.Fatalf(err.Error())
}
}
} }
// checkChannelPolicy checks that the policy matches the expected one. // checkChannelPolicy checks that the policy matches the expected one.
@ -1872,7 +1946,7 @@ func testOpenChannelAfterReorg(net *lntest.NetworkHarness, t *harnessTest) {
assertTxInBlock(t, block, fundingTxID) assertTxInBlock(t, block, fundingTxID)
ctxt, _ = context.WithTimeout(ctxb, channelCloseTimeout) ctxt, _ = context.WithTimeout(ctxb, channelCloseTimeout)
closeChannelAndAssert(ctxt, t, net, net.Alice, chanPoint, false) closeReorgedChannelAndAssert(ctxt, t, net, net.Alice, chanPoint, false)
} }
// testDisconnectingTargetPeer performs a test which // testDisconnectingTargetPeer performs a test which