From f9f9d68543a5a264b25c98d8cfa25dcc59efb708 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Tue, 11 Jul 2017 16:27:11 -0700 Subject: [PATCH] test: ensure the WaitForBlockchainSync grouting always exits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit fixes a minor bug in the goroutine that’s launched to check the sync status of a particular node. Previously, the goroutine could end up infinitely stuck on a send as once the chain has been detected as synced, it didn't exit. We fix this now by ensure that the goroutine always terminates after the initial notification to the caller. Additionally, we not ensure that both the internal and exterior goroutine are both reading off of the peer’s quit channel. --- lnd_test.go | 2 +- networktest.go | 25 ++++++++++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/lnd_test.go b/lnd_test.go index 1e55e947..0e678c83 100644 --- a/lnd_test.go +++ b/lnd_test.go @@ -416,7 +416,7 @@ func testDisconnectingTargetPeer(net *networkHarness, t *harnessTest) { // At this point, the channel should be fully opened and there should // be no pending channels remaining for either node. - time.Sleep(time.Millisecond * 3000) + time.Sleep(time.Millisecond * 300) ctxt, _ = context.WithTimeout(ctxb, timeout) assertNumOpenChannelsPending(ctxt, t, net.Alice, net.Bob, 0) diff --git a/networktest.go b/networktest.go index 38377247..9a66fd8a 100644 --- a/networktest.go +++ b/networktest.go @@ -600,34 +600,46 @@ func (l *lightningNode) WaitForNetworkChannelClose(ctx context.Context, } } -// WaitForBlockchainSync will block until node synchronizes its blockchain +// WaitForBlockchainSync will block until the target nodes has fully +// synchronized with the blockchain. If the passed context object has a set +// timeout, then the goroutine will continually poll until the timeout has +// elapsed. In the case that the chain isn't synced before the timeout is up, +// then this function will return an error. func (l *lightningNode) WaitForBlockchainSync(ctx context.Context) error { errChan := make(chan error, 1) retryDelay := time.Millisecond * 100 + go func() { for { select { case <-ctx.Done(): - break + case <-l.quit: + return default: } + getInfoReq := &lnrpc.GetInfoRequest{} getInfoResp, err := l.GetInfo(ctx, getInfoReq) if err != nil { errChan <- err - break + return } if getInfoResp.SyncedToChain { errChan <- nil + return } + select { case <-ctx.Done(): - break + return case <-time.After(retryDelay): } } }() + select { + case <-l.quit: + return nil case err := <-errChan: return err case <-ctx.Done(): @@ -1033,7 +1045,10 @@ func (n *networkHarness) OpenChannel(ctx context.Context, srcNode, destNode *lightningNode, amt btcutil.Amount, pushAmt btcutil.Amount, numConfs uint32) (lnrpc.Lightning_OpenChannelClient, error) { - // Wait until srcNode and destNode have blockchain synced + // Wait until srcNode and destNode have the latest chain synced. + // Otherwise, we may run into a check within the funding manager that + // prevents any funding workflows from being kicked off if the chain + // isn't yet synced. if err := srcNode.WaitForBlockchainSync(ctx); err != nil { return nil, fmt.Errorf("Unable to sync srcNode chain: %v", err) }