As far as I understand, closing a payment channel does not trigger a notification to the counterparty right now. In practice, this means that if you are using payment channels, you need to have a process constantly polling to make sure none of your peers have tried to start closing out their channels to you.
It seems like it would be better if the payment channel close transaction generated a notification that would be sent to the receiving party's account notification stream. That way, you could simply have a listener for that event and submit your outstanding claims as soon as you see it.
One potential downside to having such a notification would be if the long-lived websocket connection is not reliable enough to ensure that you definitely get the notification, it might be safer to poll at some interval. If polling is indeed better, it would be nice if ripple-lib included some helper functions for this or a channel watcher that you could run as a separate process.
What do you think?
PS This guide on how to use payment channels does not mention watching out for peers trying to close channels and that's arguably a critical component of using this feature correctly.
I would think a new account_channels subscription would be good for this. Provide an account, get notified by any transaction that funds, redeems, and most importantly, requests to close any channels connected to that account. Maybe also a single-channel subscription.
How reliable are such channels anyways? It would probably make sense to periodically poll for a current state anyways and compare that to the state that is assumed from just watching websockets.
If the websocket notifications are reliable enough, it doesn't seem like you should need to poll for the current state. The only things that can change the payment channel state are you depositing/withdrawing from it, the channel expiring (at the expiration time you set initially), or your counterparty attempting to close the channel prematurely.
This means you rely heavily on the reliability of websockets... Realistically you'd need to also poll twice per SettleDelay time frame to be sure.
If the websocket notifications are reliable enough, it doesn't seem like you should need to poll for the current state. The only things that can change the payment channel state are you depositing/withdrawing from it, the channel expiring (at the expiration time you set initially), or your counterparty attempting to close the channel prematurely.
This means you rely heavily on the reliability of websockets... Realistically you'd need to also poll twice per SettleDelay time frame to be sure.
If the connection dropped, could you have the ability to re-subscribe to events and have them replayed, starting from a particular ledger version? If not, like @MarkusTeufelberger noted, I think you'd still want to poll as a fallback in case you missed something. The subscription would still enable you to poll at much less frequent intervals, though, which would be nice.
I agree that adding this functionality is important and improves the UX of payment channels. @emschwartz, @MarkusTeufelberger, @kincaidoneil: can you provide a list of features you'd like to see for this?
add start option to the subscribe command, specifying where to start returning records from. Use ledgersequence or Ripple Epoch.
add similar method to data api use http live streaming
@nbougalis I would second the features @mDuo13 laid out above. The only other thing I could think of would be having a heartbeat or something similar in the websocket connection (if it doesn't already exist) that would make it really obvious to the client listening for such notifications that they need to reconnect and re-scan their channels to make sure they didn't miss anything.
It would also be great to add recommendations for how you should monitor your channels to the usage guide and to the ripple-lib sections that talk about creating them. It should be emphasized that using channels without proper monitoring is extremely unsafe and may result in the loss of money.
An even more advanced feature that could be nice but may be undesirable from the rippled perspective would be reliable delivery notifications. You could subscribe with some ID, ACK each notification you get, and then the rippled would know which notifications it needs to send you in case your subscription drops and reconnects later (within, say, 24 hours or so so that it can eventually forget about that subscription). The downside is that this would involve some additional state in the rippled node for each subscription that comes in.
To be safe you'd need to subscribe via websocket and in addition poll the channel state at less than half the SettleDelay - ledger_close_interval time frame to be sure to catch a closed channel. Either the Websocket already gives you the necessary signal or you get the changed state via polling.
I wouldn't trust to have state on websocket connections (what if I connect to a cluster behind a loadbalancer for example and reach a different server each time or what if a server simply restarts and loses state?). Currently rippled has something similar with the "pagination" stuff in ledger_data, but I'm not sure if that's really useful or implementable in a websocket context.
I haven't looked to deeply into it, but I assume that when querying for the current state of a PayChan, I can also see when this state has last changed? In that case it would be enough to subscribe, query the current state and then backtrack any on-ledger state changes that I've missed since disconnecting.
On rippled side I think being able to subscribe to individual Payment Channels and to display channel changes in all the account subscriptions that would be affected in the future by this channel change should be enough.
If you need to poll for state changes anyway, I'm not sure how useful the websocket notification would be. Yes, you might find out faster, but it seems more annoying to implement and like it could be a potential footgun to have a push-based notification that you _shouldn't_ rely on. If you expected to have the channel open longer and your peer wants to close it, it may not make a substantial difference to you to get the money back sooner (assuming you'll get it back later otherwise).
I assume that when querying for the current state of a PayChan, I can also see when this state has last changed?
I'm not sure it matters when it last changed, only what the current state is and whether you need to submit a claim right now.
It's possible that the real need behind this feature request could be addressed through a guide and _maybe_ a feature in ripple-lib that does this polling and claim submission the right way.
I'm not sure it matters when it last changed, only what the current state is and whether you need to submit a claim right now.
For claims sure, but you might want to know e.g. when new XRP were added to the channel by whom and in which increments.
The reliability of WebSockets shouldn't really be in question, it's a TCP socket and TCP already handles reliability.
If you use TCP keepalives and a WS heartbeat you should know if the connection is down in which case you should re-establish the connection and catch up on state changes you may have missed.
I assume you'd have a heartbeat that is sent more often than the polling that would be necessary without the subscribed stream.
Seems like ripped already supports native heartbeats in WS so all that is left is for clients to use it to detect that a connection is down:
wscat --slash --connect wss://s1.ripple.com
connected (press CTRL+C to quit)
> /ping
< Received pong
I personally would rather worry about the reliability of the rippled server when trying to track a payment channel over days/weeks/months on the same connection. I view WebSocket connections as nice complimentary tool to be notified faster about potential changes, but I wouldn't trust them to be notified reliably. Not necessarily because of the WebSocket part, more of the "how reliable are both end-points" part.
Operating on the assumption a payment channel is somewhat similar to a RippleState and has 2 clear owners, seems possible to just update Meta#getAffectedAccounts(...) and have everything (notifications, polling) work:
https://github.com/ripple/rippled/blob/0ebed961424d9757f5d26ce7e8b3e5e8d83eb239/src/ripple/ledger/impl/TxMeta.cpp#L120-L121
Publish to subscribers:
https://github.com/ripple/rippled/blob/0ebed961424d9757f5d26ce7e8b3e5e8d83eb239/src/ripple/app/misc/NetworkOPs.cpp#L2608-L2624
https://github.com/ripple/rippled/blob/0ebed961424d9757f5d26ce7e8b3e5e8d83eb239/src/ripple/app/ledger/AcceptedLedgerTx.cpp#L39
Save in sqlite AccountTransactions table (which account_transactions rpc command uses)
https://github.com/ripple/rippled/blob/5214b3c1b09749420ed0682a2e49fbbd759741e5/src/ripple/app/ledger/Ledger.cpp#L888-L893
Probably missing something
Actually, is a new subscription necessary to support this?
Using the existing transaction stream subscription, it seems pretty trivial to filter the AffectedNodes by closed channels and check them against a list of channels to watch.