From 91538884daa7b94505c8a8721bfd82de47f6a434 Mon Sep 17 00:00:00 2001 From: Matheus Degiovani Date: Mon, 20 Apr 2020 12:09:05 -0300 Subject: [PATCH] lntest: wait for valid tls cert and macaroon files This changes the wait during node connection to check both for the existance as well as for the validity of the tls cert and macaroon files. This ensures that nodes in the process of starting up don't inadvertedly cause a connection error due to not yet having written the entire file. --- lntest/node.go | 80 +++++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 47 deletions(-) diff --git a/lntest/node.go b/lntest/node.go index d8eb08ac..83d23b4c 100644 --- a/lntest/node.go +++ b/lntest/node.go @@ -689,28 +689,26 @@ func (hn *HarnessNode) writePidFile() error { func (hn *HarnessNode) ReadMacaroon(macPath string, timeout time.Duration) ( *macaroon.Macaroon, error) { - // Wait until macaroon file is created before using it. - macTimeout := time.After(timeout) - for !fileExists(macPath) { - select { - case <-macTimeout: - return nil, fmt.Errorf("timeout waiting for macaroon "+ - "file %s to be created after %d seconds", - macPath, timeout/time.Second) - case <-time.After(100 * time.Millisecond): + // Wait until macaroon file is created and has valid content before + // using it. + var mac *macaroon.Macaroon + err := wait.NoError(func() error { + macBytes, err := ioutil.ReadFile(macPath) + if err != nil { + return fmt.Errorf("error reading macaroon file: %v", err) } - } - // Now that we know the file exists, read it and return the macaroon. - macBytes, err := ioutil.ReadFile(macPath) - if err != nil { - return nil, err - } - mac := &macaroon.Macaroon{} - if err = mac.UnmarshalBinary(macBytes); err != nil { - return nil, err - } - return mac, nil + newMac := &macaroon.Macaroon{} + if err = newMac.UnmarshalBinary(macBytes); err != nil { + return fmt.Errorf("error unmarshalling macaroon "+ + "file: %v", err) + } + mac = newMac + + return nil + }, timeout) + + return mac, err } // ConnectRPCWithMacaroon uses the TLS certificate and given macaroon to @@ -718,25 +716,24 @@ func (hn *HarnessNode) ReadMacaroon(macPath string, timeout time.Duration) ( func (hn *HarnessNode) ConnectRPCWithMacaroon(mac *macaroon.Macaroon) ( *grpc.ClientConn, error) { - // Wait until TLS certificate is created before using it, up to 30 sec. - tlsTimeout := time.After(DefaultTimeout) - for !fileExists(hn.Cfg.TLSCertPath) { - select { - case <-tlsTimeout: - return nil, fmt.Errorf("timeout waiting for TLS cert " + - "file to be created") - case <-time.After(100 * time.Millisecond): - } + // Wait until TLS certificate is created and has valid content before + // using it, up to 30 sec. + var tlsCreds credentials.TransportCredentials + err := wait.NoError(func() error { + var err error + tlsCreds, err = credentials.NewClientTLSFromFile( + hn.Cfg.TLSCertPath, "", + ) + return err + }, DefaultTimeout) + if err != nil { + return nil, fmt.Errorf("error reading TLS cert: %v", err) } - opts := []grpc.DialOption{grpc.WithBlock()} - tlsCreds, err := credentials.NewClientTLSFromFile( - hn.Cfg.TLSCertPath, "", - ) - if err != nil { - return nil, err + opts := []grpc.DialOption{ + grpc.WithBlock(), + grpc.WithTransportCredentials(tlsCreds), } - opts = append(opts, grpc.WithTransportCredentials(tlsCreds)) ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout) defer cancel() @@ -1159,14 +1156,3 @@ func (hn *HarnessNode) WaitForBalance(expectedBalance btcutil.Amount, confirmed return nil } - -// fileExists reports whether the named file or directory exists. -// This function is taken from https://github.com/btcsuite/btcd -func fileExists(name string) bool { - if _, err := os.Stat(name); err != nil { - if os.IsNotExist(err) { - return false - } - } - return true -}