Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add STREAM receipts #570

Merged
merged 20 commits into from
Apr 22, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: The Simple Payment Setup Protocol (SPSP)
draft: 9
draft: 10
---
# Simple Payment Setup Protocol (SPSP)

Expand All @@ -24,6 +24,7 @@ SPSP provides for exchanging basic server details needed by a client to set up a
* **SPSP Server** - The application that handles incoming SPSP requests from the SPSP Client.
* **SPSP Endpoint** - The specific HTTPS endpoint on the SPSP Server used for setting up a payment.
* **STREAM Module** - Software included in the SPSP Client and Server that implements the [STREAM](../0029-stream/0029-stream.md) protocol.
* **STREAM Receipt** - Proof provided by the payment recipient of the total amount received on a stream.
sappenin marked this conversation as resolved.
Show resolved Hide resolved

### Interfaces

Expand Down Expand Up @@ -62,6 +63,17 @@ Host: example.com
Accept: application/spsp4+json, application/spsp+json
```

##### Request Headers
wilsonianb marked this conversation as resolved.
Show resolved Hide resolved

The request MAY contain at least the following headers in order to pre-share STREAM Receipt details between the SPSP Server and a party verifying payments sent to the SPSP Server:
sappenin marked this conversation as resolved.
Show resolved Hide resolved

| Header | Description |
|:----------------|:-----------------------------------------------------------|
| `Receipt-Nonce` | A base64-encoded 16-byte random nonce used to identify the STREAM connection in STREAM Receipts. |
| `Receipt-Secret` | A base64-encoded 32-byte key used to generate a STREAM Receipt's HMAC. |
kincaidoneil marked this conversation as resolved.
Show resolved Hide resolved

The SPSP Client MAY be provided with an SPSP Endpoint belonging to the receipt verifier, which would add the receipt headers and proxy the query to the SPSP Server.
wilsonianb marked this conversation as resolved.
Show resolved Hide resolved

#### Response
``` http
HTTP/1.1 200 OK
Expand Down
24 changes: 23 additions & 1 deletion 0029-stream/0029-stream.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: STREAM - A Multiplexed Money and Data Transport for ILP
draft: 8
draft: 9
---

# STREAM: A Multiplexed Money and Data Transport for ILP
Expand Down Expand Up @@ -55,6 +55,7 @@ This document specifies the STREAM Interledger Transport protocol, which provide
- [5.3.12. `StreamMaxData` Frame](#5312-streammaxdata-frame)
- [5.3.13. `StreamDataBlocked` Frame](#5313-streamdatablocked-frame)
- [5.3.14. `ConnectionAssetDetails` Frame](#5314-connectionassetdetails-frame)
- [5.3.15. `StreamReceipt` Frame](#5315-streamreceipt-frame)
- [5.4. Error Codes](#54-error-codes)
- [6. Condition and Fulfillment Generation](#6-condition-and-fulfillment-generation)
- [6.1. Unfulfillable Condition](#61-unfulfillable-condition)
Expand Down Expand Up @@ -192,6 +193,8 @@ Client streams MUST be odd-numbered starting with 1 and server-initiated streams

Money can be sent for a given stream by sending an ILP Prepare packet with a non-zero `amount` and a `StreamMoney` frame in the STREAM packet to indicate which stream the money is for. A single ILP Prepare can carry value destined for multiple streams and the `shares` field in each of the `StreamMoney` frames indicates what portion of the Prepare amount should go to each stream.

The receiver SHOULD include `StreamReceipt` frames in the ILP Fulfill packet indicating the total amount of money received in each stream, unless a secret key with which to generate receipts was not pre-shared with the receiver. Receipts can be verified, in order to confirm payment, using the pre-shared secret.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A Receipt Secret to generate receipts and a Receipt Nonce to include in those receipts. Also did we land on whether there's a required length for the Receipt Secret & Receipt Nonce? Might make sense to say they're both 32 bytes to prevent someone from DoSing an SPSP server with a massive Receipt Secret

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now, it's 16 byte nonce and 32 byte secret (https://github.com/interledger/rfcs/pull/570/files#diff-0bbc536b39826341170954e2675f765cR72-R73).
Is it worth making the nonce 32 bytes?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well for the nonce we only need uniqueness, given it's public. So 16 is probably fine. 32 byte secret is good because it's often gonna be output of sha256. I think those values are good, but open to hear any other opinions


#### 4.4.3. Sending Data

Data can be sent for a given stream by sending an ILP Prepare packet with a `StreamData` frame in the STREAM packet. A single ILP Prepare can carry data destined for multiple streams.
Expand Down Expand Up @@ -313,6 +316,7 @@ The frame types are as follows and each is described in greater detail below:
| `0x14` | Stream Data |
| `0x15` | Stream Data Max |
| `0x16` | Stream Data Blocked |
| `0x17` | Stream Receipt |

#### 5.3.1. `ConnectionClose` Frame

Expand Down Expand Up @@ -436,6 +440,24 @@ In other words, if a sender resends data (e.g. because a packet was lost), it MU

Asset details exposed by this frame MUST NOT change during the lifetime of a Connection.

#### 5.3.15. `StreamReceipt` Frame

| Field | Type | Description |
|---|---|---|
| Stream ID | VarUInt | Identifier of the stream this frame refers to. |
| Receipt | 65-Byte OctetString | Proof provided by the receiver of the total amount received on this stream |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why doesn't the frame individually enumerate the fields of the receipt? Are they not intended to be exposed at the STREAM layer...?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The receipt is kinda treated as a whole object that's passed around, for instance the receipt would be emitted in WM. So I think "grouping" like this can be helpful

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why mandate the exact size of the receipt instead of leaving it open-ended for possible extension?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍
Should we also consider including a receipt version number?
Or could the receipt size be used to check compatibility, such as with receipt support discovery (#570 (comment))?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps the receipt itself could have a version byte? Size might not be good enough if a future version is variable length. And if the receipt contains its own version info then STREAM doesn't need to emit extra information about receipt version

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed receipt to VarOctetString and added version number: 1633e86


The `Receipt` MUST contain the following fields encoded using the [Octet Encoding Rules (OER)](http://www.oss.com/asn1/resources/books-whitepapers-pubs/Overview_of_OER.pdf):
wilsonianb marked this conversation as resolved.
Show resolved Hide resolved

| Field | Type | Description |
|---|---|---|
| HMAC | UInt256 | HMAC-SHA256 over all other fields using a secret pre-shared between the verifying party and the receiver. |

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should explicitly name this pre-shared secret the Receipt Secret and be explicit that it's an additional optional parameter to create a STREAM connection. I could imagine someone reading this and thinking we're referring to the shared secret here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bc04d01 adds more details on Receipt Secret and Receipt Nonce

| Receipt Nonce | UInt128 | A random nonce pre-shared between the verifying party and the receiver used to identify the STREAM connection. |
| Stream ID | UInt8 | Identifier of the stream this receipt refers to. |
wilsonianb marked this conversation as resolved.
Show resolved Hide resolved
| Total Received | UInt64 | Total amount, denominated in the units of the receiver, that the receiver has received on this stream thus far. |
| Stream Start Time | UInt64 | A UNIX timestamp referring to the time that the stream was established at the receiver. |

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's worth considering whether we should use an InterledgerTimestamp here. It still is fixed length, and although it is a little trickier to parse it solves things like leap seconds. That said a unix timestamp is gonna be easier to use in a lot of different environments.

wilsonianb marked this conversation as resolved.
Show resolved Hide resolved


### 5.4. Error Codes

Error codes are sent in `StreamClose` and `ConnectionClose` frames to indicate what caused the stream or connection to be closed.
Expand Down
17 changes: 17 additions & 0 deletions 0029-stream/test-vectors/StreamPacketFixtures.json
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,23 @@
},
"buffer": "AQwBAAEAAQEWCwF7CP//////////"
},
{
"name": "frame:stream_receipt",
"packet": {
"sequence": "0",
"packetType": 12,
"amount": "0",
"frames": [
{
"type": 23,
"name": "StreamReceipt",
"streamId": "123",
"receipt": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
}
]
},
"buffer": "AQwBAAEAAQEXQwF7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
},
{
"name": "frame:stream_max_money:receive_max:too_big",
"packet": {
Expand Down
11 changes: 10 additions & 1 deletion asn1/Stream.asn
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ FrameSet FRAME ::= {
{19 StreamMoneyBlocked} |
{20 StreamData} |
{21 StreamMaxData} |
{22 StreamDataBlocked}
{22 StreamDataBlocked} |
{23 StreamReceipt]}
}

StreamFrame ::= SEQUENCE {
Expand Down Expand Up @@ -174,4 +175,12 @@ StreamDataBlocked ::= SEQUENCE {
maxOffset VarUInt
}

StreamReceipt ::= SEQUENCE {
-- Identifier of the stream
streamId VarUInt,

-- Receipt for verifying the total amount received on this stream
receipt OCTET STRING (SIZE(65))
}

END