lntemp+itest: refactor testRemoteSigner

This commit is contained in:
yyforyongyu 2022-08-11 15:56:06 +08:00
parent b8566359da
commit 38eaa36d90
No known key found for this signature in database
GPG key ID: 9BCD95C4FF296868
5 changed files with 201 additions and 179 deletions

View file

@ -675,6 +675,32 @@ func (h *HarnessTest) NewNodeWithSeedEtcd(name string, etcdCfg *etcd.Config,
return h.newNodeWithSeed(name, extraArgs, req, statelessInit) return h.newNodeWithSeed(name, extraArgs, req, statelessInit)
} }
// NewNodeRemoteSigner creates a new remote signer node and asserts its
// creation.
func (h *HarnessTest) NewNodeRemoteSigner(name string, extraArgs []string,
password []byte, watchOnly *lnrpc.WatchOnly) *node.HarnessNode {
hn, err := h.manager.newNode(h.T, name, extraArgs, password, true)
require.NoErrorf(h, err, "unable to create new node for %s", name)
err = hn.StartWithNoAuth(h.runCtx)
require.NoError(h, err, "failed to start node %s", name)
// With the seed created, construct the init request to the node,
// including the newly generated seed.
initReq := &lnrpc.InitWalletRequest{
WalletPassword: password,
WatchOnly: watchOnly,
}
// Pass the init request via rpc to finish unlocking the node. This
// will also initialize the macaroon-authenticated LightningClient.
_, err = h.manager.initWalletAndNode(hn, initReq)
require.NoErrorf(h, err, "failed to init node %s", name)
return hn
}
// KillNode kills the node (but won't wait for the node process to stop). // KillNode kills the node (but won't wait for the node process to stop).
func (h *HarnessTest) KillNode(hn *node.HarnessNode) { func (h *HarnessTest) KillNode(hn *node.HarnessNode) {
require.NoErrorf(h, hn.Kill(), "%s: kill got error", hn.Name()) require.NoErrorf(h, hn.Kill(), "%s: kill got error", hn.Name())

View file

@ -164,11 +164,11 @@ func (hn *HarnessNode) String() string {
type nodeCfg struct { type nodeCfg struct {
LogFilenamePrefix string LogFilenamePrefix string
ExtraArgs []string ExtraArgs []string
HasSeed bool SkipUnlock bool
Password []byte
P2PPort int P2PPort int
RPCPort int RPCPort int
RESTPort int RESTPort int
ProfilePort int
AcceptKeySend bool AcceptKeySend bool
FeeURL string FeeURL string
} }
@ -185,6 +185,8 @@ func (hn *HarnessNode) String() string {
PubKey: hn.PubKeyStr, PubKey: hn.PubKeyStr,
State: hn.State, State: hn.State,
NodeCfg: nodeCfg{ NodeCfg: nodeCfg{
SkipUnlock: hn.Cfg.SkipUnlock,
Password: hn.Cfg.Password,
LogFilenamePrefix: hn.Cfg.LogFilenamePrefix, LogFilenamePrefix: hn.Cfg.LogFilenamePrefix,
ExtraArgs: hn.Cfg.ExtraArgs, ExtraArgs: hn.Cfg.ExtraArgs,
P2PPort: hn.Cfg.P2PPort, P2PPort: hn.Cfg.P2PPort,

View file

@ -481,4 +481,8 @@ var allTestCasesTemp = []*lntemp.TestCase{
Name: "async payments benchmark", Name: "async payments benchmark",
TestFunc: testAsyncPayments, TestFunc: testAsyncPayments,
}, },
{
Name: "remote signer",
TestFunc: testRemoteSigner,
},
} }

View file

@ -1,13 +1,17 @@
package itest package itest
import ( import (
"fmt"
"testing" "testing"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/btcutil/hdkeychain" "github.com/btcsuite/btcd/btcutil/hdkeychain"
"github.com/btcsuite/btcwallet/waddrmgr" "github.com/btcsuite/btcwallet/waddrmgr"
"github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lnrpc/walletrpc"
"github.com/lightningnetwork/lnd/lntemp"
"github.com/lightningnetwork/lnd/lntemp/node"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -50,192 +54,182 @@ var (
// testRemoteSigner tests that a watch-only wallet can use a remote signing // testRemoteSigner tests that a watch-only wallet can use a remote signing
// wallet to perform any signing or ECDH operations. // wallet to perform any signing or ECDH operations.
func testRemoteSigner(net *lntest.NetworkHarness, t *harnessTest) { func testRemoteSigner(ht *lntemp.HarnessTest) {
// ctxb := context.Background() type testCase struct {
name string
randomSeed bool
sendCoins bool
fn func(tt *lntemp.HarnessTest,
wo, carol *node.HarnessNode)
}
// subTests := []struct { subTests := []testCase{{
// name string name: "random seed",
// randomSeed bool randomSeed: true,
// sendCoins bool fn: func(tt *lntemp.HarnessTest, wo, carol *node.HarnessNode) {
// fn func(tt *harnessTest, wo, carol *lntest.HarnessNode) // Nothing more to test here.
// }{{ },
// name: "random seed", }, {
// randomSeed: true, name: "account import",
// fn: func(tt *harnessTest, wo, carol *lntest.HarnessNode) { fn: func(tt *lntemp.HarnessTest, wo, carol *node.HarnessNode) {
// // Nothing more to test here. runWalletImportAccountScenario(
// }, tt, walletrpc.AddressType_WITNESS_PUBKEY_HASH,
// }, { carol, wo,
// name: "account import", )
// fn: func(tt *harnessTest, wo, carol *lntest.HarnessNode) { },
// runWalletImportAccountScenario( }, {
// net, tt, name: "basic channel open close",
// walletrpc.AddressType_WITNESS_PUBKEY_HASH, sendCoins: true,
// carol, wo, fn: func(tt *lntemp.HarnessTest, wo, carol *node.HarnessNode) {
// ) runBasicChannelCreationAndUpdates(tt, wo, carol)
// }, },
// }, { }, {
// name: "basic channel open close", name: "async payments",
// sendCoins: true, sendCoins: true,
// fn: func(tt *harnessTest, wo, carol *lntest.HarnessNode) { fn: func(tt *lntemp.HarnessTest, wo, carol *node.HarnessNode) {
// runBasicChannelCreationAndUpdates( runAsyncPayments(tt, wo, carol)
// net, tt, wo, carol, },
// ) }, {
// }, name: "shared key",
// }, { fn: func(tt *lntemp.HarnessTest, wo, carol *node.HarnessNode) {
// name: "async payments", runDeriveSharedKey(tt, wo)
// sendCoins: true, },
// fn: func(tt *harnessTest, wo, carol *lntest.HarnessNode) { }, {
// runAsyncPayments(net, tt, wo, carol) name: "cpfp",
// }, sendCoins: true,
// }, { fn: func(tt *lntemp.HarnessTest, wo, carol *node.HarnessNode) {
// name: "shared key", runCPFP(tt, wo, carol)
// fn: func(tt *harnessTest, wo, carol *lntest.HarnessNode) { },
// runDeriveSharedKey(tt, wo) }, {
// }, name: "psbt",
// }, { randomSeed: true,
// name: "cpfp", fn: func(tt *lntemp.HarnessTest, wo, carol *node.HarnessNode) {
// sendCoins: true, runPsbtChanFunding(tt, carol, wo)
// fn: func(tt *harnessTest, wo, carol *lntest.HarnessNode) { runSignPsbtSegWitV0P2WKH(tt, wo)
// runCPFP(net, tt, wo, carol) runSignPsbtSegWitV1KeySpendBip86(tt, wo)
// }, runSignPsbtSegWitV1KeySpendRootHash(tt, wo)
// }, { runSignPsbtSegWitV1ScriptSpend(tt, wo)
// name: "psbt", },
// randomSeed: true, }, {
// fn: func(tt *harnessTest, wo, carol *lntest.HarnessNode) { name: "sign output raw",
// runPsbtChanFunding(net, tt, carol, wo) sendCoins: true,
// runSignPsbtSegWitV0P2WKH(tt, net, wo) fn: func(tt *lntemp.HarnessTest, wo, carol *node.HarnessNode) {
// runSignPsbtSegWitV1KeySpendBip86(tt, net, wo) runSignOutputRaw(tt, wo)
// runSignPsbtSegWitV1KeySpendRootHash(tt, net, wo) },
// runSignPsbtSegWitV1ScriptSpend(tt, net, wo) }, {
// }, name: "sign verify msg",
// }, { sendCoins: true,
// name: "sign output raw", fn: func(tt *lntemp.HarnessTest, wo, carol *node.HarnessNode) {
// sendCoins: true, runSignVerifyMessage(tt, wo)
// fn: func(tt *harnessTest, wo, carol *lntest.HarnessNode) { },
// runSignOutputRaw(tt, net, wo) }, {
// }, name: "taproot",
// }, { sendCoins: true,
// name: "sign verify msg", randomSeed: true,
// sendCoins: true, fn: func(tt *lntemp.HarnessTest, wo, carol *node.HarnessNode) {
// fn: func(tt *harnessTest, wo, carol *lntest.HarnessNode) { testTaprootSendCoinsKeySpendBip86(tt, wo)
// runSignVerifyMessage(tt, net, wo) testTaprootComputeInputScriptKeySpendBip86(tt, wo)
// }, testTaprootSignOutputRawScriptSpend(tt, wo)
// }, { testTaprootSignOutputRawKeySpendBip86(tt, wo)
// name: "taproot", testTaprootSignOutputRawKeySpendRootHash(tt, wo)
// sendCoins: true, testTaprootMuSig2KeySpendRootHash(tt, wo)
// randomSeed: true, testTaprootMuSig2ScriptSpend(tt, wo)
// fn: func(tt *harnessTest, wo, carol *lntest.HarnessNode) { testTaprootMuSig2KeySpendBip86(tt, wo)
// ctxt, cancel := context.WithTimeout( testTaprootMuSig2CombinedLeafKeySpend(tt, wo)
// ctxb, 3*defaultTimeout, },
// ) }}
// defer cancel()
// testTaprootSendCoinsKeySpendBip86(ctxt, tt, wo, net) prepareTest := func(st *lntemp.HarnessTest,
// testTaprootComputeInputScriptKeySpendBip86( subTest testCase) (*node.HarnessNode,
// ctxt, tt, wo, net, *node.HarnessNode, *node.HarnessNode) {
// )
// testTaprootSignOutputRawScriptSpend(ctxt, tt, wo, net)
// testTaprootSignOutputRawKeySpendBip86(ctxt, tt, wo, net)
// testTaprootSignOutputRawKeySpendRootHash(
// ctxt, tt, wo, net,
// )
// testTaprootMuSig2KeySpendRootHash(ctxt, tt, wo, net)
// testTaprootMuSig2ScriptSpend(ctxt, tt, wo, net)
// testTaprootMuSig2KeySpendBip86(ctxt, tt, wo, net)
// testTaprootMuSig2CombinedLeafKeySpend(ctxt, tt, wo, net)
// },
// }}
// for _, st := range subTests { // Signer is our signing node and has the wallet with the full
// subTest := st // master private key. We test that we can create the watch-only
// wallet from the exported accounts but also from a static key
// to make sure the derivation of the account public keys is
// correct in both cases.
password := []byte("itestpassword")
var (
signerNodePubKey = nodePubKey
watchOnlyAccounts = deriveCustomScopeAccounts(ht.T)
signer *node.HarnessNode
err error
)
if !subTest.randomSeed {
signer = st.RestoreNodeWithSeed(
"Signer", nil, password, nil, rootKey, 0, nil,
)
} else {
signer = st.NewNode("Signer", nil)
signerNodePubKey = signer.PubKeyStr
// // Signer is our signing node and has the wallet with the full rpcAccts := signer.RPC.ListAccounts(
// // master private key. We test that we can create the watch-only &walletrpc.ListAccountsRequest{},
// // wallet from the exported accounts but also from a static key )
// // to make sure the derivation of the account public keys is
// // correct in both cases.
// password := []byte("itestpassword")
// var (
// signerNodePubKey = nodePubKey
// watchOnlyAccounts = deriveCustomScopeAccounts(t.t)
// signer *lntest.HarnessNode
// err error
// )
// if !subTest.randomSeed {
// signer, err = net.RestoreNodeWithSeed(
// "Signer", nil, password, nil, rootKey, 0, nil,
// )
// require.NoError(t.t, err)
// } else {
// signer = net.NewNode(t.t, "Signer", nil)
// signerNodePubKey = signer.PubKeyStr
// rpcAccts, err := signer.WalletKitClient.ListAccounts( watchOnlyAccounts, err = walletrpc.AccountsToWatchOnly(
// ctxb, &walletrpc.ListAccountsRequest{}, rpcAccts.Accounts,
// ) )
// require.NoError(t.t, err) require.NoError(st, err)
}
// watchOnlyAccounts, err = walletrpc.AccountsToWatchOnly( // WatchOnly is the node that has a watch-only wallet and uses
// rpcAccts.Accounts, // the Signer node for any operation that requires access to
// ) // private keys.
// require.NoError(t.t, err) watchOnly := st.NewNodeRemoteSigner(
// } "WatchOnly", []string{
"--remotesigner.enable",
fmt.Sprintf(
"--remotesigner.rpchost=localhost:%d",
signer.Cfg.RPCPort,
),
fmt.Sprintf(
"--remotesigner.tlscertpath=%s",
signer.Cfg.TLSCertPath,
),
fmt.Sprintf(
"--remotesigner.macaroonpath=%s",
signer.Cfg.AdminMacPath,
),
}, password, &lnrpc.WatchOnly{
MasterKeyBirthdayTimestamp: 0,
MasterKeyFingerprint: nil,
Accounts: watchOnlyAccounts,
},
)
// // WatchOnly is the node that has a watch-only wallet and uses resp := watchOnly.RPC.GetInfo()
// // the Signer node for any operation that requires access to require.Equal(st, signerNodePubKey, resp.IdentityPubkey)
// // private keys.
// watchOnly, err := net.NewNodeRemoteSigner(
// "WatchOnly", []string{
// "--remotesigner.enable",
// fmt.Sprintf(
// "--remotesigner.rpchost=localhost:%d",
// signer.Cfg.RPCPort,
// ),
// fmt.Sprintf(
// "--remotesigner.tlscertpath=%s",
// signer.Cfg.TLSCertPath,
// ),
// fmt.Sprintf(
// "--remotesigner.macaroonpath=%s",
// signer.Cfg.AdminMacPath,
// ),
// }, password, &lnrpc.WatchOnly{
// MasterKeyBirthdayTimestamp: 0,
// MasterKeyFingerprint: nil,
// Accounts: watchOnlyAccounts,
// },
// )
// require.NoError(t.t, err)
// resp, err := watchOnly.GetInfo(ctxb, &lnrpc.GetInfoRequest{}) if subTest.sendCoins {
// require.NoError(t.t, err) st.FundCoins(btcutil.SatoshiPerBitcoin, watchOnly)
ht.AssertWalletAccountBalance(
watchOnly, "default",
btcutil.SatoshiPerBitcoin, 0,
)
}
// require.Equal(t.t, signerNodePubKey, resp.IdentityPubkey) carol := st.NewNode("carol", nil)
st.EnsureConnected(watchOnly, carol)
// if subTest.sendCoins { return signer, watchOnly, carol
// net.SendCoins(t.t, btcutil.SatoshiPerBitcoin, watchOnly) }
// assertAccountBalance(
// t.t, watchOnly, "default",
// btcutil.SatoshiPerBitcoin, 0,
// )
// }
// carol := net.NewNode(t.t, "carol", nil) for _, testCase := range subTests {
// net.EnsureConnected(t.t, watchOnly, carol) subTest := testCase
// success := t.t.Run(subTest.name, func(tt *testing.T) { success := ht.Run(subTest.name, func(tt *testing.T) {
// ht := newHarnessTest(tt, net) // Skip the cleanup here as no standby node is used.
// subTest.fn(ht, watchOnly, carol) st := ht.Subtest(tt)
// })
// shutdownAndAssert(net, t, carol) _, watchOnly, carol := prepareTest(st, subTest)
// shutdownAndAssert(net, t, watchOnly) subTest.fn(st, watchOnly, carol)
// shutdownAndAssert(net, t, signer) })
// if !success { if !success {
// return return
// } }
// } }
} }
// deriveCustomScopeAccounts derives the first 255 default accounts of the custom lnd // deriveCustomScopeAccounts derives the first 255 default accounts of the custom lnd

View file

@ -8,10 +8,6 @@ var allTestCases = []*testCase{
name: "async bidirectional payments", name: "async bidirectional payments",
test: testBidirectionalAsyncPayments, test: testBidirectionalAsyncPayments,
}, },
{
name: "remote signer",
test: testRemoteSigner,
},
{ {
name: "taproot coop close", name: "taproot coop close",
test: testTaprootCoopClose, test: testTaprootCoopClose,