config: add automatic btcd RPC configuration for testnet
A common pitfall with new users setting up lnd on test net has been observed to be the initial RPC credential set up between btcd and lnd. As of a recent version of btcd now performs automatic RPC credential set up by generating a random rpcuser and rpcpass on start up. We now take advantage of this by reading the RPC credentials (if possible and running in simmer mode). As a result, it is now possible to simply run: `lnd—testnet` assuming a fresh installation of bcd (with a set btcd.conf). Fixes #68.
This commit is contained in:
parent
a668aab478
commit
58690d96f2
87
config.go
87
config.go
@ -2,9 +2,11 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -26,9 +28,8 @@ const (
|
||||
defaultSPVMode = false
|
||||
defaultPeerPort = 5656
|
||||
defaultRPCHost = "localhost"
|
||||
defaultRPCUser = "user"
|
||||
defaultRPCPass = "passwd"
|
||||
defaultSPVHostAdr = "localhost:18333"
|
||||
defaultRPCUser = ""
|
||||
defaultRPCPass = ""
|
||||
defaultMaxPendingChannels = 1
|
||||
)
|
||||
|
||||
@ -143,9 +144,9 @@ func loadConfig() (*config, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Multiple networks can't be selected simultaneously.
|
||||
// Count number of network flags passed; assign active network params
|
||||
// while we're at it.
|
||||
// Multiple networks can't be selected simultaneously. Count number of
|
||||
// network flags passed; assign active network params while we're at
|
||||
// it.
|
||||
numNets := 0
|
||||
if cfg.TestNet3 {
|
||||
numNets++
|
||||
@ -174,6 +175,34 @@ func loadConfig() (*config, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// If the rpcuser and rpcpass paramters aren't set, then we'll attempt
|
||||
// to automatically obtain the properm mcredentials for btcd and set
|
||||
// them within the configuration.
|
||||
if cfg.RPCUser == "" || cfg.RPCPass == "" {
|
||||
// If we're in simnet mode, then the running btcd instance
|
||||
// won't read the RPC credentials from the configuration. So if
|
||||
// lnd wasn't specified the paramters, then we won't be able to
|
||||
// start.
|
||||
if cfg.SimNet {
|
||||
str := "%v: rpcuser and rpcpass must be set to your btcd " +
|
||||
"node's RPC paramters"
|
||||
return nil, fmt.Errorf(str, funcName)
|
||||
}
|
||||
|
||||
fmt.Println("Attempting automatic RPC configuration to btcd")
|
||||
|
||||
confFile := filepath.Join(btcdHomeDir, "btcd.conf")
|
||||
rpcUser, rpcPass, err := extractRPCParams(confFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to extract RPC "+
|
||||
"credentials: %v, cannot start w/o RPC connection",
|
||||
err)
|
||||
}
|
||||
|
||||
fmt.Println("Automatically obtained btcd's RPC credentials")
|
||||
cfg.RPCUser, cfg.RPCPass = rpcUser, rpcPass
|
||||
}
|
||||
|
||||
// Append the network type to the data directory so it is "namespaced"
|
||||
// per network. In addition to the block database, there are other
|
||||
// pieces of data that are saved to disk such as address manager state.
|
||||
@ -309,3 +338,49 @@ func noiseDial(idPriv *btcec.PrivateKey) func(net.Addr) (net.Conn, error) {
|
||||
return brontide.Dial(idPriv, lnAddr)
|
||||
}
|
||||
}
|
||||
|
||||
// extractRPCParams attempts to extract the RPC credentials for an existing
|
||||
// btcd instance. The passed path is expected to be the location of btcd's
|
||||
// application data directory on the target system.
|
||||
func extractRPCParams(btcdConfigPath string) (string, string, error) {
|
||||
// First, we'll open up the btcd configuration file found at the target
|
||||
// destination.
|
||||
btcdConfigFile, err := os.Open(btcdConfigPath)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
defer btcdConfigFile.Close()
|
||||
|
||||
// With the file open extract the contents of the configuration file so
|
||||
// we can attempt o locate the RPC credentials.
|
||||
configContents, err := ioutil.ReadAll(btcdConfigFile)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
// Attempt to locate the RPC user using a regular expression. If we
|
||||
// don't have a match for our regular expression then we'll exit with
|
||||
// an error.
|
||||
rpcUserRegexp, err := regexp.Compile(`(?m)^\s*rpcuser=([^\s]+)`)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
userSubmatches := rpcUserRegexp.FindSubmatch(configContents)
|
||||
if userSubmatches == nil {
|
||||
return "", "", fmt.Errorf("unable to find rpcuser in config")
|
||||
}
|
||||
|
||||
// Similarly, we'll use another regular expression to find the set
|
||||
// rpcpass (if any). If we can't find the pass, then we'll exit with an
|
||||
// error.
|
||||
rpcPassRegexp, err := regexp.Compile(`(?m)^\s*rpcpass=([^\s]+)`)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
passSubmatches := rpcPassRegexp.FindSubmatch(configContents)
|
||||
if passSubmatches == nil {
|
||||
return "", "", fmt.Errorf("unable to find rpcuser in config")
|
||||
}
|
||||
|
||||
return string(userSubmatches[1]), string(passSubmatches[1]), nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user