|
|
|
@ -67,9 +67,8 @@ type NetworkHarness struct {
|
|
|
|
|
Alice *HarnessNode |
|
|
|
|
Bob *HarnessNode |
|
|
|
|
|
|
|
|
|
// embeddedEtcd is set to true if new nodes are to be created with an
|
|
|
|
|
// embedded etcd backend instead of just bbolt.
|
|
|
|
|
embeddedEtcd bool |
|
|
|
|
// dbBackend sets the database backend to use.
|
|
|
|
|
dbBackend DatabaseBackend |
|
|
|
|
|
|
|
|
|
// Channel for transmitting stderr output from failed lightning node
|
|
|
|
|
// to main process.
|
|
|
|
@ -84,12 +83,19 @@ type NetworkHarness struct {
|
|
|
|
|
mtx sync.Mutex |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type DatabaseBackend int |
|
|
|
|
|
|
|
|
|
const ( |
|
|
|
|
BackendBbolt DatabaseBackend = iota |
|
|
|
|
BackendEtcd |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// NewNetworkHarness creates a new network test harness.
|
|
|
|
|
// TODO(roasbeef): add option to use golang's build library to a binary of the
|
|
|
|
|
// current repo. This will save developers from having to manually `go install`
|
|
|
|
|
// within the repo each time before changes
|
|
|
|
|
func NewNetworkHarness(r *rpctest.Harness, b BackendConfig, lndBinary string, |
|
|
|
|
embeddedEtcd bool) (*NetworkHarness, error) { |
|
|
|
|
dbBackend DatabaseBackend) (*NetworkHarness, error) { |
|
|
|
|
|
|
|
|
|
feeService := startFeeService() |
|
|
|
|
|
|
|
|
@ -103,7 +109,7 @@ func NewNetworkHarness(r *rpctest.Harness, b BackendConfig, lndBinary string,
|
|
|
|
|
feeService: feeService, |
|
|
|
|
quit: make(chan struct{}), |
|
|
|
|
lndBinary: lndBinary, |
|
|
|
|
embeddedEtcd: embeddedEtcd, |
|
|
|
|
dbBackend: dbBackend, |
|
|
|
|
} |
|
|
|
|
return &n, nil |
|
|
|
|
} |
|
|
|
@ -306,11 +312,11 @@ func (n *NetworkHarness) NewNodeWithSeedEtcd(name string, etcdCfg *etcd.Config,
|
|
|
|
|
*HarnessNode, []string, []byte, error) { |
|
|
|
|
|
|
|
|
|
// We don't want to use the embedded etcd instance.
|
|
|
|
|
const embeddedEtcd = false |
|
|
|
|
const dbBackend = BackendBbolt |
|
|
|
|
|
|
|
|
|
extraArgs := extraArgsEtcd(etcdCfg, name, cluster) |
|
|
|
|
return n.newNodeWithSeed( |
|
|
|
|
name, extraArgs, password, entropy, statelessInit, embeddedEtcd, |
|
|
|
|
name, extraArgs, password, entropy, statelessInit, dbBackend, |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -323,10 +329,10 @@ func (n *NetworkHarness) NewNodeEtcd(name string, etcdCfg *etcd.Config,
|
|
|
|
|
password []byte, cluster, wait bool) (*HarnessNode, error) { |
|
|
|
|
|
|
|
|
|
// We don't want to use the embedded etcd instance.
|
|
|
|
|
const embeddedEtcd = false |
|
|
|
|
const dbBackend = BackendBbolt |
|
|
|
|
|
|
|
|
|
extraArgs := extraArgsEtcd(etcdCfg, name, cluster) |
|
|
|
|
return n.newNode(name, extraArgs, true, password, embeddedEtcd, wait) |
|
|
|
|
return n.newNode(name, extraArgs, true, password, dbBackend, wait) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// NewNode fully initializes a returns a new HarnessNode bound to the
|
|
|
|
@ -336,7 +342,7 @@ func (n *NetworkHarness) NewNode(t *testing.T,
|
|
|
|
|
name string, extraArgs []string) *HarnessNode { |
|
|
|
|
|
|
|
|
|
node, err := n.newNode( |
|
|
|
|
name, extraArgs, false, nil, n.embeddedEtcd, true, |
|
|
|
|
name, extraArgs, false, nil, n.dbBackend, true, |
|
|
|
|
) |
|
|
|
|
require.NoErrorf(t, err, "unable to create new node for %s", name) |
|
|
|
|
|
|
|
|
@ -352,16 +358,16 @@ func (n *NetworkHarness) NewNodeWithSeed(name string, extraArgs []string,
|
|
|
|
|
error) { |
|
|
|
|
|
|
|
|
|
return n.newNodeWithSeed( |
|
|
|
|
name, extraArgs, password, nil, statelessInit, n.embeddedEtcd, |
|
|
|
|
name, extraArgs, password, nil, statelessInit, n.dbBackend, |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (n *NetworkHarness) newNodeWithSeed(name string, extraArgs []string, |
|
|
|
|
password, entropy []byte, statelessInit, embeddedEtcd bool) ( |
|
|
|
|
password, entropy []byte, statelessInit bool, dbBackend DatabaseBackend) ( |
|
|
|
|
*HarnessNode, []string, []byte, error) { |
|
|
|
|
|
|
|
|
|
node, err := n.newNode( |
|
|
|
|
name, extraArgs, true, password, embeddedEtcd, true, |
|
|
|
|
name, extraArgs, true, password, dbBackend, true, |
|
|
|
|
) |
|
|
|
|
if err != nil { |
|
|
|
|
return nil, nil, nil, err |
|
|
|
@ -425,7 +431,7 @@ func (n *NetworkHarness) RestoreNodeWithSeed(name string, extraArgs []string,
|
|
|
|
|
opts ...NodeOption) (*HarnessNode, error) { |
|
|
|
|
|
|
|
|
|
node, err := n.newNode( |
|
|
|
|
name, extraArgs, true, password, n.embeddedEtcd, true, opts..., |
|
|
|
|
name, extraArgs, true, password, n.dbBackend, true, opts..., |
|
|
|
|
) |
|
|
|
|
if err != nil { |
|
|
|
|
return nil, err |
|
|
|
@ -456,7 +462,7 @@ func (n *NetworkHarness) RestoreNodeWithSeed(name string, extraArgs []string,
|
|
|
|
|
// can be used immediately. Otherwise, the node will require an additional
|
|
|
|
|
// initialization phase where the wallet is either created or restored.
|
|
|
|
|
func (n *NetworkHarness) newNode(name string, extraArgs []string, hasSeed bool, |
|
|
|
|
password []byte, embeddedEtcd, wait bool, opts ...NodeOption) ( |
|
|
|
|
password []byte, dbBackend DatabaseBackend, wait bool, opts ...NodeOption) ( |
|
|
|
|
*HarnessNode, error) { |
|
|
|
|
|
|
|
|
|
cfg := &NodeConfig{ |
|
|
|
@ -468,7 +474,7 @@ func (n *NetworkHarness) newNode(name string, extraArgs []string, hasSeed bool,
|
|
|
|
|
NetParams: n.netParams, |
|
|
|
|
ExtraArgs: extraArgs, |
|
|
|
|
FeeURL: n.feeService.url, |
|
|
|
|
Etcd: embeddedEtcd, |
|
|
|
|
DbBackend: dbBackend, |
|
|
|
|
} |
|
|
|
|
for _, opt := range opts { |
|
|
|
|
opt(cfg) |
|
|
|
@ -1548,9 +1554,9 @@ func FileExists(path string) bool {
|
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// CopyAll copies all files and directories from srcDir to dstDir recursively.
|
|
|
|
|
// copyAll copies all files and directories from srcDir to dstDir recursively.
|
|
|
|
|
// Note that this function does not support links.
|
|
|
|
|
func CopyAll(dstDir, srcDir string) error { |
|
|
|
|
func copyAll(dstDir, srcDir string) error { |
|
|
|
|
entries, err := ioutil.ReadDir(srcDir) |
|
|
|
|
if err != nil { |
|
|
|
|
return err |
|
|
|
@ -1571,7 +1577,7 @@ func CopyAll(dstDir, srcDir string) error {
|
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
err = CopyAll(dstPath, srcPath) |
|
|
|
|
err = copyAll(dstPath, srcPath) |
|
|
|
|
if err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
@ -1582,3 +1588,43 @@ func CopyAll(dstDir, srcDir string) error {
|
|
|
|
|
|
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// BackupDb creates a backup of the current database.
|
|
|
|
|
func (n *NetworkHarness) BackupDb(hn *HarnessNode) error { |
|
|
|
|
if hn.backupDbDir != "" { |
|
|
|
|
return errors.New("backup already created") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Backup files.
|
|
|
|
|
tempDir, err := ioutil.TempDir("", "past-state") |
|
|
|
|
if err != nil { |
|
|
|
|
return fmt.Errorf("unable to create temp db folder: %v", err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if err := copyAll(tempDir, hn.DBDir()); err != nil { |
|
|
|
|
return fmt.Errorf("unable to copy database files: %v", err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
hn.backupDbDir = tempDir |
|
|
|
|
|
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// RestoreDb restores a database backup.
|
|
|
|
|
func (n *NetworkHarness) RestoreDb(hn *HarnessNode) error { |
|
|
|
|
if hn.backupDbDir == "" { |
|
|
|
|
return errors.New("no database backup created") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Restore files.
|
|
|
|
|
if err := copyAll(hn.DBDir(), hn.backupDbDir); err != nil { |
|
|
|
|
return fmt.Errorf("unable to copy database files: %v", err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if err := os.RemoveAll(hn.backupDbDir); err != nil { |
|
|
|
|
return fmt.Errorf("unable to remove backup dir: %v", err) |
|
|
|
|
} |
|
|
|
|
hn.backupDbDir = "" |
|
|
|
|
|
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|