lntemp+itest: refactor testStatelessInit

This commit is contained in:
yyforyongyu 2022-08-09 15:18:39 +08:00
parent 4b469eb0c5
commit 8a4d2741a3
No known key found for this signature in database
GPG Key ID: 9BCD95C4FF296868
6 changed files with 71 additions and 60 deletions

View File

@ -502,6 +502,12 @@ func (h *HarnessTest) RestartNode(hn *node.HarnessNode) {
}
}
// RestartNodeNoUnlock restarts a given node without unlocking its wallet.
func (h *HarnessTest) RestartNodeNoUnlock(hn *node.HarnessNode) {
err := h.manager.restartNode(h.runCtx, hn, nil)
require.NoErrorf(h, err, "failed to restart node %s", hn.Name())
}
// RestartNodeWithChanBackups restarts a given node with the specified channel
// backups.
func (h *HarnessTest) RestartNodeWithChanBackups(hn *node.HarnessNode,

View File

@ -488,6 +488,19 @@ func (hn *HarnessNode) InitNode(macBytes []byte) error {
return hn.initLightningClient()
}
// InitChangePassword initializes a harness node by passing the change password
// request via RPC. After the request is submitted, this method will block until
// a macaroon-authenticated RPC connection can be established to the harness
// node. Once established, the new connection is used to initialize the
// RPC clients and subscribes the HarnessNode to topology changes.
func (hn *HarnessNode) ChangePasswordAndInit(
req *lnrpc.ChangePasswordRequest) (
*lnrpc.ChangePasswordResponse, error) {
response := hn.RPC.ChangePassword(req)
return response, hn.InitNode(response.AdminMacaroon)
}
// waitTillServerState makes a subscription to the server's state change and
// blocks until the server is in the targeted state.
func (hn *HarnessNode) waitTillServerState(

View File

@ -48,3 +48,17 @@ func (h *HarnessRPC) GenSeed(req *lnrpc.GenSeedRequest) *lnrpc.GenSeedResponse {
return resp
}
// ChangePassword makes a RPC request to WalletUnlocker and asserts there's no
// error.
func (h *HarnessRPC) ChangePassword(
req *lnrpc.ChangePasswordRequest) *lnrpc.ChangePasswordResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
resp, err := h.WalletUnlocker.ChangePassword(ctxt, req)
h.NoError(err, "ChangePassword")
return resp
}

View File

@ -357,4 +357,8 @@ var allTestCasesTemp = []*lntemp.TestCase{
Name: "delete macaroon id",
TestFunc: testDeleteMacaroonID,
},
{
Name: "stateless init",
TestFunc: testStatelessInit,
},
}

View File

@ -1,7 +1,6 @@
package itest
import (
"bytes"
"context"
"encoding/hex"
"os"
@ -14,7 +13,6 @@ import (
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lntemp"
"github.com/lightningnetwork/lnd/lntemp/node"
"github.com/lightningnetwork/lnd/lntest"
"github.com/lightningnetwork/lnd/macaroons"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -612,7 +610,7 @@ func testDeleteMacaroonID(ht *lntemp.HarnessTest) {
// does not write any macaroon files to the daemon's file system and returns
// the admin macaroon in the response. It then checks that the password
// change of the wallet can also happen stateless.
func testStatelessInit(net *lntest.NetworkHarness, t *harnessTest) {
func testStatelessInit(ht *lntemp.HarnessTest) {
var (
initPw = []byte("stateless")
newPw = []byte("stateless-new")
@ -624,85 +622,79 @@ func testStatelessInit(net *lntest.NetworkHarness, t *harnessTest) {
// First, create a new node and request it to initialize stateless.
// This should return us the binary serialized admin macaroon that we
// can then use for further calls.
carol, _, macBytes, err := net.NewNodeWithSeed(
"Carol", nil, initPw, true,
)
require.NoError(t.t, err)
if len(macBytes) == 0 {
t.Fatalf("invalid macaroon returned in stateless init")
}
carol, _, macBytes := ht.NewNodeWithSeed("Carol", nil, initPw, true)
require.NotEmpty(ht, macBytes,
"invalid macaroon returned in stateless init")
// Now make sure no macaroon files have been created by the node Carol.
_, err = os.Stat(carol.AdminMacPath())
require.Error(t.t, err)
_, err = os.Stat(carol.ReadMacPath())
require.Error(t.t, err)
_, err = os.Stat(carol.InvoiceMacPath())
require.Error(t.t, err)
_, err := os.Stat(carol.Cfg.AdminMacPath)
require.Error(ht, err)
_, err = os.Stat(carol.Cfg.ReadMacPath)
require.Error(ht, err)
_, err = os.Stat(carol.Cfg.InvoiceMacPath)
require.Error(ht, err)
// Then check that we can unmarshal the binary serialized macaroon.
adminMac := &macaroon.Macaroon{}
err = adminMac.UnmarshalBinary(macBytes)
require.NoError(t.t, err)
require.NoError(ht, err)
// Find out if we can actually use the macaroon that has been returned
// to us for a RPC call.
conn, err := carol.ConnectRPCWithMacaroon(adminMac)
require.NoError(t.t, err)
require.NoError(ht, err)
defer conn.Close()
adminMacClient := lnrpc.NewLightningClient(conn)
ctxt, _ := context.WithTimeout(context.Background(), defaultTimeout)
ctxt, cancel := context.WithTimeout(ht.Context(), defaultTimeout)
defer cancel()
res, err := adminMacClient.NewAddress(ctxt, newAddrReq)
require.NoError(t.t, err)
require.NoError(ht, err)
if !strings.HasPrefix(res.Address, harnessNetParams.Bech32HRPSegwit) {
t.Fatalf("returned address was not a regtest address")
require.Fail(ht, "returned address was not a regtest address")
}
// As a second part, shut down the node and then try to change the
// password when we start it up again.
if err := net.RestartNodeNoUnlock(carol, nil, true); err != nil {
t.Fatalf("Node restart failed: %v", err)
}
ht.RestartNodeNoUnlock(carol)
changePwReq := &lnrpc.ChangePasswordRequest{
CurrentPassword: initPw,
NewPassword: newPw,
StatelessInit: true,
}
response, err := carol.InitChangePassword(changePwReq)
require.NoError(t.t, err)
response, err := carol.ChangePasswordAndInit(changePwReq)
require.NoError(ht, err)
// Again, make sure no macaroon files have been created by the node
// Carol.
_, err = os.Stat(carol.AdminMacPath())
require.Error(t.t, err)
_, err = os.Stat(carol.ReadMacPath())
require.Error(t.t, err)
_, err = os.Stat(carol.InvoiceMacPath())
require.Error(t.t, err)
_, err = os.Stat(carol.Cfg.AdminMacPath)
require.Error(ht, err)
_, err = os.Stat(carol.Cfg.ReadMacPath)
require.Error(ht, err)
_, err = os.Stat(carol.Cfg.InvoiceMacPath)
require.Error(ht, err)
// Then check that we can unmarshal the new binary serialized macaroon
// and that it really is a new macaroon.
if err = adminMac.UnmarshalBinary(response.AdminMacaroon); err != nil {
t.Fatalf("unable to unmarshal macaroon: %v", err)
}
if bytes.Equal(response.AdminMacaroon, macBytes) {
t.Fatalf("expected new macaroon to be different")
}
err = adminMac.UnmarshalBinary(response.AdminMacaroon)
require.NoError(ht, err, "unable to unmarshal macaroon")
require.NotEqual(ht, response.AdminMacaroon, macBytes,
"expected new macaroon to be different")
// Finally, find out if we can actually use the new macaroon that has
// been returned to us for a RPC call.
conn2, err := carol.ConnectRPCWithMacaroon(adminMac)
require.NoError(t.t, err)
require.NoError(ht, err)
defer conn2.Close()
adminMacClient = lnrpc.NewLightningClient(conn2)
// Changing the password takes a while, so we use the default timeout
// of 30 seconds to wait for the connection to be ready.
ctxt, _ = context.WithTimeout(context.Background(), defaultTimeout)
ctxt, cancel = context.WithTimeout(ht.Context(), defaultTimeout)
defer cancel()
res, err = adminMacClient.NewAddress(ctxt, newAddrReq)
require.NoError(t.t, err)
require.NoError(ht, err)
if !strings.HasPrefix(res.Address, harnessNetParams.Bech32HRPSegwit) {
t.Fatalf("returned address was not a regtest address")
require.Fail(ht, "returned address was not a regtest address")
}
}
@ -720,20 +712,6 @@ func readMacaroonFromHex(macHex string) (*macaroon.Macaroon, error) {
return mac, nil
}
// TODO(yy): remove.
func macaroonClientOld(t *testing.T, testNode *lntest.HarnessNode,
mac *macaroon.Macaroon) (func(), lnrpc.LightningClient) {
conn, err := testNode.ConnectRPCWithMacaroon(mac)
require.NoError(t, err, "connect to alice")
cleanup := func() {
err := conn.Close()
require.NoError(t, err, "close")
}
return cleanup, lnrpc.NewLightningClient(conn)
}
func macaroonClient(t *testing.T, testNode *node.HarnessNode,
mac *macaroon.Macaroon) (func(), lnrpc.LightningClient) {

View File

@ -92,10 +92,6 @@ var allTestCases = []*testCase{
name: "forward interceptor dedup htlcs",
test: testForwardInterceptorDedupHtlc,
},
{
name: "stateless init",
test: testStatelessInit,
},
{
name: "wallet import account",
test: testWalletImportAccount,