lntest: standby test nodes in remote signing configuration

Add the ability to create a test harness with nodes in a
remote signing configuration.
This commit is contained in:
Calvin Zachman 2024-01-08 16:13:38 -06:00
parent 9afe1b72dc
commit 2209badfe8
No known key found for this signature in database
GPG Key ID: 52AAA845E345D42E

View File

@ -171,48 +171,87 @@ func (h *HarnessTest) Context() context.Context {
return h.runCtx return h.runCtx
} }
// SetUp starts the initial seeder nodes within the test harness. The initial // setupWatchOnlyNode initializes a node with the watch-only accounts of an
// node's wallets will be funded wallets with 10x10 BTC outputs each. // associated remote signing instance.
func (h *HarnessTest) SetupStandbyNodes() { func (h *HarnessTest) setupWatchOnlyNode(name string,
h.Log("Setting up standby nodes Alice and Bob...") signerNode *node.HarnessNode, password []byte) *node.HarnessNode {
defer h.Log("Finished the setup, now running tests...")
lndArgs := []string{ // Prepare arguments for watch-only node connected to the remote signer.
"--default-remote-max-htlcs=483", remoteSignerArgs := []string{
"--dust-threshold=5000000", "--remotesigner.enable",
} fmt.Sprintf("--remotesigner.rpchost=localhost:%d",
// Start the initial seeder nodes within the test network, then connect signerNode.Cfg.RPCPort),
// their respective RPC clients. fmt.Sprintf("--remotesigner.tlscertpath=%s",
h.Alice = h.NewNode("Alice", lndArgs) signerNode.Cfg.TLSCertPath),
h.Bob = h.NewNode("Bob", lndArgs) fmt.Sprintf("--remotesigner.macaroonpath=%s",
signerNode.Cfg.AdminMacPath),
addrReq := &lnrpc.NewAddressRequest{
Type: lnrpc.AddressType_WITNESS_PUBKEY_HASH,
} }
const initialFund = 1 * btcutil.SatoshiPerBitcoin // Fetch watch-only accounts from the signer node.
resp := signerNode.RPC.ListAccounts(&walletrpc.ListAccountsRequest{})
watchOnlyAccounts, err := walletrpc.AccountsToWatchOnly(resp.Accounts)
require.NoErrorf(h, err, "unable to find watch only accounts for %s",
name)
// Load up the wallets of the seeder nodes with 100 outputs of 1 BTC // Create a new watch-only node with remote signer configuration.
// each. return h.NewNodeRemoteSigner(
nodes := []*node.HarnessNode{h.Alice, h.Bob} name, remoteSignerArgs, password,
for _, hn := range nodes { &lnrpc.WatchOnly{
h.manager.standbyNodes[hn.Cfg.NodeID] = hn MasterKeyBirthdayTimestamp: 0,
for i := 0; i < 100; i++ { MasterKeyFingerprint: nil,
resp := hn.RPC.NewAddress(addrReq) Accounts: watchOnlyAccounts,
},
addr, err := btcutil.DecodeAddress(
resp.Address, h.Miner.ActiveNet,
) )
require.NoError(h, err) }
addrScript, err := txscript.PayToAddrScript(addr) // createAndSendOutput send amt satoshis from the internal mining node to the
require.NoError(h, err) // targeted lightning node using a P2WKH address. No blocks are mined so
// transactions will sit unconfirmed in mempool.
func (h *HarnessTest) createAndSendOutput(target *node.HarnessNode,
amt btcutil.Amount, addrType lnrpc.AddressType) {
req := &lnrpc.NewAddressRequest{Type: addrType}
resp := target.RPC.NewAddress(req)
addr := h.DecodeAddress(resp.Address)
addrScript := h.PayToAddrScript(addr)
output := &wire.TxOut{ output := &wire.TxOut{
PkScript: addrScript, PkScript: addrScript,
Value: initialFund, Value: int64(amt),
} }
h.Miner.SendOutput(output, defaultMinerFeeRate) h.Miner.SendOutput(output, defaultMinerFeeRate)
}
// SetupRemoteSigningStandbyNodes starts the initial seeder nodes within the
// test harness in a remote signing configuration. The initial node's wallets
// will be funded wallets with 100x1 BTC outputs each.
func (h *HarnessTest) SetupRemoteSigningStandbyNodes() {
h.Log("Setting up standby nodes Alice and Bob with remote " +
"signing configurations...")
defer h.Log("Finished the setup, now running tests...")
password := []byte("itestpassword")
// Setup remote signing nodes for Alice and Bob.
signerAlice := h.NewNode("SignerAlice", nil)
signerBob := h.NewNode("SignerBob", nil)
// Setup watch-only nodes for Alice and Bob, each configured with their
// own remote signing instance.
h.Alice = h.setupWatchOnlyNode("Alice", signerAlice, password)
h.Bob = h.setupWatchOnlyNode("Bob", signerBob, password)
// Fund each node with 100 BTC (using 100 separate transactions).
const fundAmount = 1 * btcutil.SatoshiPerBitcoin
const numOutputs = 100
const totalAmount = fundAmount * numOutputs
for _, node := range []*node.HarnessNode{h.Alice, h.Bob} {
h.manager.standbyNodes[node.Cfg.NodeID] = node
for i := 0; i < numOutputs; i++ {
h.createAndSendOutput(
node, fundAmount,
lnrpc.AddressType_WITNESS_PUBKEY_HASH,
)
} }
} }
@ -226,24 +265,52 @@ func (h *HarnessTest) SetupStandbyNodes() {
h.WaitForBlockchainSync(h.Bob) h.WaitForBlockchainSync(h.Bob)
// Now block until both wallets have fully synced up. // Now block until both wallets have fully synced up.
const expectedBalance = 100 * initialFund h.WaitForBalanceConfirmed(h.Alice, totalAmount)
err := wait.NoError(func() error { h.WaitForBalanceConfirmed(h.Bob, totalAmount)
aliceResp := h.Alice.RPC.WalletBalance() }
bobResp := h.Bob.RPC.WalletBalance()
if aliceResp.ConfirmedBalance != expectedBalance { // SetUp starts the initial seeder nodes within the test harness. The initial
return fmt.Errorf("expected 10 BTC, instead "+ // node's wallets will be funded wallets with 10x10 BTC outputs each.
"alice has %d", aliceResp.ConfirmedBalance) func (h *HarnessTest) SetupStandbyNodes() {
h.Log("Setting up standby nodes Alice and Bob...")
defer h.Log("Finished the setup, now running tests...")
lndArgs := []string{
"--default-remote-max-htlcs=483",
"--dust-threshold=5000000",
} }
if bobResp.ConfirmedBalance != expectedBalance { // Start the initial seeder nodes within the test network.
return fmt.Errorf("expected 10 BTC, instead "+ h.Alice = h.NewNode("Alice", lndArgs)
"bob has %d", bobResp.ConfirmedBalance) h.Bob = h.NewNode("Bob", lndArgs)
// Load up the wallets of the seeder nodes with 100 outputs of 1 BTC
// each.
const fundAmount = 1 * btcutil.SatoshiPerBitcoin
const numOutputs = 100
const totalAmount = fundAmount * numOutputs
for _, node := range []*node.HarnessNode{h.Alice, h.Bob} {
h.manager.standbyNodes[node.Cfg.NodeID] = node
for i := 0; i < numOutputs; i++ {
h.createAndSendOutput(
node, fundAmount,
lnrpc.AddressType_WITNESS_PUBKEY_HASH,
)
}
} }
return nil // We generate several blocks in order to give the outputs created
}, DefaultTimeout) // above a good number of confirmations.
require.NoError(h, err, "timeout checking balance for node") const totalTxes = 200
h.MineBlocksAndAssertNumTxes(numBlocksSendOutput, totalTxes)
// Now we want to wait for the nodes to catch up.
h.WaitForBlockchainSync(h.Alice)
h.WaitForBlockchainSync(h.Bob)
// Now block until both wallets have fully synced up.
h.WaitForBalanceConfirmed(h.Alice, totalAmount)
h.WaitForBalanceConfirmed(h.Bob, totalAmount)
} }
// Stop stops the test harness. // Stop stops the test harness.