Merge pull request #5097 from ellemouton/lncli-interrupt-handler

lncli: cancel RPC context on OS interrupts
This commit is contained in:
Oliver Gugger
2021-03-17 10:31:08 +01:00
committed by GitHub
19 changed files with 211 additions and 181 deletions

View File

@@ -23,6 +23,7 @@ import (
"github.com/lightninglabs/protobuf-hex-display/proto"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/routing/route"
"github.com/lightningnetwork/lnd/signal"
"github.com/urfave/cli"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
@@ -39,6 +40,15 @@ const (
defaultUtxoMinConf = 1
)
func getContext() context.Context {
ctxc, cancel := context.WithCancel(context.Background())
go func() {
<-signal.ShutdownChannel()
cancel()
}()
return ctxc
}
func printJSON(resp interface{}) {
b, err := json.Marshal(resp)
if err != nil {
@@ -119,6 +129,7 @@ var newAddressCommand = cli.Command{
}
func newAddress(ctx *cli.Context) error {
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -137,8 +148,7 @@ func newAddress(ctx *cli.Context) error {
"are: p2wkh and np2wkh", stringAddrType)
}
ctxb := context.Background()
addr, err := client.NewAddress(ctxb, &lnrpc.NewAddressRequest{
addr, err := client.NewAddress(ctxc, &lnrpc.NewAddressRequest{
Type: addrType,
})
if err != nil {
@@ -172,6 +182,7 @@ var estimateFeeCommand = cli.Command{
}
func estimateFees(ctx *cli.Context) error {
ctxc := getContext()
var amountToAddr map[string]int64
jsonMap := ctx.Args().First()
@@ -179,11 +190,10 @@ func estimateFees(ctx *cli.Context) error {
return err
}
ctxb := context.Background()
client, cleanUp := getClient(ctx)
defer cleanUp()
resp, err := client.EstimateFee(ctxb, &lnrpc.EstimateFeeRequest{
resp, err := client.EstimateFee(ctxc, &lnrpc.EstimateFeeRequest{
AddrToAmount: amountToAddr,
TargetConf: int32(ctx.Int64("conf_target")),
})
@@ -260,6 +270,7 @@ func sendCoins(ctx *cli.Context) error {
amt int64
err error
)
ctxc := getContext()
args := ctx.Args()
if ctx.NArg() == 0 && ctx.NumFlags() == 0 {
@@ -299,7 +310,6 @@ func sendCoins(ctx *cli.Context) error {
"sweep all coins out of the wallet")
}
ctxb := context.Background()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -314,7 +324,7 @@ func sendCoins(ctx *cli.Context) error {
MinConfs: minConfs,
SpendUnconfirmed: minConfs == 0,
}
txid, err := client.SendCoins(ctxb, req)
txid, err := client.SendCoins(ctxc, req)
if err != nil {
return err
}
@@ -367,6 +377,7 @@ func listUnspent(ctx *cli.Context) error {
maxConfirms int64
err error
)
ctxc := getContext()
args := ctx.Args()
if ctx.IsSet("max_confs") && !ctx.IsSet("min_confs") {
@@ -413,7 +424,6 @@ func listUnspent(ctx *cli.Context) error {
maxConfirms = math.MaxInt32
}
ctxb := context.Background()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -421,7 +431,7 @@ func listUnspent(ctx *cli.Context) error {
MinConfs: int32(minConfirms),
MaxConfs: int32(maxConfirms),
}
resp, err := client.ListUnspent(ctxb, req)
resp, err := client.ListUnspent(ctxc, req)
if err != nil {
return err
}
@@ -481,6 +491,7 @@ var sendManyCommand = cli.Command{
}
func sendMany(ctx *cli.Context) error {
ctxc := getContext()
var amountToAddr map[string]int64
jsonMap := ctx.Args().First()
@@ -493,12 +504,11 @@ func sendMany(ctx *cli.Context) error {
"set, but not both")
}
ctxb := context.Background()
client, cleanUp := getClient(ctx)
defer cleanUp()
minConfs := int32(ctx.Uint64("min_confs"))
txid, err := client.SendMany(ctxb, &lnrpc.SendManyRequest{
txid, err := client.SendMany(ctxc, &lnrpc.SendManyRequest{
AddrToAmount: amountToAddr,
TargetConf: int32(ctx.Int64("conf_target")),
SatPerByte: ctx.Int64("sat_per_byte"),
@@ -546,7 +556,7 @@ var connectCommand = cli.Command{
}
func connectPeer(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -567,7 +577,7 @@ func connectPeer(ctx *cli.Context) error {
Timeout: uint64(ctx.Duration("timeout").Seconds()),
}
lnid, err := client.ConnectPeer(ctxb, req)
lnid, err := client.ConnectPeer(ctxc, req)
if err != nil {
return err
}
@@ -592,7 +602,7 @@ var disconnectCommand = cli.Command{
}
func disconnectPeer(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -610,7 +620,7 @@ func disconnectPeer(ctx *cli.Context) error {
PubKey: pubKey,
}
lnid, err := client.DisconnectPeer(ctxb, req)
lnid, err := client.DisconnectPeer(ctxc, req)
if err != nil {
return err
}
@@ -691,6 +701,7 @@ var closeChannelCommand = cli.Command{
}
func closeChannel(ctx *cli.Context) error {
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -733,7 +744,7 @@ func closeChannel(ctx *cli.Context) error {
})
}()
err = executeChannelClose(client, req, txidChan, ctx.Bool("block"))
err = executeChannelClose(ctxc, client, req, txidChan, ctx.Bool("block"))
if err != nil {
return err
}
@@ -750,10 +761,10 @@ func closeChannel(ctx *cli.Context) error {
// transaction ID is sent through `txidChan` as soon as it is broadcasted to the
// network. The block boolean is used to determine if we should block until the
// closing transaction receives all of its required confirmations.
func executeChannelClose(client lnrpc.LightningClient, req *lnrpc.CloseChannelRequest,
txidChan chan<- string, block bool) error {
func executeChannelClose(ctxc context.Context, client lnrpc.LightningClient,
req *lnrpc.CloseChannelRequest, txidChan chan<- string, block bool) error {
stream, err := client.CloseChannel(context.Background(), req)
stream, err := client.CloseChannel(ctxc, req)
if err != nil {
return err
}
@@ -836,11 +847,12 @@ var closeAllChannelsCommand = cli.Command{
}
func closeAllChannels(ctx *cli.Context) error {
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
listReq := &lnrpc.ListChannelsRequest{}
openChannels, err := client.ListChannels(context.Background(), listReq)
openChannels, err := client.ListChannels(ctxc, listReq)
if err != nil {
return fmt.Errorf("unable to fetch open channels: %v", err)
}
@@ -971,7 +983,7 @@ func closeAllChannels(ctx *cli.Context) error {
}
txidChan := make(chan string, 1)
err = executeChannelClose(client, req, txidChan, false)
err = executeChannelClose(ctxc, client, req, txidChan, false)
if err != nil {
res.FailErr = fmt.Sprintf("unable to close "+
"channel: %v", err)
@@ -1046,8 +1058,7 @@ var abandonChannelCommand = cli.Command{
}
func abandonChannel(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -1066,7 +1077,7 @@ func abandonChannel(ctx *cli.Context) error {
ChannelPoint: channelPoint,
}
resp, err := client.AbandonChannel(ctxb, req)
resp, err := client.AbandonChannel(ctxc, req)
if err != nil {
return err
}
@@ -1126,7 +1137,7 @@ var listPeersCommand = cli.Command{
}
func listPeers(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -1135,7 +1146,7 @@ func listPeers(ctx *cli.Context) error {
req := &lnrpc.ListPeersRequest{
LatestError: !ctx.IsSet("list_errors"),
}
resp, err := client.ListPeers(ctxb, req)
resp, err := client.ListPeers(ctxc, req)
if err != nil {
return err
}
@@ -1152,12 +1163,12 @@ var walletBalanceCommand = cli.Command{
}
func walletBalance(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
req := &lnrpc.WalletBalanceRequest{}
resp, err := client.WalletBalance(ctxb, req)
resp, err := client.WalletBalance(ctxc, req)
if err != nil {
return err
}
@@ -1175,12 +1186,12 @@ var channelBalanceCommand = cli.Command{
}
func channelBalance(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
req := &lnrpc.ChannelBalanceRequest{}
resp, err := client.ChannelBalance(ctxb, req)
resp, err := client.ChannelBalance(ctxc, req)
if err != nil {
return err
}
@@ -1196,12 +1207,12 @@ var getInfoCommand = cli.Command{
}
func getInfo(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
req := &lnrpc.GetInfoRequest{}
resp, err := client.GetInfo(ctxb, req)
resp, err := client.GetInfo(ctxc, req)
if err != nil {
return err
}
@@ -1217,12 +1228,12 @@ var getRecoveryInfoCommand = cli.Command{
}
func getRecoveryInfo(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
req := &lnrpc.GetRecoveryInfoRequest{}
resp, err := client.GetRecoveryInfo(ctxb, req)
resp, err := client.GetRecoveryInfo(ctxc, req)
if err != nil {
return err
}
@@ -1239,12 +1250,12 @@ var pendingChannelsCommand = cli.Command{
}
func pendingChannels(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
req := &lnrpc.PendingChannelsRequest{}
resp, err := client.PendingChannels(ctxb, req)
resp, err := client.PendingChannels(ctxc, req)
if err != nil {
return err
}
@@ -1286,7 +1297,7 @@ var listChannelsCommand = cli.Command{
}
func listChannels(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -1312,7 +1323,7 @@ func listChannels(ctx *cli.Context) error {
Peer: peerKey,
}
resp, err := client.ListChannels(ctxb, req)
resp, err := client.ListChannels(ctxc, req)
if err != nil {
return err
}
@@ -1361,7 +1372,7 @@ var closedChannelsCommand = cli.Command{
}
func closedChannels(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -1374,7 +1385,7 @@ func closedChannels(ctx *cli.Context) error {
Abandoned: ctx.Bool("abandoned"),
}
resp, err := client.ClosedChannels(ctxb, req)
resp, err := client.ClosedChannels(ctxc, req)
if err != nil {
return err
}
@@ -1402,6 +1413,7 @@ var describeGraphCommand = cli.Command{
}
func describeGraph(ctx *cli.Context) error {
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -1409,7 +1421,7 @@ func describeGraph(ctx *cli.Context) error {
IncludeUnannounced: ctx.Bool("include_unannounced"),
}
graph, err := client.DescribeGraph(context.Background(), req)
graph, err := client.DescribeGraph(ctxc, req)
if err != nil {
return err
}
@@ -1427,6 +1439,7 @@ var getNodeMetricsCommand = cli.Command{
}
func getNodeMetrics(ctx *cli.Context) error {
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -1434,7 +1447,7 @@ func getNodeMetrics(ctx *cli.Context) error {
Types: []lnrpc.NodeMetricType{lnrpc.NodeMetricType_BETWEENNESS_CENTRALITY},
}
nodeMetrics, err := client.GetNodeMetrics(context.Background(), req)
nodeMetrics, err := client.GetNodeMetrics(ctxc, req)
if err != nil {
return err
}
@@ -1489,6 +1502,7 @@ var listPaymentsCommand = cli.Command{
}
func listPayments(ctx *cli.Context) error {
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -1499,7 +1513,7 @@ func listPayments(ctx *cli.Context) error {
Reversed: !ctx.Bool("paginate_forwards"),
}
payments, err := client.ListPayments(context.Background(), req)
payments, err := client.ListPayments(ctxc, req)
if err != nil {
return err
}
@@ -1525,7 +1539,7 @@ var getChanInfoCommand = cli.Command{
}
func getChanInfo(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -1550,7 +1564,7 @@ func getChanInfo(ctx *cli.Context) error {
ChanId: uint64(chanID),
}
chanInfo, err := client.GetChanInfo(ctxb, req)
chanInfo, err := client.GetChanInfo(ctxc, req)
if err != nil {
return err
}
@@ -1581,7 +1595,7 @@ var getNodeInfoCommand = cli.Command{
}
func getNodeInfo(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -1602,7 +1616,7 @@ func getNodeInfo(ctx *cli.Context) error {
IncludeChannels: ctx.Bool("include_channels"),
}
nodeInfo, err := client.GetNodeInfo(ctxb, req)
nodeInfo, err := client.GetNodeInfo(ctxc, req)
if err != nil {
return err
}
@@ -1657,7 +1671,7 @@ var queryRoutesCommand = cli.Command{
}
func queryRoutes(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -1706,7 +1720,7 @@ func queryRoutes(ctx *cli.Context) error {
OutgoingChanId: ctx.Uint64("outgoing_chanid"),
}
route, err := client.QueryRoutes(ctxb, req)
route, err := client.QueryRoutes(ctxc, req)
if err != nil {
return err
}
@@ -1758,13 +1772,13 @@ var getNetworkInfoCommand = cli.Command{
}
func getNetworkInfo(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
req := &lnrpc.NetworkInfoRequest{}
netInfo, err := client.GetNetworkInfo(ctxb, req)
netInfo, err := client.GetNetworkInfo(ctxc, req)
if err != nil {
return err
}
@@ -1794,7 +1808,7 @@ var debugLevelCommand = cli.Command{
}
func debugLevel(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
req := &lnrpc.DebugLevelRequest{
@@ -1802,7 +1816,7 @@ func debugLevel(ctx *cli.Context) error {
LevelSpec: ctx.String("level"),
}
resp, err := client.DebugLevel(ctxb, req)
resp, err := client.DebugLevel(ctxc, req)
if err != nil {
return err
}
@@ -1846,7 +1860,7 @@ var listChainTxnsCommand = cli.Command{
}
func listChainTxns(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -1859,7 +1873,7 @@ func listChainTxns(ctx *cli.Context) error {
req.EndHeight = int32(ctx.Int64("end_height"))
}
resp, err := client.GetTransactions(ctxb, req)
resp, err := client.GetTransactions(ctxc, req)
if err != nil {
return err
}
@@ -1878,11 +1892,11 @@ var stopCommand = cli.Command{
}
func stopDaemon(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
_, err := client.StopDaemon(ctxb, &lnrpc.StopRequest{})
_, err := client.StopDaemon(ctxc, &lnrpc.StopRequest{})
if err != nil {
return err
}
@@ -1910,7 +1924,7 @@ var signMessageCommand = cli.Command{
}
func signMessage(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -1925,7 +1939,7 @@ func signMessage(ctx *cli.Context) error {
return fmt.Errorf("msg argument missing")
}
resp, err := client.SignMessage(ctxb, &lnrpc.SignMessageRequest{Msg: msg})
resp, err := client.SignMessage(ctxc, &lnrpc.SignMessageRequest{Msg: msg})
if err != nil {
return err
}
@@ -1959,7 +1973,7 @@ var verifyMessageCommand = cli.Command{
}
func verifyMessage(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -1990,7 +2004,7 @@ func verifyMessage(ctx *cli.Context) error {
}
req := &lnrpc.VerifyMessageRequest{Msg: msg, Signature: sig}
resp, err := client.VerifyMessage(ctxb, req)
resp, err := client.VerifyMessage(ctxc, req)
if err != nil {
return err
}
@@ -2010,12 +2024,12 @@ var feeReportCommand = cli.Command{
}
func feeReport(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
req := &lnrpc.FeeReportRequest{}
resp, err := client.FeeReport(ctxb, req)
resp, err := client.FeeReport(ctxc, req)
if err != nil {
return err
}
@@ -2103,7 +2117,7 @@ func parseChanPoint(s string) (*lnrpc.ChannelPoint, error) {
}
func updateChannelPolicy(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -2198,7 +2212,7 @@ func updateChannelPolicy(ctx *cli.Context) error {
}
}
resp, err := client.UpdateChannelPolicy(ctxb, req)
resp, err := client.UpdateChannelPolicy(ctxc, req)
if err != nil {
return err
}
@@ -2254,7 +2268,7 @@ var forwardingHistoryCommand = cli.Command{
}
func forwardingHistory(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -2323,7 +2337,7 @@ func forwardingHistory(ctx *cli.Context) error {
IndexOffset: indexOffset,
NumMaxEvents: maxEvents,
}
resp, err := client.ForwardingHistory(ctxb, req)
resp, err := client.ForwardingHistory(ctxc, req)
if err != nil {
return err
}
@@ -2386,7 +2400,7 @@ var exportChanBackupCommand = cli.Command{
}
func exportChanBackup(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -2420,7 +2434,7 @@ func exportChanBackup(ctx *cli.Context) error {
}
chanBackup, err := client.ExportChannelBackup(
ctxb, &lnrpc.ExportChannelBackupRequest{
ctxc, &lnrpc.ExportChannelBackupRequest{
ChanPoint: chanPointRPC,
},
)
@@ -2455,7 +2469,7 @@ func exportChanBackup(ctx *cli.Context) error {
}
chanBackup, err := client.ExportAllChannelBackups(
ctxb, &lnrpc.ChanBackupExportRequest{},
ctxc, &lnrpc.ChanBackupExportRequest{},
)
if err != nil {
return err
@@ -2531,7 +2545,7 @@ var verifyChanBackupCommand = cli.Command{
}
func verifyChanBackup(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -2557,7 +2571,7 @@ func verifyChanBackup(ctx *cli.Context) error {
}
}
resp, err := client.VerifyChanBackup(ctxb, &verifyReq)
resp, err := client.VerifyChanBackup(ctxc, &verifyReq)
if err != nil {
return err
}
@@ -2673,7 +2687,7 @@ func parseChanBackups(ctx *cli.Context) (*lnrpc.RestoreChanBackupRequest, error)
}
func restoreChanBackup(ctx *cli.Context) error {
ctxb := context.Background()
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()
@@ -2692,7 +2706,7 @@ func restoreChanBackup(ctx *cli.Context) error {
req.Backup = backups.Backup
_, err = client.RestoreChannelBackups(ctxb, &req)
_, err = client.RestoreChannelBackups(ctxc, &req)
if err != nil {
return fmt.Errorf("unable to restore chan backups: %v", err)
}