From 92a77ce7bb66290546e4df87f51d928943c52d75 Mon Sep 17 00:00:00 2001 From: Jonathan Zernik Date: Sun, 11 Oct 2020 07:01:35 -0700 Subject: [PATCH] Add subscribe channel events rpc (#283) * Add subscribe channel events rpc * Upgrade lnd to 0.11.1 (#284) * Got test working for open and close channel with subscriptions --- docker/lnd/Dockerfile | 2 +- itests/tests/test_squeak_node.py | 22 +++++++++++++++++++ proto/lnd.proto | 20 ++++++++--------- proto/squeak_admin.proto | 4 ++++ .../admin/squeak_admin_server_handler.py | 4 ++++ .../admin/squeak_admin_server_servicer.py | 3 +++ squeakserver/common/lnd_lightning_client.py | 7 ++++++ 7 files changed, 51 insertions(+), 11 deletions(-) diff --git a/docker/lnd/Dockerfile b/docker/lnd/Dockerfile index 87a35b14..5ad5abe9 100644 --- a/docker/lnd/Dockerfile +++ b/docker/lnd/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.12-alpine as builder +FROM golang:1.13-alpine as builder MAINTAINER Olaoluwa Osuntokun diff --git a/itests/tests/test_squeak_node.py b/itests/tests/test_squeak_node.py index 5c678003..f7cb9714 100644 --- a/itests/tests/test_squeak_node.py +++ b/itests/tests/test_squeak_node.py @@ -756,3 +756,25 @@ def test_open_channel(server_stub, admin_stub, lightning_client, saved_squeak_ha pending_channels_response = admin_stub.LndPendingChannels(ln.PendingChannelsRequest()) assert len(pending_channels_response.pending_open_channels) == 1 + + subscribe_channel_events_response = admin_stub.LndSubscribeChannelEvents(ln.ChannelEventSubscription()) + for update in subscribe_channel_events_response: + if update.HasField("active_channel"): + channel_point = update.active_channel + print("Channel now open: " + str(channel_point)) + break + + list_channels_response = admin_stub.LndListChannels(ln.ListChannelsRequest()) + assert len(list_channels_response.channels) == 1 + + # Close the channel + close_channel_response = admin_stub.LndCloseChannel(ln.CloseChannelRequest( + channel_point=channel_point, + )) + for update in close_channel_response: + if update.HasField("chan_close"): + print("Channel now closed.") + break + + list_channels_response = admin_stub.LndListChannels(ln.ListChannelsRequest()) + assert len(list_channels_response.channels) == 0 diff --git a/proto/lnd.proto b/proto/lnd.proto index 5d574b70..ee5504d7 100644 --- a/proto/lnd.proto +++ b/proto/lnd.proto @@ -131,7 +131,7 @@ service Lightning { the client in which any events relevant to the state of peers are sent over. Events include peers going online and offline. */ - rpc SubscribePeerEvents (PeerEventPeer) returns (stream PeerEvent); + rpc SubscribePeerEvents (PeerEventSubscription) returns (stream PeerEvent); /* lncli: `getinfo` GetInfo returns general information concerning the lightning node including @@ -170,7 +170,7 @@ service Lightning { sent over. Events include new active channels, inactive channels, and closed channels. */ - rpc SubscribeChannelEvents (ChannelEventPeer) + rpc SubscribeChannelEvents (ChannelEventSubscription) returns (stream ChannelEventUpdate); /* lncli: `closedchannels` @@ -312,7 +312,7 @@ service Lightning { of these fields can be set. If no fields are set, then we'll only send out the latest add/settle events. */ - rpc SubscribeInvoices (InvoicePeer) returns (stream Invoice); + rpc SubscribeInvoices (InvoiceSubscription) returns (stream Invoice); /* lncli: `decodepayreq` DecodePayReq takes an encoded payment request string and attempts to decode @@ -396,7 +396,7 @@ service Lightning { channels being advertised, updates in the routing policy for a directional channel edge, and when channels are closed on-chain. */ - rpc SubscribeChannelGraph (GraphTopologyPeer) + rpc SubscribeChannelGraph (GraphTopologySubscription) returns (stream GraphTopologyUpdate); /* lncli: `debuglevel` @@ -482,7 +482,7 @@ service Lightning { ups, but the updated set of encrypted multi-chan backups with the closed channel(s) removed. */ - rpc SubscribeChannelBackups (ChannelBackupPeer) + rpc SubscribeChannelBackups (ChannelBackupSubscription) returns (stream ChanBackupSnapshot); /* lncli: `bakemacaroon` @@ -1416,7 +1416,7 @@ message ListPeersResponse { repeated Peer peers = 1; } -message PeerEventPeer { +message PeerEventSubscription { } message PeerEvent { @@ -2042,7 +2042,7 @@ message PendingChannelsResponse { repeated WaitingCloseChannel waiting_close_channels = 5; } -message ChannelEventPeer { +message ChannelEventSubscription { } message ChannelEventUpdate { @@ -2515,7 +2515,7 @@ message StopRequest { message StopResponse { } -message GraphTopologyPeer { +message GraphTopologySubscription { } message GraphTopologyUpdate { repeated NodeUpdate node_updates = 1; @@ -2845,7 +2845,7 @@ message ListInvoiceResponse { uint64 first_index_offset = 3; } -message InvoicePeer { +message InvoiceSubscription { /* If specified (non-zero), then we'll first start by sending out notifications for all added indexes with an add_index greater than this @@ -3311,7 +3311,7 @@ message RestoreChanBackupRequest { message RestoreBackupResponse { } -message ChannelBackupPeer { +message ChannelBackupSubscription { } message VerifyChanBackupResponse { diff --git a/proto/squeak_admin.proto b/proto/squeak_admin.proto index e70e160e..58e0c3ca 100644 --- a/proto/squeak_admin.proto +++ b/proto/squeak_admin.proto @@ -56,6 +56,10 @@ service SqueakAdmin { */ rpc LndCloseChannel (lnrpc.CloseChannelRequest) returns (stream lnrpc.CloseStatusUpdate) {} + /** sqkadmin: `lndsubscribechannelevents` + */ + rpc LndSubscribeChannelEvents (lnrpc.ChannelEventSubscription) returns (stream lnrpc.ChannelEventUpdate) {} + /** sqkadmin: `createsigningprofile` */ rpc CreateSigningProfile (CreateSigningProfileRequest) returns (CreateSigningProfileReply) {} diff --git a/squeakserver/admin/squeak_admin_server_handler.py b/squeakserver/admin/squeak_admin_server_handler.py index c8c42967..8dc2625e 100644 --- a/squeakserver/admin/squeak_admin_server_handler.py +++ b/squeakserver/admin/squeak_admin_server_handler.py @@ -74,6 +74,10 @@ class SqueakAdminServerHandler(object): channel_point, ) + def handle_lnd_subscribe_channel_events(self): + logger.info("Handle subscribe channel events") + return self.lightning_client.subscribe_channel_events() + def handle_create_signing_profile(self, profile_name): logger.info("Handle create signing profile with name: {}".format(profile_name)) profile_id = self.squeak_node.create_signing_profile(profile_name) diff --git a/squeakserver/admin/squeak_admin_server_servicer.py b/squeakserver/admin/squeak_admin_server_servicer.py index 2a65ab9a..f9097dd5 100644 --- a/squeakserver/admin/squeak_admin_server_servicer.py +++ b/squeakserver/admin/squeak_admin_server_servicer.py @@ -66,6 +66,9 @@ class SqueakAdminServerServicer(squeak_admin_pb2_grpc.SqueakAdminServicer): sat_per_byte, ) + def LndSubscribeChannelEvents(self, request, context): + return self.handler.handle_lnd_subscribe_channel_events() + def CreateSigningProfile(self, request, context): profile_name = request.profile_name profile_id = self.handler.handle_create_signing_profile(profile_name) diff --git a/squeakserver/common/lnd_lightning_client.py b/squeakserver/common/lnd_lightning_client.py index 23e75976..61356b49 100644 --- a/squeakserver/common/lnd_lightning_client.py +++ b/squeakserver/common/lnd_lightning_client.py @@ -206,6 +206,13 @@ class LNDLightningClient: metadata=[("macaroon", self.macaroon)], ) + def subscribe_channel_events(self): + subscribe_channel_events_request = lnd_pb2.ChannelEventSubscription() + return self.stub.SubscribeChannelEvents( + subscribe_channel_events_request, + metadata=[("macaroon", self.macaroon)], + ) + def get_transactions(self): # Get transactions get_transactions_request = lnd_pb2.GetTransactionsRequest()