func newNode(config *nodeConfig, dataDir string) (*node, error) {
	return &node{
		config:  config,
		dataDir: dataDir,
		cmd:     config.command(),
	}, nil
}
newNode creates a new node instance according to the passed config. dataDir
will be used to hold a file recording the pid of the launched process, and
as the base for the log and data directories for soterd.
package rpctest
import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"time"
	rpc "github.com/soteria-dag/soterd/rpcclient"
	"github.com/soteria-dag/soterd/soterutil"
)
type nodeConfig struct {
	netCfgFile string
	rpcUser    string
	rpcPass    string
	listen     string
	rpcListen  string
	rpcConnect string
	dataDir    string
	logDir     string
	profile    string
	debugLevel string
	extra      []string
	prefix     string
	keepLogs   bool
	exe          string
	endpoint     string
	certFile     string
	keyFile      string
	certificates []byte
}
func newConfig(prefix, certFile, keyFile string, extra []string, keepLogs bool) (*nodeConfig, error) {
	soterdPath, err := soterdExecutablePath()
	if err != nil {
		soterdPath = "soterd"
	}
	a := &nodeConfig{
		listen:    "127.0.0.1:18555",
		rpcListen: "127.0.0.1:18556",
		rpcUser:   "user",
		rpcPass:   "pass",
		extra:     extra,
		prefix:    prefix,
		keepLogs:  keepLogs,
		exe:       soterdPath,
		endpoint:  "ws",
		certFile:  certFile,
		keyFile:   keyFile,
	}
	if err := a.setDefaults(); err != nil {
		return nil, err
	}
	return a, nil
}
func (n *nodeConfig) setDefaults() error {
	datadir, err := ioutil.TempDir("", n.prefix+"-data")
	if err != nil {
		return err
	}
	n.dataDir = datadir
	logdir, err := ioutil.TempDir("", n.prefix+"-logs")
	if err != nil {
		return err
	}
	n.logDir = logdir
	cert, err := ioutil.ReadFile(n.certFile)
	if err != nil {
		return err
	}
	n.certificates = cert
	return nil
}
func (n *nodeConfig) arguments() []string {
	args := []string{}
	if n.rpcUser != "" {
		args = append(args, fmt.Sprintf("--rpcuser=%s", n.rpcUser))
	}
	if n.rpcPass != "" {
		args = append(args, fmt.Sprintf("--rpcpass=%s", n.rpcPass))
	}
	if n.listen != "" {
		args = append(args, fmt.Sprintf("--listen=%s", n.listen))
	}
	if n.rpcListen != "" {
		args = append(args, fmt.Sprintf("--rpclisten=%s", n.rpcListen))
	}
	if n.rpcConnect != "" {
		args = append(args, fmt.Sprintf("--rpcconnect=%s", n.rpcConnect))
	}
	args = append(args, fmt.Sprintf("--rpccert=%s", n.certFile))
	args = append(args, fmt.Sprintf("--rpckey=%s", n.keyFile))
	if n.dataDir != "" {
		args = append(args, fmt.Sprintf("--datadir=%s", n.dataDir))
	}
	if n.logDir != "" {
		args = append(args, fmt.Sprintf("--logdir=%s", n.logDir))
	}
	if n.profile != "" {
		args = append(args, fmt.Sprintf("--profile=%s", n.profile))
	}
	if n.debugLevel != "" {
		args = append(args, fmt.Sprintf("--debuglevel=%s", n.debugLevel))
	}
	args = append(args, n.extra...)
	return args
}
func (n *nodeConfig) command() *exec.Cmd {
	return exec.Command(n.exe, n.arguments()...)
}
func (n *nodeConfig) rpcConnConfig() rpc.ConnConfig {
	return rpc.ConnConfig{
		Host:                 n.rpcListen,
		Endpoint:             n.endpoint,
		User:                 n.rpcUser,
		Pass:                 n.rpcPass,
		Certificates:         n.certificates,
		DisableAutoReconnect: true,
	}
}
func (n *nodeConfig) String() string {
	return n.prefix
}
func (n *nodeConfig) cleanup() error {
	dirs := []string{
		n.dataDir,
		n.netCfgFile,
	}
	if !n.keepLogs {
		dirs = append(dirs, n.logDir)
	}
	var err error
	for _, dir := range dirs {
		if err = os.RemoveAll(dir); err != nil {
			log.Printf("Cannot remove dir %s: %v", dir, err)
		}
	}
	return err
}
type node struct {
	config *nodeConfig
	cmd     *exec.Cmd
	pidFile string
	dataDir string
}