lnd/lntemp/rpc/lnd.go
2022-11-17 21:06:12 +08:00

570 lines
16 KiB
Go

package rpc
import (
"context"
"strings"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/stretchr/testify/require"
)
// =====================
// LightningClient related RPCs.
// =====================
// NewAddress makes a RPC call to NewAddress and asserts.
func (h *HarnessRPC) NewAddress(
req *lnrpc.NewAddressRequest) *lnrpc.NewAddressResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
resp, err := h.LN.NewAddress(ctxt, req)
h.NoError(err, "NewAddress")
return resp
}
// WalletBalance makes a RPC call to WalletBalance and asserts.
func (h *HarnessRPC) WalletBalance() *lnrpc.WalletBalanceResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
req := &lnrpc.WalletBalanceRequest{}
resp, err := h.LN.WalletBalance(ctxt, req)
h.NoError(err, "WalletBalance")
return resp
}
// ListPeers makes a RPC call to the node's ListPeers and asserts.
func (h *HarnessRPC) ListPeers() *lnrpc.ListPeersResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
resp, err := h.LN.ListPeers(ctxt, &lnrpc.ListPeersRequest{})
h.NoError(err, "ListPeers")
return resp
}
// DisconnectPeer calls the DisconnectPeer RPC on a given node with a specified
// public key string and asserts there's no error.
func (h *HarnessRPC) DisconnectPeer(
pubkey string) *lnrpc.DisconnectPeerResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
req := &lnrpc.DisconnectPeerRequest{PubKey: pubkey}
resp, err := h.LN.DisconnectPeer(ctxt, req)
h.NoError(err, "DisconnectPeer")
return resp
}
// DeleteAllPayments makes a RPC call to the node's DeleteAllPayments and
// asserts.
func (h *HarnessRPC) DeleteAllPayments() {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
req := &lnrpc.DeleteAllPaymentsRequest{}
_, err := h.LN.DeleteAllPayments(ctxt, req)
h.NoError(err, "DeleteAllPayments")
}
// GetInfo calls the GetInfo RPC on a given node and asserts there's no error.
func (h *HarnessRPC) GetInfo() *lnrpc.GetInfoResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
info, err := h.LN.GetInfo(ctxt, &lnrpc.GetInfoRequest{})
h.NoError(err, "GetInfo")
return info
}
// ConnectPeer makes a RPC call to ConnectPeer and asserts there's no error.
func (h *HarnessRPC) ConnectPeer(
req *lnrpc.ConnectPeerRequest) *lnrpc.ConnectPeerResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
resp, err := h.LN.ConnectPeer(ctxt, req)
h.NoError(err, "ConnectPeer")
return resp
}
// ConnectPeerAssertErr makes a RPC call to ConnectPeer and asserts an error
// returned.
func (h *HarnessRPC) ConnectPeerAssertErr(req *lnrpc.ConnectPeerRequest) error {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
_, err := h.LN.ConnectPeer(ctxt, req)
require.Error(h, err, "expected an error from ConnectPeer")
return err
}
// ListChannels list the channels for the given node and asserts it's
// successful.
func (h *HarnessRPC) ListChannels(
req *lnrpc.ListChannelsRequest) *lnrpc.ListChannelsResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
resp, err := h.LN.ListChannels(ctxt, req)
h.NoError(err, "ListChannels")
return resp
}
// PendingChannels makes a RPC request to PendingChannels and asserts there's
// no error.
func (h *HarnessRPC) PendingChannels() *lnrpc.PendingChannelsResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
pendingChansRequest := &lnrpc.PendingChannelsRequest{}
resp, err := h.LN.PendingChannels(ctxt, pendingChansRequest)
// TODO(yy): We may get a `unable to find arbitrator` error from the
// rpc point, due to a timing issue in rpcserver,
// 1. `r.server.chanStateDB.FetchClosedChannels` fetches
// the pending force close channel.
// 2. `r.arbitratorPopulateForceCloseResp` relies on the
// channel arbitrator to get the report, and,
// 3. the arbitrator may be deleted due to the force close
// channel being resolved.
// Somewhere along the line is missing a lock to keep the data
// consistent.
//
// Return if there's no error.
if err == nil {
return resp
}
// Otherwise, give it a second shot if it's the arbitrator error.
if strings.Contains(err.Error(), "unable to find arbitrator") {
resp, err = h.LN.PendingChannels(ctxt, pendingChansRequest)
}
// It's very unlikely we'd get the arbitrator not found error again.
h.NoError(err, "PendingChannels")
return resp
}
// ClosedChannels makes a RPC call to node's ClosedChannels and asserts.
func (h *HarnessRPC) ClosedChannels(
req *lnrpc.ClosedChannelsRequest) *lnrpc.ClosedChannelsResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
resp, err := h.LN.ClosedChannels(ctxt, req)
h.NoError(err, "ClosedChannels")
return resp
}
// ListPayments lists the node's payments and asserts.
func (h *HarnessRPC) ListPayments(
req *lnrpc.ListPaymentsRequest) *lnrpc.ListPaymentsResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
resp, err := h.LN.ListPayments(ctxt, req)
h.NoError(err, "ListPayments")
return resp
}
// ListInvoices list the node's invoice using the request and asserts.
func (h *HarnessRPC) ListInvoices(
req *lnrpc.ListInvoiceRequest) *lnrpc.ListInvoiceResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
resp, err := h.LN.ListInvoices(ctxt, req)
h.NoError(err, "ListInvoice")
return resp
}
// DescribeGraph makes a RPC call to the node's DescribeGraph and asserts. It
// takes a bool to indicate whether we want to include private edges or not.
func (h *HarnessRPC) DescribeGraph(
req *lnrpc.ChannelGraphRequest) *lnrpc.ChannelGraph {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
resp, err := h.LN.DescribeGraph(ctxt, req)
h.NoError(err, "DescribeGraph")
return resp
}
// ChannelBalance gets the channel balance and asserts.
func (h *HarnessRPC) ChannelBalance() *lnrpc.ChannelBalanceResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
req := &lnrpc.ChannelBalanceRequest{}
resp, err := h.LN.ChannelBalance(ctxt, req)
h.NoError(err, "ChannelBalance")
return resp
}
type OpenChanClient lnrpc.Lightning_OpenChannelClient
// OpenChannel makes a rpc call to LightningClient and returns the open channel
// client.
func (h *HarnessRPC) OpenChannel(req *lnrpc.OpenChannelRequest) OpenChanClient {
stream, err := h.LN.OpenChannel(h.runCtx, req)
h.NoError(err, "OpenChannel")
return stream
}
type CloseChanClient lnrpc.Lightning_CloseChannelClient
// CloseChannel makes a rpc call to LightningClient and returns the close
// channel client.
func (h *HarnessRPC) CloseChannel(
req *lnrpc.CloseChannelRequest) CloseChanClient {
// Use runCtx here instead of a timeout context to keep the client
// alive for the entire test case.
stream, err := h.LN.CloseChannel(h.runCtx, req)
h.NoError(err, "CloseChannel")
return stream
}
// FundingStateStep makes a RPC call to FundingStateStep and asserts.
func (h *HarnessRPC) FundingStateStep(
msg *lnrpc.FundingTransitionMsg) *lnrpc.FundingStateStepResp {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
resp, err := h.LN.FundingStateStep(ctxt, msg)
h.NoError(err, "FundingStateStep")
return resp
}
// FundingStateStepAssertErr makes a RPC call to FundingStateStep and asserts
// there's an error.
func (h *HarnessRPC) FundingStateStepAssertErr(m *lnrpc.FundingTransitionMsg) {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
_, err := h.LN.FundingStateStep(ctxt, m)
require.Error(h, err, "expected an error from FundingStateStep")
}
// AddInvoice adds a invoice for the given node and asserts.
func (h *HarnessRPC) AddInvoice(req *lnrpc.Invoice) *lnrpc.AddInvoiceResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
invoice, err := h.LN.AddInvoice(ctxt, req)
h.NoError(err, "AddInvoice")
return invoice
}
// AbandonChannel makes a RPC call to AbandonChannel and asserts.
func (h *HarnessRPC) AbandonChannel(
req *lnrpc.AbandonChannelRequest) *lnrpc.AbandonChannelResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
resp, err := h.LN.AbandonChannel(ctxt, req)
h.NoError(err, "AbandonChannel")
return resp
}
// ExportAllChanBackups makes a RPC call to the node's ExportAllChannelBackups
// and asserts.
func (h *HarnessRPC) ExportAllChanBackups() *lnrpc.ChanBackupSnapshot {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
req := &lnrpc.ChanBackupExportRequest{}
chanBackup, err := h.LN.ExportAllChannelBackups(ctxt, req)
h.NoError(err, "ExportAllChannelBackups")
return chanBackup
}
// ExportChanBackup makes a RPC call to the node's ExportChannelBackup
// and asserts.
func (h *HarnessRPC) ExportChanBackup(
chanPoint *lnrpc.ChannelPoint) *lnrpc.ChannelBackup {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
req := &lnrpc.ExportChannelBackupRequest{
ChanPoint: chanPoint,
}
chanBackup, err := h.LN.ExportChannelBackup(ctxt, req)
h.NoError(err, "ExportChannelBackup")
return chanBackup
}
// RestoreChanBackups makes a RPC call to the node's RestoreChannelBackups and
// asserts.
func (h *HarnessRPC) RestoreChanBackups(
req *lnrpc.RestoreChanBackupRequest) *lnrpc.RestoreBackupResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
resp, err := h.LN.RestoreChannelBackups(ctxt, req)
h.NoError(err, "RestoreChannelBackups")
return resp
}
type AcceptorClient lnrpc.Lightning_ChannelAcceptorClient
// ChannelAcceptor makes a RPC call to the node's ChannelAcceptor and asserts.
func (h *HarnessRPC) ChannelAcceptor() (AcceptorClient, context.CancelFunc) {
// Use runCtx here instead of a timeout context to keep the client
// alive for the entire test case.
ctxt, cancel := context.WithCancel(h.runCtx)
resp, err := h.LN.ChannelAcceptor(ctxt)
h.NoError(err, "ChannelAcceptor")
return resp, cancel
}
// SendCoins sends a given amount of money to the specified address from the
// passed node.
func (h *HarnessRPC) SendCoins(
req *lnrpc.SendCoinsRequest) *lnrpc.SendCoinsResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
resp, err := h.LN.SendCoins(ctxt, req)
h.NoError(err, "SendCoins")
return resp
}
// SendCoinsAssertErr sends a given amount of money to the specified address
// from the passed node and asserts an error has returned.
func (h *HarnessRPC) SendCoinsAssertErr(req *lnrpc.SendCoinsRequest) {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
_, err := h.LN.SendCoins(ctxt, req)
require.Error(h, err, "node %s didn't not return an error", h.Name)
}
// GetTransactions makes a RPC call to GetTransactions and asserts.
func (h *HarnessRPC) GetTransactions(
req *lnrpc.GetTransactionsRequest) *lnrpc.TransactionDetails {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
if req == nil {
req = &lnrpc.GetTransactionsRequest{}
}
resp, err := h.LN.GetTransactions(ctxt, req)
h.NoError(err, "GetTransactions")
return resp
}
// SignMessage makes a RPC call to node's SignMessage and asserts.
func (h *HarnessRPC) SignMessage(msg []byte) *lnrpc.SignMessageResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
req := &lnrpc.SignMessageRequest{Msg: msg}
resp, err := h.LN.SignMessage(ctxt, req)
h.NoError(err, "SignMessage")
return resp
}
// VerifyMessage makes a RPC call to node's VerifyMessage and asserts.
func (h *HarnessRPC) VerifyMessage(msg []byte,
sig string) *lnrpc.VerifyMessageResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
req := &lnrpc.VerifyMessageRequest{Msg: msg, Signature: sig}
resp, err := h.LN.VerifyMessage(ctxt, req)
h.NoError(err, "VerifyMessage")
return resp
}
// GetRecoveryInfo uses the specified node to make a RPC call to
// GetRecoveryInfo and asserts.
func (h *HarnessRPC) GetRecoveryInfo(
req *lnrpc.GetRecoveryInfoRequest) *lnrpc.GetRecoveryInfoResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
if req == nil {
req = &lnrpc.GetRecoveryInfoRequest{}
}
resp, err := h.LN.GetRecoveryInfo(ctxt, req)
h.NoError(err, "GetRecoveryInfo")
return resp
}
// BatchOpenChannel makes a RPC call to BatchOpenChannel and asserts.
func (h *HarnessRPC) BatchOpenChannel(
req *lnrpc.BatchOpenChannelRequest) *lnrpc.BatchOpenChannelResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
resp, err := h.LN.BatchOpenChannel(ctxt, req)
h.NoError(err, "BatchOpenChannel")
return resp
}
// BatchOpenChannelAssertErr makes a RPC call to BatchOpenChannel and asserts
// there's an error returned.
func (h *HarnessRPC) BatchOpenChannelAssertErr(
req *lnrpc.BatchOpenChannelRequest) error {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
_, err := h.LN.BatchOpenChannel(ctxt, req)
require.Error(h, err, "expecte batch open channel fail")
return err
}
// QueryRoutes makes a RPC call to QueryRoutes and asserts.
func (h *HarnessRPC) QueryRoutes(
req *lnrpc.QueryRoutesRequest) *lnrpc.QueryRoutesResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
routes, err := h.LN.QueryRoutes(ctxt, req)
h.NoError(err, "QueryRoutes")
return routes
}
// SendToRoute makes a RPC call to SendToRoute and asserts.
func (h *HarnessRPC) SendToRoute() lnrpc.Lightning_SendToRouteClient {
// SendToRoute needs to have the context alive for the entire test case
// as the returned client will be used for send and receive payment
// stream. Thus we use runCtx here instead of a timeout context.
client, err := h.LN.SendToRoute(h.runCtx)
h.NoError(err, "SendToRoute")
return client
}
// SendToRouteSync makes a RPC call to SendToRouteSync and asserts.
func (h *HarnessRPC) SendToRouteSync(
req *lnrpc.SendToRouteRequest) *lnrpc.SendResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
resp, err := h.LN.SendToRouteSync(ctxt, req)
h.NoError(err, "SendToRouteSync")
return resp
}
// UpdateChannelPolicy makes a RPC call to UpdateChannelPolicy and asserts.
func (h *HarnessRPC) UpdateChannelPolicy(
req *lnrpc.PolicyUpdateRequest) *lnrpc.PolicyUpdateResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
resp, err := h.LN.UpdateChannelPolicy(ctxt, req)
h.NoError(err, "UpdateChannelPolicy")
return resp
}
type InvoiceUpdateClient lnrpc.Lightning_SubscribeInvoicesClient
// SubscribeInvoices creates a subscription client for invoice events and
// asserts its creation.
//
// NOTE: make sure to subscribe an invoice as early as possible as it takes
// some time for the lnd to create the subscription client. If an invoice is
// added right after the subscription, it may be missed. However, if AddIndex
// or SettleIndex is used in the request, it will be fine as a backlog will
// always be sent.
func (h *HarnessRPC) SubscribeInvoices(
req *lnrpc.InvoiceSubscription) InvoiceUpdateClient {
// SubscribeInvoices needs to have the context alive for the
// entire test case as the returned client will be used for send and
// receive events stream. Thus we use runCtx here instead of a timeout
// context.
client, err := h.LN.SubscribeInvoices(h.runCtx, req)
h.NoError(err, "SubscribeInvoices")
return client
}
type BackupSubscriber lnrpc.Lightning_SubscribeChannelBackupsClient
// SubscribeChannelBackups creates a client to listen to channel backup stream.
func (h *HarnessRPC) SubscribeChannelBackups() BackupSubscriber {
// Use runCtx here instead of timeout context to keep the stream client
// alive.
backupStream, err := h.LN.SubscribeChannelBackups(
h.runCtx, &lnrpc.ChannelBackupSubscription{},
)
h.NoError(err, "SubscribeChannelBackups")
return backupStream
}
// VerifyChanBackup makes a RPC call to node's VerifyChanBackup and asserts.
func (h *HarnessRPC) VerifyChanBackup(
ss *lnrpc.ChanBackupSnapshot) *lnrpc.VerifyChanBackupResponse {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
resp, err := h.LN.VerifyChanBackup(ctxt, ss)
h.NoError(err, "VerifyChanBackup")
return resp
}