itest: basic failover itest when using leader election on etcd
This commit is contained in:
7 files changed
+309
-33
No files matched your search
+89
-13
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightningnetwork/lnd"
|
||||
"github.com/lightningnetwork/lnd/channeldb/kvdb/etcd"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lntest/wait"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
@@ -61,9 +62,9 @@ type NetworkHarness struct {
|
||||
Alice *HarnessNode
|
||||
Bob *HarnessNode
|
||||
|
||||
// useEtcd is set to true if new nodes are to be created with an
|
||||
// embeddedEtcd is set to true if new nodes are to be created with an
|
||||
// embedded etcd backend instead of just bbolt.
|
||||
useEtcd bool
|
||||
embeddedEtcd bool
|
||||
|
||||
// Channel for transmitting stderr output from failed lightning node
|
||||
// to main process.
|
||||
@@ -83,7 +84,7 @@ type NetworkHarness struct {
|
||||
// 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,
|
||||
useEtcd bool) (*NetworkHarness, error) {
|
||||
embeddedEtcd bool) (*NetworkHarness, error) {
|
||||
|
||||
feeService := startFeeService()
|
||||
|
||||
@@ -97,7 +98,7 @@ func NewNetworkHarness(r *rpctest.Harness, b BackendConfig, lndBinary string,
|
||||
feeService: feeService,
|
||||
quit: make(chan struct{}),
|
||||
lndBinary: lndBinary,
|
||||
useEtcd: useEtcd,
|
||||
embeddedEtcd: embeddedEtcd,
|
||||
}
|
||||
return &n, nil
|
||||
}
|
||||
@@ -270,11 +271,70 @@ func (n *NetworkHarness) Stop() {
|
||||
n.feeService.stop()
|
||||
}
|
||||
|
||||
// extraArgsEtcd returns extra args for configuring LND to use an external etcd
|
||||
// database (for remote channel DB and wallet DB).
|
||||
func extraArgsEtcd(etcdCfg *etcd.Config, name string, cluster bool) []string {
|
||||
extraArgs := []string{
|
||||
"--db.backend=etcd",
|
||||
fmt.Sprintf("--db.etcd.host=%v", etcdCfg.Host),
|
||||
fmt.Sprintf("--db.etcd.user=%v", etcdCfg.User),
|
||||
fmt.Sprintf("--db.etcd.pass=%v", etcdCfg.Pass),
|
||||
fmt.Sprintf("--db.etcd.namespace=%v", etcdCfg.Namespace),
|
||||
}
|
||||
|
||||
if etcdCfg.InsecureSkipVerify {
|
||||
extraArgs = append(extraArgs, "--db.etcd.insecure_skip_verify")
|
||||
|
||||
}
|
||||
|
||||
if cluster {
|
||||
extraArgs = append(extraArgs, "--cluster.enable-leader-election")
|
||||
extraArgs = append(
|
||||
extraArgs, fmt.Sprintf("--cluster.id=%v", name),
|
||||
)
|
||||
}
|
||||
|
||||
return extraArgs
|
||||
}
|
||||
|
||||
// NewNodeWithSeedEtcd starts a new node with seed that'll use an external
|
||||
// etcd database as its (remote) channel and wallet DB. The passsed cluster
|
||||
// flag indicates that we'd like the node to join the cluster leader election.
|
||||
func (n *NetworkHarness) NewNodeWithSeedEtcd(name string, etcdCfg *etcd.Config,
|
||||
password []byte, entropy []byte, statelessInit, cluster bool) (
|
||||
*HarnessNode, []string, []byte, error) {
|
||||
|
||||
// We don't want to use the embedded etcd instance.
|
||||
const embeddedEtcd = false
|
||||
|
||||
extraArgs := extraArgsEtcd(etcdCfg, name, cluster)
|
||||
return n.newNodeWithSeed(
|
||||
name, extraArgs, password, entropy, statelessInit, embeddedEtcd,
|
||||
)
|
||||
}
|
||||
|
||||
// NewNodeWithSeedEtcd starts a new node with seed that'll use an external
|
||||
// etcd database as its (remote) channel and wallet DB. The passsed cluster
|
||||
// flag indicates that we'd like the node to join the cluster leader election.
|
||||
// If the wait flag is false then we won't wait until RPC is available (this is
|
||||
// useful when the node is not expected to become the leader right away).
|
||||
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
|
||||
|
||||
extraArgs := extraArgsEtcd(etcdCfg, name, cluster)
|
||||
return n.newNode(name, extraArgs, true, password, embeddedEtcd, wait)
|
||||
}
|
||||
|
||||
// NewNode fully initializes a returns a new HarnessNode bound to the
|
||||
// current instance of the network harness. The created node is running, but
|
||||
// not yet connected to other nodes within the network.
|
||||
func (n *NetworkHarness) NewNode(name string, extraArgs []string) (*HarnessNode, error) {
|
||||
return n.newNode(name, extraArgs, false, nil)
|
||||
func (n *NetworkHarness) NewNode(name string, extraArgs []string) (*HarnessNode,
|
||||
error) {
|
||||
|
||||
return n.newNode(name, extraArgs, false, nil, n.embeddedEtcd, true)
|
||||
}
|
||||
|
||||
// NewNodeWithSeed fully initializes a new HarnessNode after creating a fresh
|
||||
@@ -285,7 +345,18 @@ func (n *NetworkHarness) NewNodeWithSeed(name string, extraArgs []string,
|
||||
password []byte, statelessInit bool) (*HarnessNode, []string, []byte,
|
||||
error) {
|
||||
|
||||
node, err := n.newNode(name, extraArgs, true, password)
|
||||
return n.newNodeWithSeed(
|
||||
name, extraArgs, password, nil, statelessInit, n.embeddedEtcd,
|
||||
)
|
||||
}
|
||||
|
||||
func (n *NetworkHarness) newNodeWithSeed(name string, extraArgs []string,
|
||||
password, entropy []byte, statelessInit, embeddedEtcd bool) (
|
||||
*HarnessNode, []string, []byte, error) {
|
||||
|
||||
node, err := n.newNode(
|
||||
name, extraArgs, true, password, embeddedEtcd, true,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
@@ -296,6 +367,7 @@ func (n *NetworkHarness) NewNodeWithSeed(name string, extraArgs []string,
|
||||
// same password as the internal wallet.
|
||||
genSeedReq := &lnrpc.GenSeedRequest{
|
||||
AezeedPassphrase: password,
|
||||
SeedEntropy: entropy,
|
||||
}
|
||||
|
||||
ctxt, cancel := context.WithTimeout(ctxb, DefaultTimeout)
|
||||
@@ -345,7 +417,9 @@ func (n *NetworkHarness) RestoreNodeWithSeed(name string, extraArgs []string,
|
||||
password []byte, mnemonic []string, recoveryWindow int32,
|
||||
chanBackups *lnrpc.ChanBackupSnapshot) (*HarnessNode, error) {
|
||||
|
||||
node, err := n.newNode(name, extraArgs, true, password)
|
||||
node, err := n.newNode(
|
||||
name, extraArgs, true, password, n.embeddedEtcd, true,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -375,7 +449,8 @@ 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) (*HarnessNode, error) {
|
||||
password []byte, embeddedEtcd, wait bool) (
|
||||
*HarnessNode, error) {
|
||||
|
||||
node, err := newNode(NodeConfig{
|
||||
Name: name,
|
||||
@@ -386,7 +461,7 @@ func (n *NetworkHarness) newNode(name string, extraArgs []string, hasSeed bool,
|
||||
NetParams: n.netParams,
|
||||
ExtraArgs: extraArgs,
|
||||
FeeURL: n.feeService.url,
|
||||
Etcd: n.useEtcd,
|
||||
Etcd: embeddedEtcd,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -398,7 +473,8 @@ func (n *NetworkHarness) newNode(name string, extraArgs []string, hasSeed bool,
|
||||
n.activeNodes[node.NodeID] = node
|
||||
n.mtx.Unlock()
|
||||
|
||||
if err := node.start(n.lndBinary, n.lndErrorChan); err != nil {
|
||||
err = node.start(n.lndBinary, n.lndErrorChan, wait)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -684,7 +760,7 @@ func (n *NetworkHarness) RestartNodeNoUnlock(node *HarnessNode,
|
||||
}
|
||||
}
|
||||
|
||||
return node.start(n.lndBinary, n.lndErrorChan)
|
||||
return node.start(n.lndBinary, n.lndErrorChan, true)
|
||||
}
|
||||
|
||||
// SuspendNode stops the given node and returns a callback that can be used to
|
||||
@@ -695,7 +771,7 @@ func (n *NetworkHarness) SuspendNode(node *HarnessNode) (func() error, error) {
|
||||
}
|
||||
|
||||
restart := func() error {
|
||||
return node.start(n.lndBinary, n.lndErrorChan)
|
||||
return node.start(n.lndBinary, n.lndErrorChan, true)
|
||||
}
|
||||
|
||||
return restart, nil
|
||||
|
||||
Reference in new issue
Block a user