Skip to content
This repository has been archived by the owner on May 5, 2022. It is now read-only.

Send-only mode #137

Open
sharafian opened this issue Mar 26, 2020 · 5 comments
Open

Send-only mode #137

sharafian opened this issue Mar 26, 2020 · 5 comments
Assignees

Comments

@sharafian
Copy link

In some use cases on top of STREAM, bidirectional communication isn't necessary. In Web Monetization, for instance, the sender repeatedly sends money to the receiver but does not expect data or money in return.

If we were able to turn on a feature in the STREAM client that stops the sender from sending their ILP address to the other side and also enable a feature that would allow the server to function in a half-open mode like this, we could simplify the infrastructure required for WM sending.

Instead of using a bidirectional communication like BTP, we could use HTTP/HTTP2, simplifying WM sending infrastructure and the WM sending code.

CC @kincaidoneil @wilsonianb @sentientwaffle if one of you is interested in looking into this, feel free to assign yourself on this issue.

@kincaidoneil I noticed you worked on the code for receive-only mode on the server, are there any considerations with this feature that I missed?

@kincaidoneil
Copy link
Member

I'm very supportive of simplifying STREAM & removing duplexing where we don't need it. (I've been working on a STREAM prototype tailored to Open Payments and fixed destination amount payments which itself is only unidirectional, so already tested a few approaches to this with the existing JS server.)


Per Ben's suggestion, one option is to not share the client's address with the server by not sending the ConnectionNewAddress frame. I've tested this does work, however the spec says:

When a client connects to a server, they MUST communicate their ILP address to the server using a ConnectionNewAddress frame.

Also: JS, Rust, and Java each send the ConnectionAssetDetails frame to the client only after they receive a ConnectionNewAddress frame, so it's breaking if the client needs the destination asset details.

Here are two potential solutions:

  1. Send a ConnectionNewAddress frame with an empty address. A hack, and adds an additional config option to the client, but it doesn't require any updates to existing server deployments.
  2. Change setReceiveMax so it doesn't start a send loop. That way, a server or client that's only receiving should mostly never try to send packets. It's a little bit more complicated since there are a few places where STREAM tries to send control frames when the connection or stream closes, which might need to also be changed. But no additional config would be required on the server or client; servers would just need to be updated.

I don't think my old "receive only" implementation is great because it requires servers to be explicitly configured with it, and that shouldn't be necessary.

@kincaidoneil kincaidoneil self-assigned this Apr 8, 2020
@wilsonianb
Copy link
Contributor

Just saw @sappenin's idea of a private prefixed client address as a variation of solution 1.
interledger/rfcs#571 (comment)

@sappenin
Copy link

sappenin commented Apr 17, 2020

Oh wow, I didn't see this issue - it's ironic that we were having the same problem, though independently it seems. Thanks for the tag @wilsonianb

Also, I added this to the "Things to think about for Stream v2" issue, although adding a new frame to the spec called ConnectionAssetDetailsRequest could probably be done in a non-breaking fashion,.

@kincaidoneil
Copy link
Member

Here's the constraints of the issue:

  1. Existing, deployed JS STREAM servers execute an exchange rate probe back to the client on incoming connections. If this probe fails, then it destroys the connection. While I think this behavior is undesirable and should be changed, we have deal with/support it. Since existing clients can accept incoming packets, this (mostly) isn't an issue, but...
  2. STREAM send-only clients need a way to pay to these receivers, and need a way to fetch destination asset details.
  3. The current STREAM spec requires/assumes the client sends a ConnectionNewAddress frame.
  4. Stateless receivers need a mechanism to share their asset details with the client.

AFAIK, there's only one backwards compatible way to get asset details from existing STREAM receivers from a send-only client without the JS receiver destroying the connection --- which is to send a ConnectionNewAddress frame with an empty address.

So, my proposed solution to this is:

  1. In the interim, all send-only clients should send ConnectionNewAddress frames with an empty address. On the receiver side, we keep the ConnectionNewAddress -> ConnectionAssetDetails behavior for now.
  2. Update new versions of ilp-protocol-stream to no longer do the rate probe unless it needs to send money.
  3. Share destination asset details using SPSP/Open Payments. Some Open Payments use cases will necessarily require sharing asset details, and doing it over STREAM can add latency, so if we're going to change the flow, we should do it at the application layer, rather than STREAM.
  4. After Open Payments rollout, change the STREAM spec & implementations to no longer require sending ConnectionNewAddress on connect and explicitly allow one-sided connections.

but in the case where the caller doesn't supply a sourceAddress, the SimpleStreamSender, will prepend the Link operator address with the private prefix

Unfortunately this won't solve the backwards compat issue. And if the payment occurred within a local private. network, the address would be routable. I think the spirit of the ConnectionNewAddress frame is that the address is routable.

@sappenin
Copy link

sappenin commented May 2, 2020

After syncing with @kincaidoneil a bit over slack, I've published a PR with some suggested clarifications to the STREAM RFC I think address all of the issues discussed in this issue (and elsewhere). Comments/feedback welcome!

interledger/rfcs#573

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants