From 9f036b431097cabe39184ad09e19d99234d2eb98 Mon Sep 17 00:00:00 2001 From: Matheus Degiovani Date: Mon, 13 Apr 2020 13:33:48 -0300 Subject: [PATCH] lntest: wait for graph subscription on node init During the channel_backup_restore/restore_during_unlock itest, the node is restored from seed and immediately restarted. Depending on specific timing of the machine, the test harness might not have had the graph subscription processed before the node shuts down, causing the harness to trigger a panic. Reducing this to a synchronous subscription attempt means node initialization necessarily waits until the subscription is done before attempting to restart, reducing flakiness and ensuring correct behavior. --- lntest/node.go | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/lntest/node.go b/lntest/node.go index 00ac34a6..d8eb08ac 100644 --- a/lntest/node.go +++ b/lntest/node.go @@ -625,9 +625,10 @@ func (hn *HarnessNode) initLightningClient(conn *grpc.ClientConn) error { // Launch the watcher that will hook into graph related topology change // from the PoV of this node. hn.wg.Add(1) - go hn.lightningNetworkWatcher() + subscribed := make(chan error) + go hn.lightningNetworkWatcher(subscribed) - return nil + return <-subscribed } // FetchNodeInfo queries an unlocked node to retrieve its public key. @@ -874,7 +875,7 @@ func getChanPointFundingTxid(chanPoint *lnrpc.ChannelPoint) ([]byte, error) { // closed or opened within the network. In order to dispatch these // notifications, the GraphTopologySubscription client exposed as part of the // gRPC interface is used. -func (hn *HarnessNode) lightningNetworkWatcher() { +func (hn *HarnessNode) lightningNetworkWatcher(subscribed chan error) { defer hn.wg.Done() graphUpdates := make(chan *lnrpc.GraphTopologyUpdate) @@ -884,16 +885,16 @@ func (hn *HarnessNode) lightningNetworkWatcher() { req := &lnrpc.GraphTopologySubscription{} ctx, cancelFunc := context.WithCancel(context.Background()) + defer cancelFunc() topologyClient, err := hn.SubscribeChannelGraph(ctx, req) if err != nil { - // We panic here in case of an error as failure to - // create the topology client will cause all subsequent - // tests to fail. - panic(fmt.Errorf("unable to create topology "+ - "client: %v", err)) + msg := fmt.Sprintf("%s(%d): unable to create topology "+ + "client: %v (%s)", hn.Name(), hn.NodeID, err, + time.Now().String()) + subscribed <- fmt.Errorf(msg) + return } - - defer cancelFunc() + close(subscribed) for { update, err := topologyClient.Recv()