polar icon indicating copy to clipboard operation
polar copied to clipboard

Feature Request: Implement real-time updates of channel balances from the nodes

Open murtyjones opened this issue 3 years ago • 7 comments

Describe the bug

While working on an example app using Polar, I noticed that opening a channel in the app doesn't seem to reflect in the Polar UI. I assume this is a bug but not 100% sure if Polar is intended to show channels in the pending state.

To Reproduce Steps to reproduce the behavior:

  1. Create a network in Polar (one node for each implementation should be fine), deposit some funds for Alice, and ensure that her balance is confirmed
  2. Run the example app linked above (yarn && yarn start in the example app directory should do it)
  3. Open a channel with one of the peers using the prompts (ignore the fact that pubkeys are being used instead of Aliases for now 😅 )
  4. Execute the List pending channels command and you should see that you have one

Expected behavior I would think that Polar would reflect that there's a pending channel.

Screenshots image image

Desktop:

  • OS: Catalina
  • Polar Version: Master
  • Docker Version: 20
  • Docker Compose Version: 1.27.4

murtyjones avatar Jan 16 '21 23:01 murtyjones

This isn't a bug, more of a feature request. Polar currently doesn't automatically update the UI when events occur on the network outside of Polar. We need to implement subscriptions to the lnd streaming RPCs and maybe do polling on the other implementations that don't support streaming/websockets.

For now, to sync the UI with the state of the nodes, first click on the canvas, then click on the Sync icon at the top of the sidebar.

I'll keep this issue open and this is something I've wanted to implement but havent gotten around to it yet.

jamaljsr avatar Jan 16 '21 23:01 jamaljsr

For now, to sync the UI with the state of the nodes, first click on the canvas, then click on the Sync icon at the top of the sidebar.

Totally missed the sync button, thank you!

murtyjones avatar Jan 17 '21 13:01 murtyjones

We need to implement subscriptions to the lnd streaming RPCs

I've started to play around with this but dealing with an issue that I'm not familiar enough with Electron/this app's setup to resolve.

If we create an IPC event for establishing the stream:

subscribeChannelEvents: 'subscribe-channel-events',
...
const subscribeChannelEvents = async (args: { node: LndNode }) => {
  const rpc = await getRpc(args.node);
  return rpc.subscribeChannelEvents();
};
...
[ipcChannels.subscribeChannelEvents]: subscribeChannelEvents,
...
async subscribeChannelEvents(
  node: LndNode,
): Promise<LND.Readable<LND.GraphTopologyUpdate>> {
  return await this.ipc(ipcChannels.subscribeChannelEvents, { node });
}

Then the stream that's returned from lnrpc (LND.Readable<LND.GraphTopologyUpdate>) is sent back as a plain JS object rather than an instance of a stream. I'm not sure that there's a way to re-serialize the object into a stream. Do you have any ideas of how to make this compatible with the IPC setup @jamaljsr? Hopefully the question makes sense but if not, LMK and I'll elaborate

murtyjones avatar Jan 19 '21 01:01 murtyjones

I understand the issue. The Electron IPC only supports sending & receiving plain JS objects, so streams are not going to work with this approach. The Electron main process would need to subscribe to the lnd streams, then forward the events to the renderer process. In the renderer, there would need to be a listener that receives these events and knows how to update the node associated with each event.

I'm pretty confident this will be a substantial update that requires refactoring a fair amount of the Polar <-> node plumbing code. I would want this to support all the implementations, so we'd need to abstract away the LND specific streaming events into more generic events that can be unified across all nodes. Some may use streams, others may use polling.

Overall, this would require some planning ahead of writing any code in Polar. I haven't investigated each implementation's capabilities enough to be able to suggest an approach right now.

If you wanted to take this on, it would be best to first educate yourself on all the node streaming API's (if they have any). I would then create a separate proof of concept project that just logs the events to the console. once I was happy with an implementation, then I would port the code over to Polar and deal with Electron and the UI.

I don't know if all of this helps at all. I'm just offering my initial thoughts on the topic.

jamaljsr avatar Jan 19 '21 02:01 jamaljsr

Okay, I think that makes sense! I'll play around with the implementations' support for event streaming and see what I find

murtyjones avatar Jan 19 '21 13:01 murtyjones

Spent a little bit of time with this here and discovered the following:

  • lnd has streaming as discussed
  • eclair exposes a websocket with channel opening events
  • c-lightning seems to have nothing other than the standard synchronous calls which could be used in polling

i'm going to spend some time getting to now the app structure better. then maybe i can propose where to slot these in.

murtyjones avatar Jan 26 '21 02:01 murtyjones

Cool, thanks for investigating. Let me know if you have any questions for me.

jamaljsr avatar Jan 26 '21 14:01 jamaljsr

Completed in #837

jamaljsr avatar May 03 '24 13:05 jamaljsr