interledger / rfcs

Specifications for Interledger and related protocols

Home Page:https://interledger.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Question] How to compose STREAM packet

dora-gt opened this issue · comments

  • How to compose STREAM packet.
    • For example, I have (A and B) endpoints on a connection and 2 streams on it.
      • A sends 100 [XRP] to B on a ILP Prepare packet that contains 4 frames.
        • A money frame and a data frame for stream "alpha", share 50%
        • A money frame and a data frame for stream "beta", share 50%
      • B wants to decline "alpha" but wants to accept "beta".
    • Then what happens?
      • The frames is prepared on the same condition.
      • Can B decline only "alpha"?

If the receiver rejects a packet, it rejects all of the frames contained in it.

We could add a recommendation to the spec like this one from QUIC:

Note that when data from multiple streams is bundled into a single QUIC packet, loss of that packet blocks all those streams from making progress. An implementation is therefore advised to bundle as few streams as necessary in outgoing packets without losing transmission efficiency to underfilled packets.

I see.

I'm curious about the succeeding procedure.
A should know...

  • alpha was rejected.
  • beta was qualified but rejected because of the other stream (alpha).
    and resend a packet for beta again somehow.

It may be application layer problem though. The strategy how many frames should be in a ILP packet is difficult.

That actually is a transport-layer (or transport implementation) concern. It's definitely one of the trickier parts of this.

The two types of frames that might cause a packet to be rejected are the StreamMoneyFrame and StreamDataFrame. If the receiver rejects it because of a money frame, they should probably send back a StreamMaxMoneyFrame and if it's rejected because of a data frame, they should send back a StreamMaxDataFrame.

So, the rejected frame (for alpha) seems to be clear, what about beta? What kind of frame should B respond for beta stream?

If the receiver doesn't respond with any type of frame, the sender should just resend that one.

The way the implementation handles this is that each side keeps track of the limits of the other side. When one is loading up packets to send, it checks whether each stream has money and/or data to send, and if the other side is willing to receive more, and sends off packets accordingly. Stream Max frames are used just to update the state representing the other sides limits.

Thank you for the detail, and maybe I had misunderstood.

You mean...the reason why receiver sends StreamMaxMoneyFrame back to sender is that the packet is rejected because it reached the max value of money, don't you?

I feel something strange because there probably is more reason of a packet being rejected. For example,

  • the sender sends some data and money with ILP Prepare packet.
  • the receiver could not accept the ILP Prepare packet because the receiver could not parse the data frame, or the data is broken, or the data is not suitable for the situation.

Then the receiver may want to respond with some frame that represents the data was not accepted, but it is not because of it reaching max.

I'm sorry if I'm missing something.

I think the packet should only be rejected if:

  • There is money for a stream that exceeds its limit
  • There is data for a stream that exceeds its limit
  • There is money or data for a stream that is already closed
  • The packet contains an invalid frame (I think this should actually cause the connection to close)

If the receiver doesn't want the data for some other reason, that can be handled on the application layer. For example, if you implemented a request/response protocol on top of STREAM, the recipient of the data could respond to a request with an error. However, that would not be done at the level of fulfilling or rejecting packets, that would just be application data that the receiver would send back to the sender.

Packets should only be rejected because of concerns internal to the STREAM protocol

So, what about this case?

  • A web application API
    • Accepts uint from 0 to 100 that represents an ID
    • Returns some data for the ID
  • A user sends a request
    • Contains uint of 200
    • Exceeds limit (200 is over 100)

I think this is application layer concern, but this should be rejected and refunded, isn't it?

The application would have set the receiveMax to 100 units, so any packets that would exceed that limit would be rejected automatically. The sender's STREAM module would know not to send more than that.

Ah I see. Maybe this use case is not suitable for STREAM 🤔
If the request consists of multiple input fields, the request cannot be rejected automatically.
Perhaps I should learn STREAM + SPSP, and how they handle the entire business transaction.

commented

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

If this issue is important, please feel free to bring it up on the next Interledger Community Group Call or in the Gitter chat.